Merge remote-tracking branch 'origin/dev-esp32-idf4' into ble
This commit is contained in:
commit
adc188b4b1
|
@ -97,23 +97,3 @@ size_t feed_lua_input(const char *buf, size_t n)
|
||||||
|
|
||||||
return n; // we consumed/buffered all the provided data
|
return n; // we consumed/buffered all the provided data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void output_redirect(const char *str, size_t l) {
|
|
||||||
lua_State *L = lua_getstate();
|
|
||||||
int n = lua_gettop(L);
|
|
||||||
lua_pushliteral(L, "stdout");
|
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX); /* fetch reg.stdout */
|
|
||||||
if (lua_istable(L, -1)) { /* reg.stdout is pipe */
|
|
||||||
lua_rawgeti(L, -1, 1); /* get the pipe_write func from stdout[1] */
|
|
||||||
lua_insert(L, -2); /* and move above the pipe ref */
|
|
||||||
lua_pushlstring(L, str, l);
|
|
||||||
if (lua_pcall(L, 2, 0, 0) != LUA_OK) { /* Reg.stdout:write(str) */
|
|
||||||
lua_writestringerror("error calling stdout:write(%s)\n", lua_tostring(L, -1));
|
|
||||||
esp_restart();
|
|
||||||
}
|
|
||||||
} else { /* reg.stdout == nil */
|
|
||||||
printf(str, l);
|
|
||||||
}
|
|
||||||
lua_settop(L, n); /* Make sure all code paths leave stack unchanged */
|
|
||||||
}
|
|
||||||
|
|
|
@ -305,7 +305,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
|
||||||
** They are only used in libraries and the stand-alone program. (The #if
|
** They are only used in libraries and the stand-alone program. (The #if
|
||||||
** avoids including 'stdio.h' everywhere.)
|
** avoids including 'stdio.h' everywhere.)
|
||||||
*/
|
*/
|
||||||
#ifdef LUA_USE_ESP
|
#ifdef LUA_USE_ESP8266
|
||||||
void output_redirect(const char *str, size_t l);
|
void output_redirect(const char *str, size_t l);
|
||||||
#define lua_writestring(s,l) output_redirect((s),(l))
|
#define lua_writestring(s,l) output_redirect((s),(l))
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -230,7 +230,7 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
|
||||||
|
|
||||||
/* print a string */
|
/* print a string */
|
||||||
#if !defined(lua_writestring)
|
#if !defined(lua_writestring)
|
||||||
#ifdef LUA_USE_ESP
|
#ifdef LUA_USE_ESP8266
|
||||||
void output_redirect(const char *str, size_t l);
|
void output_redirect(const char *str, size_t l);
|
||||||
#define lua_writestring(s,l) output_redirect((s),(l))
|
#define lua_writestring(s,l) output_redirect((s),(l))
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -73,6 +73,8 @@ menu "NodeMCU modules"
|
||||||
config NODEMCU_CMODULE_FILE
|
config NODEMCU_CMODULE_FILE
|
||||||
bool "File module"
|
bool "File module"
|
||||||
default "y"
|
default "y"
|
||||||
|
select VFS_SUPPORT_IO
|
||||||
|
select VFS_SUPPORT_DIR
|
||||||
help
|
help
|
||||||
Includes the file module (recommended).
|
Includes the file module (recommended).
|
||||||
|
|
||||||
|
@ -125,6 +127,7 @@ menu "NodeMCU modules"
|
||||||
config NODEMCU_CMODULE_NET
|
config NODEMCU_CMODULE_NET
|
||||||
bool "Net module"
|
bool "Net module"
|
||||||
default "y"
|
default "y"
|
||||||
|
select VFS_SUPPORT_IO
|
||||||
help
|
help
|
||||||
Includes the net module (recommended).
|
Includes the net module (recommended).
|
||||||
|
|
||||||
|
|
|
@ -230,6 +230,18 @@ static int leth_set_ip( lua_State *L )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int leth_set_hostname(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *hostname = luaL_checkstring(L, 1);
|
||||||
|
|
||||||
|
esp_err_t err = esp_netif_set_hostname(eth, hostname);
|
||||||
|
|
||||||
|
if (err != ESP_OK)
|
||||||
|
return luaL_error (L, "failed to set hostname, code %d", err);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int leth_on( lua_State *L )
|
static int leth_on( lua_State *L )
|
||||||
{
|
{
|
||||||
const char *event_name = luaL_checkstring( L, 1 );
|
const char *event_name = luaL_checkstring( L, 1 );
|
||||||
|
@ -338,6 +350,7 @@ LROT_BEGIN(eth, NULL, 0)
|
||||||
LROT_FUNCENTRY( get_mac, leth_get_mac )
|
LROT_FUNCENTRY( get_mac, leth_get_mac )
|
||||||
LROT_FUNCENTRY( set_mac, leth_set_mac )
|
LROT_FUNCENTRY( set_mac, leth_set_mac )
|
||||||
LROT_FUNCENTRY( set_ip, leth_set_ip )
|
LROT_FUNCENTRY( set_ip, leth_set_ip )
|
||||||
|
LROT_FUNCENTRY( set_hostname, leth_set_hostname )
|
||||||
|
|
||||||
LROT_NUMENTRY( PHY_DP83848, ETH_PHY_DP83848 )
|
LROT_NUMENTRY( PHY_DP83848, ETH_PHY_DP83848 )
|
||||||
LROT_NUMENTRY( PHY_IP101, ETH_PHY_IP101 )
|
LROT_NUMENTRY( PHY_IP101, ETH_PHY_IP101 )
|
||||||
|
|
|
@ -44,8 +44,13 @@ static int file_list( lua_State* L )
|
||||||
lua_newtable( L );
|
lua_newtable( L );
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
while ((e = readdir(dir))) {
|
while ((e = readdir(dir))) {
|
||||||
|
char *fname;
|
||||||
|
asprintf(&fname, "%s/%s", dirname, e->d_name);
|
||||||
|
if (!fname)
|
||||||
|
return luaL_error(L, "no memory");
|
||||||
struct stat st = { 0, };
|
struct stat st = { 0, };
|
||||||
stat(e->d_name, &st);
|
stat(fname, &st);
|
||||||
|
free(fname);
|
||||||
lua_pushinteger(L, st.st_size);
|
lua_pushinteger(L, st.st_size);
|
||||||
lua_setfield(L, -2, e->d_name);
|
lua_setfield(L, -2, e->d_name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,26 +399,90 @@ static int node_input( lua_State* L )
|
||||||
// When there is any write to the replaced stdout, our function redir_write will be called.
|
// When there is any write to the replaced stdout, our function redir_write will be called.
|
||||||
// we can then invoke the lua callback.
|
// we can then invoke the lua callback.
|
||||||
|
|
||||||
static FILE *oldstdout; // keep the old stdout, e.g., the uart0
|
// A buffer size that should be sufficient for most cases, yet not so large
|
||||||
lua_ref_t output_redir = LUA_NOREF; // this will hold the Lua callback
|
// as to present an issue.
|
||||||
int serial_debug = 0; // whether or not to write also to uart
|
# define OUTPUT_CHUNK_SIZE 127
|
||||||
const char *VFS_REDIR = "/redir"; // virtual filesystem mount point
|
typedef struct {
|
||||||
|
uint8_t used;
|
||||||
|
uint8_t bytes[OUTPUT_CHUNK_SIZE];
|
||||||
|
} output_chunk_t;
|
||||||
|
|
||||||
|
static task_handle_t output_task; // for getting output into the LVM thread
|
||||||
|
static lua_ref_t output_redir = LUA_NOREF; // this will hold the Lua callback
|
||||||
|
static FILE *serial_debug; // the console uart, if wanted
|
||||||
|
static const char *VFS_REDIR = "/redir"; // virtual filesystem mount point
|
||||||
|
|
||||||
// redir_write will be called everytime any code writes to stdout when
|
// redir_write will be called everytime any code writes to stdout when
|
||||||
// redirection is active
|
// redirection is active, from ANY RTOS thread
|
||||||
ssize_t redir_write(int fd, const void *data, size_t size) {
|
ssize_t redir_write(int fd, const void *data, size_t size) {
|
||||||
if (serial_debug) // if serial_debug is nonzero, write to uart
|
UNUSED(fd);
|
||||||
fwrite(data, sizeof(char), size, oldstdout);
|
if (size)
|
||||||
|
{
|
||||||
if (output_redir != LUA_NOREF) { // prepare lua call
|
size_t n = (size > OUTPUT_CHUNK_SIZE) ? OUTPUT_CHUNK_SIZE : size;
|
||||||
lua_State *L = lua_getstate();
|
output_chunk_t *chunk = malloc(sizeof(output_chunk_t));
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, output_redir); // push function reference
|
chunk->used = (uint8_t)n;
|
||||||
lua_pushlstring(L, (char *)data, size); // push data
|
memcpy(chunk->bytes, data, n);
|
||||||
luaL_pcallx(L, 1, 0); // invoke callback
|
_Static_assert(sizeof(task_param_t) >= sizeof(chunk), "cast error below");
|
||||||
|
if (!task_post_high(output_task, (task_param_t)chunk))
|
||||||
|
{
|
||||||
|
static const char overflow[] = "E: output overflow\n";
|
||||||
|
fwrite(overflow, sizeof(overflow) -1, sizeof(char), serial_debug);
|
||||||
|
free(chunk);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return size;
|
|
||||||
|
if (serial_debug)
|
||||||
|
{
|
||||||
|
size_t written = 0;
|
||||||
|
while (written < n)
|
||||||
|
{
|
||||||
|
size_t w = fwrite(
|
||||||
|
data + written, sizeof(char), n - written, serial_debug);
|
||||||
|
if (w > 0)
|
||||||
|
written += w;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void redir_output(task_param_t param, task_prio_t prio)
|
||||||
|
{
|
||||||
|
UNUSED(prio);
|
||||||
|
output_chunk_t *chunk = (output_chunk_t *)param;
|
||||||
|
bool redir_active = (output_redir != LUA_NOREF);
|
||||||
|
if (redir_active)
|
||||||
|
{
|
||||||
|
lua_State *L = lua_getstate();
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, output_redir);
|
||||||
|
lua_pushlstring(L, (char *)chunk->bytes, chunk->used);
|
||||||
|
luaL_pcallx(L, 1, 0);
|
||||||
|
}
|
||||||
|
free(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(CONFIG_ESP_CONSOLE_NONE)
|
||||||
|
static const char *default_console_name(void)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
#if defined(CONFIG_ESP_CONSOLE_UART)
|
||||||
|
# define STRINGIFY(x) STRINGIFY2(x)
|
||||||
|
# define STRINGIFY2(x) #x
|
||||||
|
"/dev/uart/" STRINGIFY(CONFIG_ESP_CONSOLE_UART_NUM);
|
||||||
|
#undef STRINGIFY2
|
||||||
|
#undef STRINGIFY
|
||||||
|
#elif defined(CONFIG_ESP_CONSOLE_USB_CDC)
|
||||||
|
"/dev/cdcacm";
|
||||||
|
#elif defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG)
|
||||||
|
"/dev/usbserjtag";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// redir_open is called when fopen() is called on /redir/xxx
|
// redir_open is called when fopen() is called on /redir/xxx
|
||||||
int redir_open(const char *path, int flags, int mode) {
|
int redir_open(const char *path, int flags, int mode) {
|
||||||
return 79; // since we only have one "file", just return some fd number to make the VFS system happy
|
return 79; // since we only have one "file", just return some fd number to make the VFS system happy
|
||||||
|
@ -426,6 +490,11 @@ int redir_open(const char *path, int flags, int mode) {
|
||||||
|
|
||||||
// Lua: node.output(func, serial_debug)
|
// Lua: node.output(func, serial_debug)
|
||||||
static int node_output(lua_State *L) {
|
static int node_output(lua_State *L) {
|
||||||
|
if (serial_debug)
|
||||||
|
{
|
||||||
|
fclose(serial_debug);
|
||||||
|
serial_debug = NULL;
|
||||||
|
}
|
||||||
if (lua_isfunction(L, 1)) {
|
if (lua_isfunction(L, 1)) {
|
||||||
if (output_redir == LUA_NOREF) {
|
if (output_redir == LUA_NOREF) {
|
||||||
// create an instance of a virtual filesystem so we can use fopen
|
// create an instance of a virtual filesystem so we can use fopen
|
||||||
|
@ -439,69 +508,25 @@ static int node_output(lua_State *L) {
|
||||||
};
|
};
|
||||||
// register this filesystem under the `/redir` namespace
|
// register this filesystem under the `/redir` namespace
|
||||||
ESP_ERROR_CHECK(esp_vfs_register(VFS_REDIR, &redir_fs, NULL));
|
ESP_ERROR_CHECK(esp_vfs_register(VFS_REDIR, &redir_fs, NULL));
|
||||||
oldstdout = stdout; // save the previous stdout
|
freopen(VFS_REDIR, "w", stdout);
|
||||||
stdout = fopen(VFS_REDIR, "w"); // open the new one for writing
|
|
||||||
|
if (lua_isnoneornil(L, 2) ||
|
||||||
|
(lua_isnumber(L, 2) && lua_tonumber(L, 2)))
|
||||||
|
serial_debug = fopen(default_console_name(), "w");
|
||||||
} else {
|
} else {
|
||||||
luaX_unset_ref(L, &output_redir); // dereference previous callback
|
luaX_unset_ref(L, &output_redir); // dereference previous callback
|
||||||
}
|
}
|
||||||
luaX_set_ref(L, 1, &output_redir); // set the callback
|
luaX_set_ref(L, 1, &output_redir); // set the callback
|
||||||
} else {
|
} else {
|
||||||
if (output_redir != LUA_NOREF) {
|
if (output_redir != LUA_NOREF) {
|
||||||
fclose(stdout); // close the redirected stdout
|
#if defined(CONFIG_ESP_CONSOLE_NONE)
|
||||||
stdout = oldstdout; // restore original stdout
|
fclose(stdout);
|
||||||
ESP_ERROR_CHECK(esp_vfs_unregister(VFS_REDIR)); // unregister redir filesystem
|
#else
|
||||||
luaX_unset_ref(L, &output_redir); // forget callback
|
// reopen the console device onto the stdout stream
|
||||||
}
|
freopen(default_console_name(), "w", stdout);
|
||||||
serial_debug = 1;
|
#endif
|
||||||
return 0;
|
ESP_ERROR_CHECK(esp_vfs_unregister(VFS_REDIR));
|
||||||
}
|
luaX_unset_ref(L, &output_redir);
|
||||||
|
|
||||||
// second parameter indicates whether output will also be sent to old stdout
|
|
||||||
if (lua_isnumber(L, 2)) {
|
|
||||||
serial_debug = lua_tointeger(L, 2);
|
|
||||||
if (serial_debug != 0)
|
|
||||||
serial_debug = 1;
|
|
||||||
} else {
|
|
||||||
serial_debug = 1; // default to 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The implementation of node.osoutput redirect all OS logging to Lua space
|
|
||||||
lua_ref_t os_output_redir = LUA_NOREF; // this will hold the Lua callback
|
|
||||||
static vprintf_like_t oldvprintf; // keep the old vprintf
|
|
||||||
|
|
||||||
// redir_vprintf will be called everytime the OS attempts to print a trace statement
|
|
||||||
int redir_vprintf(const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
static char data[128];
|
|
||||||
int size = vsnprintf(data, 128, fmt, ap);
|
|
||||||
|
|
||||||
if (os_output_redir != LUA_NOREF) { // prepare lua call
|
|
||||||
lua_State *L = lua_getstate();
|
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, os_output_redir); // push function reference
|
|
||||||
lua_pushlstring(L, (char *)data, size); // push data
|
|
||||||
luaL_pcallx(L, 1, 0); // invoke callback
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Lua: node.output(func, serial_debug)
|
|
||||||
static int node_osoutput(lua_State *L) {
|
|
||||||
if (lua_isfunction(L, 1)) {
|
|
||||||
if (os_output_redir == LUA_NOREF) {
|
|
||||||
// register our log redirect first time this is invoked
|
|
||||||
oldvprintf = esp_log_set_vprintf(redir_vprintf);
|
|
||||||
} else {
|
|
||||||
luaX_unset_ref(L, &os_output_redir); // dereference previous callback
|
|
||||||
}
|
|
||||||
luaX_set_ref(L, 1, &os_output_redir); // set the callback
|
|
||||||
} else {
|
|
||||||
if (os_output_redir != LUA_NOREF) {
|
|
||||||
esp_log_set_vprintf(oldvprintf);
|
|
||||||
luaX_unset_ref(L, &os_output_redir); // forget callback
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,7 +861,6 @@ LROT_BEGIN(node, NULL, 0)
|
||||||
LROT_FUNCENTRY( heap, node_heap )
|
LROT_FUNCENTRY( heap, node_heap )
|
||||||
LROT_FUNCENTRY( input, node_input )
|
LROT_FUNCENTRY( input, node_input )
|
||||||
LROT_FUNCENTRY( output, node_output )
|
LROT_FUNCENTRY( output, node_output )
|
||||||
LROT_FUNCENTRY( osoutput, node_osoutput )
|
|
||||||
LROT_FUNCENTRY( osprint, node_osprint )
|
LROT_FUNCENTRY( osprint, node_osprint )
|
||||||
LROT_FUNCENTRY( restart, node_restart )
|
LROT_FUNCENTRY( restart, node_restart )
|
||||||
LROT_FUNCENTRY( setonerror, node_setonerror )
|
LROT_FUNCENTRY( setonerror, node_setonerror )
|
||||||
|
@ -849,6 +873,8 @@ LROT_END(node, NULL, 0)
|
||||||
|
|
||||||
int luaopen_node(lua_State *L)
|
int luaopen_node(lua_State *L)
|
||||||
{
|
{
|
||||||
|
output_task = task_get_id(redir_output);
|
||||||
|
|
||||||
lua_settop(L, 0);
|
lua_settop(L, 0);
|
||||||
return node_setonerror(L); /* set default onerror action */
|
return node_setonerror(L); /* set default onerror action */
|
||||||
}
|
}
|
||||||
|
|
|
@ -1037,7 +1037,7 @@ LROT_END(sjson, NULL, 0)
|
||||||
LUALIB_API int luaopen_sjson (lua_State *L) {
|
LUALIB_API int luaopen_sjson (lua_State *L) {
|
||||||
luaL_rometatable(L, "sjson.decoder", LROT_TABLEREF(sjson_decoder_map));
|
luaL_rometatable(L, "sjson.decoder", LROT_TABLEREF(sjson_decoder_map));
|
||||||
luaL_rometatable(L, "sjson.encoder", LROT_TABLEREF(sjson_encoder_map));
|
luaL_rometatable(L, "sjson.encoder", LROT_TABLEREF(sjson_encoder_map));
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NODEMCU_MODULE(SJSON, "sjson", sjson, luaopen_sjson);
|
NODEMCU_MODULE(SJSON, "sjson", sjson, luaopen_sjson);
|
||||||
|
|
|
@ -233,6 +233,15 @@ static int tmr_create( lua_State *L ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Lua: tmr.wdclr()
|
||||||
|
static int tmr_wdclr( lua_State *L )
|
||||||
|
{
|
||||||
|
// Suspend ourselves momentarily to let the IDLE task do its thing
|
||||||
|
vTaskDelay(1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Module function map
|
// Module function map
|
||||||
|
|
||||||
LROT_BEGIN(tmr_dyn, NULL, LROT_MASK_GC_INDEX)
|
LROT_BEGIN(tmr_dyn, NULL, LROT_MASK_GC_INDEX)
|
||||||
|
@ -249,6 +258,7 @@ LROT_END(tmr_dyn, NULL, LROT_MASK_GC_INDEX)
|
||||||
|
|
||||||
LROT_BEGIN(tmr, NULL, 0)
|
LROT_BEGIN(tmr, NULL, 0)
|
||||||
LROT_FUNCENTRY( create, tmr_create )
|
LROT_FUNCENTRY( create, tmr_create )
|
||||||
|
LROT_FUNCENTRY( wdclr, tmr_wdclr )
|
||||||
LROT_NUMENTRY ( ALARM_SINGLE, TIMER_MODE_SINGLE )
|
LROT_NUMENTRY ( ALARM_SINGLE, TIMER_MODE_SINGLE )
|
||||||
LROT_NUMENTRY ( ALARM_SEMI, TIMER_MODE_SEMI )
|
LROT_NUMENTRY ( ALARM_SEMI, TIMER_MODE_SEMI )
|
||||||
LROT_NUMENTRY ( ALARM_AUTO, TIMER_MODE_AUTO )
|
LROT_NUMENTRY ( ALARM_AUTO, TIMER_MODE_AUTO )
|
||||||
|
|
|
@ -76,7 +76,7 @@ static void dht_deinit( void )
|
||||||
static int dht_init( uint8_t gpio_num )
|
static int dht_init( uint8_t gpio_num )
|
||||||
{
|
{
|
||||||
// acquire an RMT module for RX
|
// acquire an RMT module for RX
|
||||||
if ((dht_rmt.channel = platform_rmt_allocate( 1 )) >= 0) {
|
if ((dht_rmt.channel = platform_rmt_allocate( 1, RMT_MODE_RX )) >= 0) {
|
||||||
|
|
||||||
#ifdef DHT_DEBUG
|
#ifdef DHT_DEBUG
|
||||||
ESP_LOGI("dht", "RMT RX channel: %d", dht_rmt.channel);
|
ESP_LOGI("dht", "RMT RX channel: %d", dht_rmt.channel);
|
||||||
|
|
|
@ -14,13 +14,14 @@
|
||||||
* @brief Allocate an RMT channel.
|
* @brief Allocate an RMT channel.
|
||||||
*
|
*
|
||||||
* @param num_mem Number of memory blocks.
|
* @param num_mem Number of memory blocks.
|
||||||
|
* @param mode Mode of the channel, RMT_MODE_TX allocates a TX channel, RMT_MODE_RX an RX channel.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* - Channel number when successful
|
* - Channel number when successful
|
||||||
* - -1 if no channel available
|
* - -1 if no channel available
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int platform_rmt_allocate( uint8_t num_mem );
|
int platform_rmt_allocate( uint8_t num_mem, rmt_mode_t mode );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Release a previously allocated RMT channel.
|
* @brief Release a previously allocated RMT channel.
|
||||||
|
|
|
@ -113,8 +113,8 @@ static int onewire_rmt_init( uint8_t gpio_num )
|
||||||
}
|
}
|
||||||
|
|
||||||
// acquire an RMT module for TX and RX each
|
// acquire an RMT module for TX and RX each
|
||||||
if ((ow_rmt.tx = platform_rmt_allocate( 1 )) >= 0) {
|
if ((ow_rmt.tx = platform_rmt_allocate( 1, RMT_MODE_TX )) >= 0) {
|
||||||
if ((ow_rmt.rx = platform_rmt_allocate( 1 )) >= 0) {
|
if ((ow_rmt.rx = platform_rmt_allocate( 1, RMT_MODE_RX )) >= 0) {
|
||||||
|
|
||||||
#ifdef OW_DEBUG
|
#ifdef OW_DEBUG
|
||||||
ESP_LOGI("ow", "RMT TX channel: %d", ow_rmt.tx);
|
ESP_LOGI("ow", "RMT TX channel: %d", ow_rmt.tx);
|
||||||
|
|
|
@ -116,12 +116,6 @@ static void task_uart( void *pvParameters ){
|
||||||
if(xQueueReceive(uart_status[id].queue, (void * )&event, (portTickType)portMAX_DELAY)) {
|
if(xQueueReceive(uart_status[id].queue, (void * )&event, (portTickType)portMAX_DELAY)) {
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case UART_DATA: {
|
case UART_DATA: {
|
||||||
post = (uart_event_post_t*)malloc(sizeof(uart_event_post_t));
|
|
||||||
if(post == NULL) {
|
|
||||||
ESP_LOGE(UART_TAG, "Can not alloc memory in task_uart()");
|
|
||||||
// reboot here?
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Attempt to coalesce received bytes to reduce risk of overrunning
|
// Attempt to coalesce received bytes to reduce risk of overrunning
|
||||||
// the task event queue.
|
// the task event queue.
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -129,6 +123,13 @@ static void task_uart( void *pvParameters ){
|
||||||
len = event.size;
|
len = event.size;
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
continue; // we already gobbled all the bytes
|
continue; // we already gobbled all the bytes
|
||||||
|
|
||||||
|
post = (uart_event_post_t*)malloc(sizeof(uart_event_post_t));
|
||||||
|
if(post == NULL) {
|
||||||
|
ESP_LOGE(UART_TAG, "Can not alloc memory in task_uart()");
|
||||||
|
// reboot here?
|
||||||
|
continue;
|
||||||
|
}
|
||||||
post->data = malloc(len);
|
post->data = malloc(len);
|
||||||
if(post->data == NULL) {
|
if(post->data == NULL) {
|
||||||
ESP_LOGE(UART_TAG, "Can not alloc memory in task_uart()");
|
ESP_LOGE(UART_TAG, "Can not alloc memory in task_uart()");
|
||||||
|
|
|
@ -24,12 +24,33 @@ static bool rmt_channel_check( uint8_t channel, uint8_t num_mem )
|
||||||
return rmt_channel_check( channel-1, num_mem-1);
|
return rmt_channel_check( channel-1, num_mem-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int platform_rmt_allocate( uint8_t num_mem )
|
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
|
int platform_rmt_allocate( uint8_t num_mem, rmt_mode_t mode )
|
||||||
|
#else
|
||||||
|
int platform_rmt_allocate( uint8_t num_mem, rmt_mode_t mode __attribute__((unused)))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
int channel;
|
int channel;
|
||||||
|
int alloc_min;
|
||||||
|
int alloc_max;
|
||||||
uint8_t tag = 1;
|
uint8_t tag = 1;
|
||||||
|
|
||||||
for (channel = RMT_CHANNEL_MAX-1; channel >= 0; channel--) {
|
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
|
/* The ESP32-C3 is limited to TX on channel 0-1 and RX on channel 2-3. */
|
||||||
|
if( mode==RMT_MODE_TX ) {
|
||||||
|
alloc_min = 0;
|
||||||
|
alloc_max = SOC_RMT_TX_CANDIDATES_PER_GROUP - 1;
|
||||||
|
} else {
|
||||||
|
alloc_min = RMT_CHANNEL_MAX - SOC_RMT_RX_CANDIDATES_PER_GROUP;
|
||||||
|
alloc_max = RMT_CHANNEL_MAX - 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* The other ESP32 devices can do RX and TX on all channels. */
|
||||||
|
alloc_min = 0;
|
||||||
|
alloc_max = RMT_CHANNEL_MAX - 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (channel = alloc_max; channel >= alloc_min; channel--) {
|
||||||
if (rmt_channel_alloc[channel] == 0) {
|
if (rmt_channel_alloc[channel] == 0) {
|
||||||
if (rmt_channel_check( channel, num_mem )) {
|
if (rmt_channel_check( channel, num_mem )) {
|
||||||
rmt_channel_alloc[channel] = tag++;
|
rmt_channel_alloc[channel] = tag++;
|
||||||
|
|
|
@ -138,7 +138,7 @@ int platform_ws2812_setup( uint8_t gpio_num, uint8_t num_mem, const uint8_t *dat
|
||||||
{
|
{
|
||||||
int channel;
|
int channel;
|
||||||
|
|
||||||
if ((channel = platform_rmt_allocate( num_mem )) >= 0) {
|
if ((channel = platform_rmt_allocate( num_mem, RMT_MODE_TX )) >= 0) {
|
||||||
ws2812_chain_t *chain = &(ws2812_chains[channel]);
|
ws2812_chain_t *chain = &(ws2812_chains[channel]);
|
||||||
|
|
||||||
chain->valid = true;
|
chain->valid = true;
|
||||||
|
|
|
@ -200,3 +200,21 @@ eth.set_ip({
|
||||||
dns = "8.8.8.8"
|
dns = "8.8.8.8"
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## eth.set_hostname()
|
||||||
|
Configures the interface specific hostname for the ethernet interface. The ethernet interface must be initialized before the hostname can be configured.
|
||||||
|
|
||||||
|
By default the system hostname is used, as configured in the menu config.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
```lua
|
||||||
|
eth.set_hostname(hostname)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
- `hostname` the hostname to use on the ethernet interface
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
`nil`
|
||||||
|
|
||||||
|
An error is thrown in case the hostname cannot be set.
|
||||||
|
|
|
@ -301,68 +301,20 @@ Reload LFS with the flash image provided. Flash images can be generated on the h
|
||||||
- The reload process internally makes multiple passes through the LFS image file. The first pass validates the file and header formats and detects many errors. If any is detected then an error string is returned.
|
- The reload process internally makes multiple passes through the LFS image file. The first pass validates the file and header formats and detects many errors. If any is detected then an error string is returned.
|
||||||
|
|
||||||
|
|
||||||
## node.key() --deprecated
|
|
||||||
|
|
||||||
Defines action to take on button press (on the old devkit 0.9), button connected to GPIO 16.
|
|
||||||
|
|
||||||
This function is only available if the firmware was compiled with DEVKIT_VERSION_0_9 defined.
|
|
||||||
|
|
||||||
#### Syntax
|
|
||||||
`node.key(type, function())`
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
- `type`: type is either string "long" or "short". long: press the key for 3 seconds, short: press shortly(less than 3 seconds)
|
|
||||||
- `function`: user defined function which is called when key is pressed. If nil, remove the user defined function. Default function: long: change LED blinking rate, short: reset chip
|
|
||||||
|
|
||||||
#### Returns
|
|
||||||
`nil`
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
```lua
|
|
||||||
node.key("long", function() print('hello world') end)
|
|
||||||
```
|
|
||||||
#### See also
|
|
||||||
[`node.led()`](#nodeled-deprecated)
|
|
||||||
|
|
||||||
## node.led() --deprecated
|
|
||||||
|
|
||||||
Sets the on/off time for the LED (on the old devkit 0.9), with the LED connected to GPIO16, multiplexed with [`node.key()`](#nodekey-deprecated).
|
|
||||||
|
|
||||||
This function is only available if the firmware was compiled with DEVKIT_VERSION_0_9 defined.
|
|
||||||
|
|
||||||
#### Syntax
|
|
||||||
`node.led(low, high)`
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
- `low` LED off time, LED keeps on when low=0. Unit: milliseconds, time resolution: 80~100ms
|
|
||||||
- `high` LED on time. Unit: milliseconds, time resolution: 80~100ms
|
|
||||||
|
|
||||||
#### Returns
|
|
||||||
`nil`
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
```lua
|
|
||||||
-- turn led on forever.
|
|
||||||
node.led(0)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### See also
|
|
||||||
[`node.key()`](#nodekey-deprecated)
|
|
||||||
|
|
||||||
## node.output()
|
## node.output()
|
||||||
|
|
||||||
Redirects the Lua interpreter output to a callback function. Optionally also prints it to the serial console.
|
Redirects all standard output (`stdout`) to a callback function. Optionally also prints it to the console device, as specified in Kconfig under the "ESP System Settings" section.
|
||||||
|
|
||||||
!!! note "Note:"
|
!!! note "Note:"
|
||||||
|
|
||||||
Do **not** attempt to `print()` or otherwise induce the Lua interpreter to produce output from within the callback function. Doing so results in infinite recursion, and leads to a watchdog-triggered restart.
|
Do **not** attempt to `print()` or otherwise induce the Lua interpreter to produce output from within the callback function. Doing so results in infinite recursion, and leads to a crash or watchdog-triggered restart.
|
||||||
|
|
||||||
#### Syntax
|
#### Syntax
|
||||||
`node.output(function(str), serial_output)`
|
`node.output(function(str), console_output)`
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
- `output_fn(str)` a function accept every output as str, and can send the output to a socket (or maybe a file). `nil` to unregister the previous function.
|
- `output_fn(str)` a function accept every output as str, and can send the output to a socket (or maybe a file). `nil` to unregister the previous function.
|
||||||
- `serial_output` 1 output also sent out the serial port. 0: no serial output. Defaults to 1 if not specified.
|
- `console_output` 1 output also sent out the console port. 0: no console output. Defaults to 1 if not specified.
|
||||||
|
|
||||||
#### Returns
|
#### Returns
|
||||||
`nil`
|
`nil`
|
||||||
|
@ -372,7 +324,7 @@ Redirects the Lua interpreter output to a callback function. Optionally also pri
|
||||||
function tonet(str)
|
function tonet(str)
|
||||||
sk:send(str)
|
sk:send(str)
|
||||||
end
|
end
|
||||||
node.output(tonet, 1) -- serial also get the lua output.
|
node.output(tonet, 1) -- console also get the lua output.
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
@ -403,37 +355,6 @@ node.output(nil, 0)
|
||||||
#### See also
|
#### See also
|
||||||
[`node.input()`](#nodeinput)
|
[`node.input()`](#nodeinput)
|
||||||
|
|
||||||
## node.osoutput()
|
|
||||||
|
|
||||||
Redirects the debugging output from the Espressif SDK to a callback function allowing it to be captured or processed in Lua.
|
|
||||||
|
|
||||||
####Syntax
|
|
||||||
`node.osoutput(function(str))`
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `function(str)` a function accepts debugging output as str, and can send the output to a socket (or maybe a file). `nil` to unregister the previous function.
|
|
||||||
|
|
||||||
#### Returns
|
|
||||||
|
|
||||||
Nothing
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
|
||||||
```lua
|
|
||||||
function luaprint(str)
|
|
||||||
print("lua space: "str)
|
|
||||||
end
|
|
||||||
node.osoutput(luaprint)
|
|
||||||
```
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- disable all output completely
|
|
||||||
node.osoutput(nil)
|
|
||||||
```
|
|
||||||
|
|
||||||
## node.readvdd33() --deprecated
|
|
||||||
Moved to [`adc.readvdd33()`](adc/#adcreadvdd33).
|
|
||||||
|
|
||||||
## node.restart()
|
## node.restart()
|
||||||
|
|
||||||
|
|
|
@ -212,3 +212,37 @@ none
|
||||||
|
|
||||||
#### See also
|
#### See also
|
||||||
[`tmr.obj:register()`](#tmrobjregister)
|
[`tmr.obj:register()`](#tmrobjregister)
|
||||||
|
|
||||||
|
|
||||||
|
## tmr.wdclr()
|
||||||
|
|
||||||
|
Resets the watchdog timer to prevent a reboot due to a perceived hung task.
|
||||||
|
|
||||||
|
Use with caution, as this could prevent a reboot to recover from a
|
||||||
|
genuinely hung task.
|
||||||
|
|
||||||
|
On the ESP32, the `tmr.wdclr()` function is implemented as a task yield
|
||||||
|
to let the system "IDLE" task do the necessary watchdog maintenance.
|
||||||
|
Overuse of this function is likely to result in degraded performance.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`tmr.wdclr()`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
none
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
`nil`
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
```lua
|
||||||
|
function long_running_function()
|
||||||
|
while 1
|
||||||
|
do
|
||||||
|
if some_condition then break end
|
||||||
|
-- do some heavy calculation here, for example
|
||||||
|
tmr.wdclr()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue