Merge branch 'dev' of https://github.com/nodemcu/nodemcu-firmware into dev
This commit is contained in:
commit
638bf7b023
|
@ -29,6 +29,7 @@
|
|||
#define LUA_USE_MODULES_MQTT
|
||||
#define LUA_USE_MODULES_COAP
|
||||
#define LUA_USE_MODULES_U8G
|
||||
#define LUA_USE_MODULES_WS2801
|
||||
#define LUA_USE_MODULES_WS2812
|
||||
#define LUA_USE_MODULES_CJSON
|
||||
#define LUA_USE_MODULES_CRYPTO
|
||||
|
|
|
@ -133,6 +133,14 @@
|
|||
#define ROM_MODULES_BIT
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_MODULES_WS2801)
|
||||
#define MODULES_WS2801 "ws2801"
|
||||
#define ROM_MODULES_WS2801 \
|
||||
_ROM(MODULES_WS2801, luaopen_ws2801, ws2801_map)
|
||||
#else
|
||||
#define ROM_MODULES_WS2801
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_MODULES_WS2812)
|
||||
#define MODULES_WS2812 "ws2812"
|
||||
#define ROM_MODULES_WS2812 \
|
||||
|
@ -190,6 +198,7 @@
|
|||
ROM_MODULES_UART \
|
||||
ROM_MODULES_OW \
|
||||
ROM_MODULES_BIT \
|
||||
ROM_MODULES_WS2801 \
|
||||
ROM_MODULES_WS2812 \
|
||||
ROM_MODULES_CJSON \
|
||||
ROM_MODULES_CRYPTO \
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include "platform.h"
|
||||
#include "auxmods.h"
|
||||
#include "lrotable.h"
|
||||
#include "c_stdlib.h"
|
||||
#include "c_string.h"
|
||||
|
||||
/**
|
||||
* Code is based on https://github.com/CHERTS/esp8266-devkit/blob/master/Espressif/examples/EspLightNode/user/ws2801.c
|
||||
* and provides a similar api as the ws2812 module.
|
||||
* The current implementation allows the caller to use
|
||||
* any combination of GPIO0, GPIO2, GPIO4, GPIO5 as clock and data.
|
||||
*/
|
||||
|
||||
#define PIN_CLK_DEFAULT 0
|
||||
#define PIN_DATA_DEFAULT 2
|
||||
|
||||
static uint32_t ws2801_bit_clk;
|
||||
static uint32_t ws2801_bit_data;
|
||||
|
||||
static void ws2801_byte(uint8_t n) {
|
||||
uint8_t bitmask;
|
||||
for (bitmask = 0x80; bitmask !=0 ; bitmask >>= 1) {
|
||||
if (n & bitmask) {
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, ws2801_bit_data);
|
||||
} else {
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, ws2801_bit_data);
|
||||
}
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, ws2801_bit_clk);
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, ws2801_bit_clk);
|
||||
}
|
||||
}
|
||||
|
||||
static void ws2801_color(uint8_t r, uint8_t g, uint8_t b) {
|
||||
ws2801_byte(r);
|
||||
ws2801_byte(g);
|
||||
ws2801_byte(b);
|
||||
}
|
||||
|
||||
static void ws2801_strip(uint8_t const * data, uint16_t len) {
|
||||
while (len--) {
|
||||
ws2801_byte(*(data++));
|
||||
}
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, ws2801_bit_data);
|
||||
}
|
||||
|
||||
static void enable_pin_mux(pin) {
|
||||
// The API only supports setting PERIPHS_IO_MUX on GPIO 0, 2, 4, 5
|
||||
switch (pin) {
|
||||
case 0:
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
|
||||
break;
|
||||
case 2:
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
|
||||
break;
|
||||
case 4:
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);
|
||||
break;
|
||||
case 5:
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lua: ws2801.init(pin_clk, pin_data)
|
||||
* Sets up the GPIO pins
|
||||
*
|
||||
* ws2801.init(0, 2) uses GPIO0 as clock and GPIO2 as data.
|
||||
* This is the default behavior.
|
||||
*/
|
||||
static int ICACHE_FLASH_ATTR ws2801_init_lua(lua_State* L) {
|
||||
uint32_t pin_clk;
|
||||
uint32_t pin_data;
|
||||
uint32_t func_gpio_clk;
|
||||
uint32_t func_gpio_data;
|
||||
|
||||
if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2)) {
|
||||
// Use default pins if the input is omitted
|
||||
pin_clk = PIN_CLK_DEFAULT;
|
||||
pin_data = PIN_DATA_DEFAULT;
|
||||
} else {
|
||||
pin_clk = luaL_checkinteger(L, 1);
|
||||
pin_data = luaL_checkinteger(L, 2);
|
||||
}
|
||||
|
||||
ws2801_bit_clk = 1 << pin_clk;
|
||||
ws2801_bit_data = 1 << pin_data;
|
||||
|
||||
os_delay_us(10);
|
||||
|
||||
//Set GPIO pins to output mode
|
||||
enable_pin_mux(pin_clk);
|
||||
enable_pin_mux(pin_data);
|
||||
|
||||
//Set both GPIOs low low
|
||||
gpio_output_set(0, ws2801_bit_clk | ws2801_bit_data, ws2801_bit_clk | ws2801_bit_data, 0);
|
||||
|
||||
os_delay_us(10);
|
||||
}
|
||||
|
||||
/* Lua: ws2801.write(pin, "string")
|
||||
* Byte triples in the string are interpreted as R G B values.
|
||||
* This function does not corrupt your buffer.
|
||||
*
|
||||
* ws2801.write(string.char(255, 0, 0)) sets the first LED red.
|
||||
* ws2801.write(string.char(0, 0, 255):rep(10)) sets ten LEDs blue.
|
||||
* ws2801.write(string.char(0, 255, 0, 255, 255, 255)) first LED green, second LED white.
|
||||
*/
|
||||
static int ICACHE_FLASH_ATTR ws2801_writergb(lua_State* L) {
|
||||
size_t length;
|
||||
const char *buffer = luaL_checklstring(L, 1, &length);
|
||||
|
||||
os_delay_us(10);
|
||||
|
||||
os_intr_lock();
|
||||
|
||||
ws2801_strip(buffer, length);
|
||||
|
||||
os_intr_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MIN_OPT_LEVEL 2
|
||||
#include "lrodefs.h"
|
||||
const LUA_REG_TYPE ws2801_map[] =
|
||||
{
|
||||
{ LSTRKEY( "write" ), LFUNCVAL( ws2801_writergb )},
|
||||
{ LSTRKEY( "init" ), LFUNCVAL( ws2801_init_lua )},
|
||||
{ LNILKEY, LNILVAL}
|
||||
};
|
||||
|
||||
LUALIB_API int luaopen_ws2801(lua_State *L) {
|
||||
LREGISTER(L, "ws2801", ws2801_map);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -128,38 +128,32 @@ class ESPROM:
|
|||
def connect(self):
|
||||
print 'Connecting...'
|
||||
|
||||
# RTS = CH_PD (i.e reset)
|
||||
# DTR = GPIO0
|
||||
# self._port.setRTS(True)
|
||||
# self._port.setDTR(True)
|
||||
# self._port.setRTS(False)
|
||||
# time.sleep(0.1)
|
||||
# self._port.setDTR(False)
|
||||
for _ in xrange(4):
|
||||
# issue reset-to-bootloader:
|
||||
# RTS = either CH_PD or nRESET (both active low = chip in reset)
|
||||
# DTR = GPIO0 (active low = boot to flasher)
|
||||
self._port.setDTR(False)
|
||||
self._port.setRTS(True)
|
||||
time.sleep(0.05)
|
||||
self._port.setDTR(True)
|
||||
self._port.setRTS(False)
|
||||
time.sleep(0.05)
|
||||
self._port.setDTR(False)
|
||||
|
||||
# NodeMCU devkit
|
||||
self._port.setRTS(True)
|
||||
self._port.setDTR(True)
|
||||
time.sleep(0.1)
|
||||
self._port.setRTS(False)
|
||||
self._port.setDTR(False)
|
||||
time.sleep(0.1)
|
||||
self._port.setRTS(True)
|
||||
time.sleep(0.1)
|
||||
self._port.setDTR(True)
|
||||
self._port.setRTS(False)
|
||||
time.sleep(0.3)
|
||||
self._port.setDTR(True)
|
||||
|
||||
self._port.timeout = 0.5
|
||||
for i in xrange(10):
|
||||
try:
|
||||
self._port.flushInput()
|
||||
self._port.flushOutput()
|
||||
self.sync()
|
||||
self._port.timeout = 5
|
||||
return
|
||||
except:
|
||||
time.sleep(0.1)
|
||||
self._port.timeout = 0.3 # worst-case latency timer should be 255ms (probably <20ms)
|
||||
for _ in xrange(4):
|
||||
try:
|
||||
self._port.flushInput()
|
||||
self._port.flushOutput()
|
||||
self.sync()
|
||||
self._port.timeout = 5
|
||||
return
|
||||
except:
|
||||
time.sleep(0.05)
|
||||
# this is a workaround for the CH340 serial driver on current versions of Linux,
|
||||
# which seems to sometimes set the serial port up with wrong parameters
|
||||
self._port.close()
|
||||
self._port.open()
|
||||
raise Exception('Failed to connect')
|
||||
|
||||
""" Read memory address in target """
|
||||
|
@ -268,6 +262,15 @@ class ESPROM:
|
|||
|
||||
return data
|
||||
|
||||
""" Abuse the loader protocol to force flash to be left in write mode """
|
||||
def flash_unlock_dio(self):
|
||||
# Enable flash write mode
|
||||
self.flash_begin(0, 0)
|
||||
# Reset the chip rather than call flash_finish(), which would have
|
||||
# write protected the chip again (why oh why does it do that?!)
|
||||
self.mem_begin(0,0,0,0x40100000)
|
||||
self.mem_finish(0x40000080)
|
||||
|
||||
""" Perform a chip erase of SPI flash """
|
||||
def flash_erase(self):
|
||||
# Trick ROM to initialize SFlash
|
||||
|
@ -566,7 +569,10 @@ if __name__ == '__main__':
|
|||
seq += 1
|
||||
print
|
||||
print '\nLeaving...'
|
||||
esp.flash_finish(False)
|
||||
if args.flash_mode == 'dio':
|
||||
esp.flash_unlock_dio()
|
||||
else:
|
||||
esp.flash_finish(False)
|
||||
|
||||
elif args.operation == 'run':
|
||||
esp.run()
|
||||
|
|
Loading…
Reference in New Issue