Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for issues in #3648 #3652

Merged
merged 4 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 44 additions & 8 deletions components/base_nodemcu/user_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,24 @@
#define SIG_LUA 0
#define SIG_UARTINPUT 1

// Line ending config from Kconfig
#if CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF
# define RX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_CRLF
#elif CONFIG_NEWLIB_STDIN_LINE_ENDING_CR
# define RX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_CR
#else
# define RX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_LF
#endif

#if CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF
# define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_CRLF
#elif CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR
# define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_CR
#else
# define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_LF
#endif


// We don't get argument size data from the esp_event dispatch, so it's
// not possible to copy and forward events from the default event queue
// to one running within our task context. To cope with this, we instead
Expand Down Expand Up @@ -148,11 +166,29 @@ static void nodemcu_init(void)
}


static bool have_console_on_data_cb(void)
{
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
return uart_has_on_data_cb(CONFIG_ESP_CONSOLE_UART_NUM);
#else
return false;
#endif
}


static void console_nodemcu_task(task_param_t param, task_prio_t prio)
{
(void)prio;
char c = (char)param;
feed_lua_input(&c, 1);

if (run_input)
feed_lua_input(&c, 1);

#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
if (have_console_on_data_cb())
uart_feed_data(CONFIG_ESP_CONSOLE_UART_NUM, &c, 1);
#endif

// The IDF doesn't seem to honor setvbuf(stdout, NULL, _IONBF, 0) :(
fsync(fileno(stdout));
}
Expand All @@ -168,7 +204,7 @@ static void console_task(void *)
*/
char c;
ssize_t n = read(fileno(stdin), &c, 1);
if (n > 0 && run_input)
if (n > 0 && (run_input || have_console_on_data_cb()))
{
if (!task_post_block_high(lua_feed_task, (task_param_t)c))
{
Expand Down Expand Up @@ -196,9 +232,9 @@ static void console_init(void)
/* Based on console/advanced example */

esp_vfs_dev_uart_port_set_rx_line_endings(
CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
CONFIG_ESP_CONSOLE_UART_NUM, RX_LINE_ENDINGS_CFG);
esp_vfs_dev_uart_port_set_tx_line_endings(
CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
CONFIG_ESP_CONSOLE_UART_NUM, TX_LINE_ENDINGS_CFG);

/* Configure UART. Note that REF_TICK is used so that the baud rate remains
* correct while APB frequency is changing in light sleep mode.
Expand All @@ -224,8 +260,8 @@ static void console_init(void)
#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
/* Based on @pjsg's work */

esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(RX_LINE_ENDINGS_CFG);
esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(TX_LINE_ENDINGS_CFG);

usb_serial_jtag_driver_config_t usb_serial_jtag_config =
USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
Expand All @@ -236,8 +272,8 @@ static void console_init(void)
#elif CONFIG_ESP_CONSOLE_USB_CDC
/* Based on console/advanced_usb_cdc */

esp_vfs_dev_cdcacm_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
esp_vfs_dev_cdcacm_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
esp_vfs_dev_cdcacm_set_rx_line_endings(RX_LINE_ENDINGS_CFG);
esp_vfs_dev_cdcacm_set_tx_line_endings(TX_LINE_ENDINGS_CFG);
#else
# error "Unsupported console type"
#endif
Expand Down
8 changes: 8 additions & 0 deletions components/modules/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ static int node_chipid( lua_State *L )
}
#endif

// Lua: node.chipmodel()
static int node_chipmodel(lua_State *L)
{
lua_pushstring(L, CONFIG_IDF_TARGET);
return 1;
}

// Lua: node.heap()
static int node_heap( lua_State* L )
{
Expand Down Expand Up @@ -868,6 +875,7 @@ LROT_BEGIN(node, NULL, 0)
#if defined(CONFIG_IDF_TARGET_ESP32)
LROT_FUNCENTRY( chipid, node_chipid )
#endif
LROT_FUNCENTRY( chipmodel, node_chipmodel )
LROT_FUNCENTRY( compile, node_compile )
LROT_FUNCENTRY( dsleep, node_dsleep )
#if defined(CONFIG_LUA_VERSION_51)
Expand Down
124 changes: 90 additions & 34 deletions components/modules/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,93 @@
#include "lauxlib.h"
#include "platform.h"
#include "linput.h"
#include "lmem.h"

#include <stdint.h>
#include <string.h>

typedef struct {
int receive_rf;
int error_rf;
char *line_buffer;
size_t line_position;
uint16_t need_len;
int16_t end_char;
} uart_cb_cfg_t;

static lua_State *gL = NULL;
static uart_cb_cfg_t uart_cb_cfg[NUM_UART];

bool uart_has_on_data_cb(unsigned id){
return uart_status[id].receive_rf != LUA_NOREF;
}

bool uart_on_data_cb(unsigned id, const char *buf, size_t len){
static bool uart_on_data_cb(unsigned id, const char *buf, size_t len){
if(!buf || len==0)
return false;
if(uart_status[id].receive_rf == LUA_NOREF)
if(uart_cb_cfg[id].receive_rf == LUA_NOREF)
return false;
if(!gL)
return false;

int top = lua_gettop(gL);
lua_rawgeti(gL, LUA_REGISTRYINDEX, uart_status[id].receive_rf);
lua_rawgeti(gL, LUA_REGISTRYINDEX, uart_cb_cfg[id].receive_rf);
lua_pushlstring(gL, buf, len);
luaL_pcallx(gL, 1, 0);
lua_settop(gL, top);
return !run_input;
}


bool uart_on_error_cb(unsigned id, const char *buf, size_t len){
if(!buf || len==0)
return false;
if(uart_status[id].error_rf == LUA_NOREF)
if(uart_cb_cfg[id].error_rf == LUA_NOREF)
return false;
if(!gL)
return false;

int top = lua_gettop(gL);
lua_rawgeti(gL, LUA_REGISTRYINDEX, uart_status[id].error_rf);
lua_rawgeti(gL, LUA_REGISTRYINDEX, uart_cb_cfg[id].error_rf);
lua_pushlstring(gL, buf, len);
luaL_pcallx(gL, 1, 0);
lua_settop(gL, top);
return true;
}


bool uart_has_on_data_cb(unsigned id){
return uart_cb_cfg[id].receive_rf != LUA_NOREF;
}


void uart_feed_data(unsigned id, const char *buf, size_t len)
{
if (id >= NUM_UART)
return;

uart_cb_cfg_t *cfg = &uart_cb_cfg[id];
if (!cfg->line_buffer)
return;

for (unsigned i = 0; i < len; ++i)
{
char ch = buf[i];
cfg->line_buffer[cfg->line_position] = ch;
cfg->line_position++;

uint16_t need_len = cfg->need_len;
int16_t end_char = cfg->end_char;
size_t max_wanted =
(end_char >= 0 && need_len == 0) ? LUA_MAXINPUT : need_len;
bool at_end = (cfg->line_position >= max_wanted);
bool end_char_found =
(end_char >= 0 && (uint8_t)ch == (uint8_t)end_char);
if (at_end || end_char_found) {
uart_on_data_cb(id, cfg->line_buffer, cfg->line_position);
cfg->line_position = 0;
}
}
}


// Lua: uart.on([id], "method", [number/char], function, [run_input])
static int uart_on( lua_State* L )
{
Expand All @@ -54,26 +99,28 @@ static int uart_on( lua_State* L )
int32_t run = 1;
uint8_t stack = 1;
const char *method;
uart_status_t *us;

if( lua_isnumber( L, stack ) ) {
id = ( unsigned )luaL_checkinteger( L, stack );
MOD_CHECK_ID( uart, id );
stack++;
}
us = & uart_status[id];

uart_cb_cfg_t *cfg = &uart_cb_cfg[id];

method = luaL_checklstring( L, stack, &sl );
stack++;
if (method == NULL)
return luaL_error( L, "wrong arg type" );

if( lua_type( L, stack ) == LUA_TNUMBER )
{
us->need_len = ( uint16_t )luaL_checkinteger( L, stack );
cfg->need_len = (uint16_t)luaL_checkinteger(L, stack);
stack++;
us->end_char = -1;
if( us->need_len > 255 ){
us->need_len = 255;
cfg->end_char = -1;
if(cfg->need_len > 255)
{
cfg->need_len = 255;
return luaL_error( L, "wrong arg range" );
}
}
Expand All @@ -84,8 +131,8 @@ static int uart_on( lua_State* L )
if(el!=1){
return luaL_error( L, "wrong arg range" );
}
us->end_char = (int16_t)end[0];
us->need_len = 0;
cfg->end_char = (int16_t)end[0];
cfg->need_len = 0;
}

if (lua_isfunction(L, stack)) {
Expand All @@ -99,25 +146,25 @@ static int uart_on( lua_State* L )
if(sl == 4 && strcmp(method, "data") == 0){
if(id == CONFIG_ESP_CONSOLE_UART_NUM)
run_input = true;
if(us->receive_rf != LUA_NOREF){
luaL_unref(L, LUA_REGISTRYINDEX, us->receive_rf);
us->receive_rf = LUA_NOREF;
if(cfg->receive_rf != LUA_NOREF){
luaL_unref(L, LUA_REGISTRYINDEX, cfg->receive_rf);
cfg->receive_rf = LUA_NOREF;
}
if(!lua_isnil(L, -1)){
us->receive_rf = luaL_ref(L, LUA_REGISTRYINDEX);
cfg->receive_rf = luaL_ref(L, LUA_REGISTRYINDEX);
gL = L;
if(id == CONFIG_ESP_CONSOLE_UART_NUM && run==0)
run_input = false;
} else {
lua_pop(L, 1);
}
} else if(sl == 5 && strcmp(method, "error") == 0){
if(us->error_rf != LUA_NOREF){
luaL_unref(L, LUA_REGISTRYINDEX, us->error_rf);
us->error_rf = LUA_NOREF;
if(cfg->error_rf != LUA_NOREF){
luaL_unref(L, LUA_REGISTRYINDEX, cfg->error_rf);
cfg->error_rf = LUA_NOREF;
}
if(!lua_isnil(L, -1)){
us->error_rf = luaL_ref(L, LUA_REGISTRYINDEX);
cfg->error_rf = luaL_ref(L, LUA_REGISTRYINDEX);
gL = L;
} else {
lua_pop(L, 1);
Expand Down Expand Up @@ -183,7 +230,7 @@ static int uart_setup( lua_State* L )
static int uart_setmode(lua_State* L)
{
unsigned id, mode;

id = luaL_checkinteger( L, 1 );
MOD_CHECK_ID( uart, id );
mode = luaL_checkinteger( L, 2 );
Expand Down Expand Up @@ -230,6 +277,11 @@ static int uart_stop( lua_State* L )
id = luaL_checkinteger( L, 1 );
MOD_CHECK_ID( uart, id );
platform_uart_stop( id );
if (uart_cb_cfg[id].line_buffer)
{
luaM_freemem(L, uart_cb_cfg[id].line_buffer, LUA_MAXINPUT);
uart_cb_cfg[id].line_buffer = NULL;
}
return 0;
}

Expand All @@ -240,6 +292,8 @@ static int uart_start( lua_State* L )
int err;
id = luaL_checkinteger( L, 1 );
MOD_CHECK_ID( uart, id );
if (!uart_cb_cfg[id].line_buffer)
uart_cb_cfg[id].line_buffer = luaM_malloc(L, LUA_MAXINPUT);
err = platform_uart_start( id );
lua_pushboolean( L, err == 0 );
return 1;
Expand Down Expand Up @@ -303,21 +357,23 @@ LROT_BEGIN(uart, NULL, 0)
LROT_NUMENTRY( FLOWCTRL_NONE, PLATFORM_UART_FLOW_NONE )
LROT_NUMENTRY( FLOWCTRL_CTS, PLATFORM_UART_FLOW_CTS )
LROT_NUMENTRY( FLOWCTRL_RTS, PLATFORM_UART_FLOW_RTS )
LROT_NUMENTRY( MODE_UART, PLATFORM_UART_MODE_UART )
LROT_NUMENTRY( MODE_UART, PLATFORM_UART_MODE_UART )
LROT_NUMENTRY( MODE_RS485_COLLISION_DETECT, PLATFORM_UART_MODE_RS485_COLLISION_DETECT )
LROT_NUMENTRY( MODE_RS485_APP_CONTROL, PLATFORM_UART_MODE_RS485_APP_CONTROL )
LROT_NUMENTRY( MODE_RS485_HALF_DUPLEX, PLATFORM_UART_MODE_HALF_DUPLEX )
LROT_NUMENTRY( MODE_IRDA, PLATFORM_UART_MODE_IRDA )
LROT_NUMENTRY( MODE_IRDA, PLATFORM_UART_MODE_IRDA )
LROT_END(uart, NULL, 0)

int luaopen_uart( lua_State *L ) {
uart_status_t *us;
for(int id = 0; id < NUM_UART; id++) {
us = & uart_status[id];
us->receive_rf = LUA_NOREF;
us->error_rf = LUA_NOREF;
us->need_len = 0;
us->end_char = -1;
for(int id = 0; id < sizeof(uart_cb_cfg)/sizeof(uart_cb_cfg[0]); id++)
{
uart_cb_cfg_t *cfg = &uart_cb_cfg[id];
cfg->receive_rf = LUA_NOREF;
cfg->error_rf = LUA_NOREF;
cfg->line_buffer = NULL;
cfg->line_position = 0;
cfg->need_len = 0;
cfg->end_char = -1;
}
return 0;
}
Expand Down
11 changes: 4 additions & 7 deletions components/platform/include/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,12 @@ typedef struct {
typedef struct {
QueueHandle_t queue;
TaskHandle_t taskHandle;
int receive_rf;
int error_rf;
char *line_buffer;
size_t line_position;
uint16_t need_len;
int16_t end_char;
} uart_status_t;

extern uart_status_t uart_status[NUM_UART];
// We have a bit of legacy spaghetti - these point into modules/uart.c
extern bool uart_has_on_data_cb(unsigned id);
extern void uart_feed_data(unsigned id, const char *buf, size_t len);
extern bool uart_on_error_cb(unsigned id, const char *buf, size_t len);

// Flow control types (this is a bit mask, one can specify PLATFORM_UART_FLOW_RTS | PLATFORM_UART_FLOW_CTS )
#define PLATFORM_UART_FLOW_NONE 0
Expand Down
Loading