diff --git a/components/base_nodemcu/user_main.c b/components/base_nodemcu/user_main.c index 9ccb56c1..565c3537 100644 --- a/components/base_nodemcu/user_main.c +++ b/components/base_nodemcu/user_main.c @@ -20,7 +20,6 @@ #include "nvs_flash.h" #include "flash_api.h" -#include "driver/console.h" #include "task/task.h" #include "sections.h" #include "nodemcu_esp_event.h" @@ -95,22 +94,8 @@ static void handle_default_loop_event(task_param_t param, task_prio_t prio) static void start_lua () { NODE_DBG("Task task_lua started.\n"); - lua_main(); -} - -static void handle_input(task_param_t flag, task_prio_t priority) { - (void)flag; (void)priority; - lua_handle_input(); -} - -static task_handle_t input_task; - -task_handle_t user_get_input_sig(void) { - return input_task; -} - -bool user_process_input(bool force) { - return task_post_low(input_task, force); + if (lua_main()) // If it returns true then LFS restart is needed + lua_main(); } void nodemcu_init(void) @@ -144,8 +129,6 @@ void __attribute__((noreturn)) app_main(void) { task_init(); - input_task = task_get_id (handle_input); - relayed_event_handled = xSemaphoreCreateBinary(); relayed_event_task = task_get_id(handle_default_loop_event); @@ -156,19 +139,7 @@ void __attribute__((noreturn)) app_main(void) relay_default_loop_events, NULL); - ConsoleSetup_t cfg; - cfg.bit_rate = CONFIG_NODEMCU_CONSOLE_BIT_RATE; - cfg.data_bits = CONSOLE_NUM_BITS_8; - cfg.parity = CONSOLE_PARITY_NONE; - cfg.stop_bits = CONSOLE_STOP_BITS_1; - cfg.auto_baud = -#ifdef CONFIG_NODEMCU_CONSOLE_BIT_RATE_AUTO - true; -#else - false; -#endif - - console_init (&cfg, input_task); + platform_uart_start(CONFIG_ESP_CONSOLE_UART_NUM); setvbuf(stdout, NULL, _IONBF, 0); nodemcu_init (); diff --git a/components/driver_console/CMakeLists.txt b/components/driver_console/CMakeLists.txt deleted file mode 100644 index b412cdeb..00000000 --- a/components/driver_console/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRCS "console.c" - INCLUDE_DIRS "include" - REQUIRES "task" "esp32" -) diff --git a/components/driver_console/console.c b/components/driver_console/console.c deleted file mode 100644 index 247c0d8f..00000000 --- a/components/driver_console/console.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2016 Dius Computing Pty Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - Neither the name of the copyright holders nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @author Johny Mattsson - */ - -#include "driver/console.h" -#include "driver/uart.h" -#include "esp_intr_alloc.h" -#include "soc/soc.h" -#include "soc/uart_reg.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "sys/reent.h" -#include - -#include "rom/libc_stubs.h" -#include "rom/uart.h" - -#if defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(syscall_table_ptr) -// The ESP32S2 libc_stubs.h is missing this compatibility def it seems -# define syscall_table_ptr syscall_table_ptr_pro -#endif - -#define UART_INPUT_QUEUE_SZ 0x100 - -// These used to be available in soc/uart_register.h: -#define UART_GET_RXFIFO_RD_BYTE(i) GET_PERI_REG_BITS2(UART_FIFO_REG(i) , UART_RXFIFO_RD_BYTE_V, UART_RXFIFO_RD_BYTE_S) -#define UART_GET_RXFIFO_CNT(i) GET_PERI_REG_BITS2(UART_STATUS_REG(i) , UART_RXFIFO_CNT_V, UART_RXFIFO_CNT_S) - - -typedef int (*_read_r_fn) (struct _reent *r, int fd, void *buf, int size); - -static _read_r_fn _read_r_app; -#if defined(CONFIG_IDF_TARGET_ESP32) -static _read_r_fn _read_r_pro; -#endif - -static xQueueHandle uart0Q; -static task_handle_t input_task = 0; - -// --- Syscall support for reading from STDIN_FILENO --------------- - -static int console_read_r (struct _reent *r, int fd, void *buf, int size, _read_r_fn next) -{ - if (fd == STDIN_FILENO) - { - static _lock_t stdin_lock; - _lock_acquire_recursive (&stdin_lock); - char *c = (char *)buf; - int i = 0; - for (; i < size; ++i) - { - if (!console_getc (c++)) - break; - } - _lock_release_recursive (&stdin_lock); - return i; - } - else if (next) - return next (r, fd, buf, size); - else - return -1; -} - -#if defined(CONFIG_IDF_TARGET_ESP32) -static int console_read_r_pro (struct _reent *r, int fd, void *buf, int size) -{ - return console_read_r (r, fd, buf, size, _read_r_pro); -} -#endif -static int console_read_r_app (struct _reent *r, int fd, void *buf, int size) -{ - return console_read_r (r, fd, buf, size, _read_r_app); -} - -// --- End syscall support ------------------------------------------- - -static void uart0_rx_intr_handler (void *arg) -{ - (void)arg; - bool received = false; - uint32_t status = READ_PERI_REG(UART_INT_ST_REG(CONSOLE_UART)); - while (status) - { - if (status & UART_FRM_ERR_INT_ENA) - { - // TODO: report somehow? - WRITE_PERI_REG(UART_INT_CLR_REG(CONSOLE_UART), UART_FRM_ERR_INT_ENA); - } - if ((status & UART_RXFIFO_TOUT_INT_ENA) || - (status & UART_RXFIFO_FULL_INT_ENA)) - { - uint32_t fifo_len = UART_GET_RXFIFO_CNT(CONSOLE_UART); - for (uint32_t i = 0; i < fifo_len; ++i) - { - received = true; - char c = UART_GET_RXFIFO_RD_BYTE(CONSOLE_UART); - if (uart0Q) - xQueueSendToBackFromISR (uart0Q, &c, NULL); - } - WRITE_PERI_REG(UART_INT_CLR_REG(CONSOLE_UART), - UART_RXFIFO_TOUT_INT_ENA | UART_RXFIFO_FULL_INT_ENA); - } - status = READ_PERI_REG(UART_INT_ST_REG(CONSOLE_UART)); - } - if (received && input_task) - task_post_isr_low (input_task, false); -} - - -void console_setup (const ConsoleSetup_t *cfg) -{ - esp_rom_uart_tx_wait_idle (CONSOLE_UART); - - uart_config_t uart_conf = { - .baud_rate = cfg->bit_rate, - .data_bits = - cfg->data_bits == CONSOLE_NUM_BITS_5 ? UART_DATA_5_BITS : - cfg->data_bits == CONSOLE_NUM_BITS_6 ? UART_DATA_6_BITS : - cfg->data_bits == CONSOLE_NUM_BITS_7 ? UART_DATA_7_BITS : - UART_DATA_8_BITS, - .stop_bits = - cfg->stop_bits == CONSOLE_STOP_BITS_1 ? UART_STOP_BITS_1 : - cfg->stop_bits == CONSOLE_STOP_BITS_2 ? UART_STOP_BITS_2 : - UART_STOP_BITS_1_5, - .parity = - cfg->parity == CONSOLE_PARITY_NONE ? UART_PARITY_DISABLE : - cfg->parity == CONSOLE_PARITY_EVEN ? UART_PARITY_EVEN : - UART_PARITY_ODD, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - }; - uart_param_config(CONSOLE_UART, &uart_conf); -} - - - -void console_init (const ConsoleSetup_t *cfg, task_handle_t tsk) -{ - input_task = tsk; - uart0Q = xQueueCreate (UART_INPUT_QUEUE_SZ, sizeof (char)); - - console_setup (cfg); - - uart_isr_register(CONSOLE_UART, uart0_rx_intr_handler, NULL, 0, NULL); - uart_set_rx_timeout(CONSOLE_UART, 2); - uart_set_rx_full_threshold(CONSOLE_UART, 10); - uart_enable_intr_mask(CONSOLE_UART, - UART_RXFIFO_TOUT_INT_ENA_M | - UART_RXFIFO_FULL_INT_ENA_M | - UART_FRM_ERR_INT_ENA_M); - - // Register our console_read_r_xxx functions to support stdin input -#if defined(CONFIG_IDF_TARGET_ESP32) - // Only the original ESP32 uses per-cpu tables; the S2/S3/C3 do not - _read_r_app = syscall_table_ptr_app->_read_r; - _read_r_pro = syscall_table_ptr_pro->_read_r; - syscall_table_ptr_app->_read_r = console_read_r_app; - syscall_table_ptr_pro->_read_r = console_read_r_pro; -#else - _read_r_app = syscall_table_ptr->_read_r; - syscall_table_ptr->_read_r = console_read_r_app; -#endif -} - - -bool console_getc (char *c) -{ - return (uart0Q && (xQueueReceive (uart0Q, c, 0) == pdTRUE)); -} diff --git a/components/driver_console/include/driver/console.h b/components/driver_console/include/driver/console.h deleted file mode 100644 index 25fb747d..00000000 --- a/components/driver_console/include/driver/console.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2016 Dius Computing Pty Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - Neither the name of the copyright holders nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @author Johny Mattsson - */ - -#include "esp_rom_uart.h" -#include "task/task.h" -#include -#include - -#define CONSOLE_UART CONFIG_ESP_CONSOLE_UART_NUM - -typedef enum -{ - CONSOLE_NUM_BITS_5 = 0x0, - CONSOLE_NUM_BITS_6 = 0x1, - CONSOLE_NUM_BITS_7 = 0x2, - CONSOLE_NUM_BITS_8 = 0x3 -} ConsoleNumBits_t; - -typedef enum -{ - CONSOLE_PARITY_NONE = 0x2, - CONSOLE_PARITY_ODD = 0x1, - CONSOLE_PARITY_EVEN = 0x0 -} ConsoleParity_t; - -typedef enum -{ - CONSOLE_STOP_BITS_1 = 0x1, - CONSOLE_STOP_BITS_1_5 = 0x2, - CONSOLE_STOP_BITS_2 = 0x3 -} ConsoleStopBits_t; - -typedef struct -{ - uint32_t bit_rate; - ConsoleNumBits_t data_bits; - ConsoleParity_t parity; - ConsoleStopBits_t stop_bits; - bool auto_baud; -} ConsoleSetup_t; - -void console_init (const ConsoleSetup_t *cfg, task_handle_t tsk); -void console_setup (const ConsoleSetup_t *cfg); -bool console_getc (char *c); diff --git a/components/lua/CMakeLists.txt b/components/lua/CMakeLists.txt index 790b1974..b98e8586 100644 --- a/components/lua/CMakeLists.txt +++ b/components/lua/CMakeLists.txt @@ -81,7 +81,7 @@ set(common_srcs idf_component_register( SRCS ${srcs} ${common_srcs} INCLUDE_DIRS ${luadir} "common" - REQUIRES "platform" "nvs_flash" "uzlib" "driver_console" + REQUIRES "platform" "nvs_flash" "uzlib" PRIV_REQUIRES "base_nodemcu" "embedded_lfs" LDFRAGMENTS "link_lua.lf" ) diff --git a/components/lua/common/linput.c b/components/lua/common/linput.c index 4cf2d51a..2dba1cfd 100644 --- a/components/lua/common/linput.c +++ b/components/lua/common/linput.c @@ -1,4 +1,3 @@ -#include "driver/console.h" #include "platform.h" #include "linput.h" #include "lua.h" @@ -20,17 +19,8 @@ static struct input_state { #define DEL 0x7f #define BS_OVER "\010 \010" -static bool input_readline(void); - -extern bool uart_on_data_cb(unsigned id, const char *buf, size_t len); -extern bool uart0_echo; -extern bool run_input; -extern uart_status_t uart_status[]; - -void lua_handle_input(void) -{ - while(input_readline()) {} -} +bool input_echo = true; +bool run_input = true; /* ** The input state (ins) is private, so input_setup() exposes the necessary @@ -48,83 +38,64 @@ void input_setprompt (const char *prompt) { ins.prompt = prompt; } -/* -** input_readline() is called from the lua_handle_input() event routine which -** is called when input data is available. This works in one of two modes -** depending on the bool ins.run_input. -** - TRUE: it clears the input buf up to EOL, doing any callback and sending -** the line to Lua. -** - FALSE: it clears the input buf doing callbacks according to the data_len -** or end_char break. -*/ -static bool input_readline(void) { - char ch = NUL; - while (console_getc(&ch)) { - if (run_input) { - /* handle CR & LF characters and aggregate \n\r and \r\n pairs */ - char tmp_last_nl_char = ins.last_nl_char; - /* handle CR & LF characters - filters second char of LF&CR (\n\r) or CR&LF (\r\n) sequences */ - if ((ch == CR && tmp_last_nl_char == LF) || // \n\r sequence -> skip \r - (ch == LF && tmp_last_nl_char == CR)) // \r\n sequence -> skip \n - { - continue; + +size_t feed_lua_input(const char *buf, size_t n) +{ + for (size_t i = 0; i < n; ++i) { + char ch = buf[i]; + if (!run_input) // We're no longer interested in the remaining bytes + return i; + + /* handle CR & LF characters and aggregate \n\r and \r\n pairs */ + char tmp_last_nl_char = ins.last_nl_char; + /* handle CR & LF characters + filters second char of LF&CR (\n\r) or CR&LF (\r\n) sequences */ + if ((ch == CR && tmp_last_nl_char == LF) || // \n\r sequence -> skip \r + (ch == LF && tmp_last_nl_char == CR)) // \r\n sequence -> skip \n + { + continue; + } + + /* backspace key */ + if (ch == DEL || ch == BS) { + if (ins.line_pos > 0) { + if(input_echo) printf(BS_OVER); + ins.line_pos--; } + ins.data[ins.line_pos] = 0; + continue; + } - /* backspace key */ - if (ch == DEL || ch == BS) { - if (ins.line_pos > 0) { - if(uart0_echo) printf(BS_OVER); - ins.line_pos--; - } - ins.data[ins.line_pos] = 0; - continue; - } + /* end of data */ + if (ch == CR || ch == LF) { + ins.last_nl_char = ch; - /* end of data */ - if (ch == CR || ch == LF) { - ins.last_nl_char = ch; - - if (uart0_echo) putchar(LF); - if (ins.line_pos == 0) { - /* Get a empty line, then go to get a new line */ - printf(ins.prompt); - fflush(stdout); - continue; - } else { - ins.data[ins.line_pos++] = LF; - lua_input_string(ins.data, ins.line_pos); - ins.line_pos = 0; - return true; - } - } - else - ins.last_nl_char = NUL; - - if(uart0_echo) putchar(ch); - - /* it's a large line, discard it */ - if ( ins.line_pos + 1 >= ins.len ){ + if (input_echo) putchar(LF); + if (ins.line_pos == 0) { + /* Get a empty line, then go to get a new line */ + printf(ins.prompt); + fflush(stdout); + } else { + ins.data[ins.line_pos++] = LF; + lua_input_string(ins.data, ins.line_pos); ins.line_pos = 0; } + continue; + } + else + ins.last_nl_char = NUL; + + if(input_echo) putchar(ch); + + /* it's a large line, discard it */ + if ( ins.line_pos + 1 >= ins.len ){ + ins.line_pos = 0; } ins.data[ins.line_pos++] = ch; - - if (!run_input) - { - uart_status_t *us = & uart_status[CONSOLE_UART]; - if(((us->need_len!=0) && (ins.line_pos>= us->need_len)) || \ - (ins.line_pos >= ins.len) || \ - ((us->end_char>=0) && ((unsigned char)ch==(unsigned char)us->end_char))) - { - uart_on_data_cb(CONSOLE_UART, ins.data, ins.line_pos); - ins.line_pos = 0; - } - } - } - return false; + + return n; // we consumed/buffered all the provided data } diff --git a/components/lua/common/linput.h b/components/lua/common/linput.h index c1b9c8a4..af19fb2a 100644 --- a/components/lua/common/linput.h +++ b/components/lua/common/linput.h @@ -1,9 +1,15 @@ -#ifndef READLINE_APP_H -#define READLINE_APP_H +#ifndef _LINPUT_H_ +#define _LINPUT_H_ -extern void input_setup(int bufsize, const char *prompt); -extern void input_setprompt (const char *prompt); +#include +#include -void lua_handle_input(void); +void input_setup(int bufsize, const char *prompt); +void input_setprompt (const char *prompt); + +unsigned feed_lua_input(const char *buf, size_t n); + +extern bool input_echo; +extern bool run_input; #endif /* READLINE_APP_H */ diff --git a/components/lua/lua-5.3/lua.c b/components/lua/lua-5.3/lua.c index d52bd1f5..f1eb1687 100644 --- a/components/lua/lua-5.3/lua.c +++ b/components/lua/lua-5.3/lua.c @@ -7,7 +7,6 @@ #include #include #include "user_version.h" -#include "driver/console.h" #include "linput.h" #define lua_c diff --git a/components/modules/uart.c b/components/modules/uart.c index ec8c852c..0e97ef43 100644 --- a/components/modules/uart.c +++ b/components/modules/uart.c @@ -3,15 +3,13 @@ #include "module.h" #include "lauxlib.h" #include "platform.h" -#include "driver/console.h" +#include "linput.h" #include #include -extern uart_status_t uart_status[NUM_UART]; - static lua_State *gL = NULL; -bool run_input = true; + bool uart_on_data_cb(unsigned id, const char *buf, size_t len){ if(!buf || len==0) return false; @@ -47,7 +45,7 @@ bool uart_on_error_cb(unsigned id, const char *buf, size_t len){ // Lua: uart.on([id], "method", [number/char], function, [run_input]) static int uart_on( lua_State* L ) { - unsigned id = CONSOLE_UART; + unsigned id = CONFIG_ESP_CONSOLE_UART_NUM; size_t sl, el; int32_t run = 1; uint8_t stack = 1; @@ -95,7 +93,7 @@ static int uart_on( lua_State* L ) lua_pushnil(L); } if(sl == 4 && strcmp(method, "data") == 0){ - if(id == CONSOLE_UART) + if(id == CONFIG_ESP_CONSOLE_UART_NUM) run_input = true; if(us->receive_rf != LUA_NOREF){ luaL_unref(L, LUA_REGISTRYINDEX, us->receive_rf); @@ -104,7 +102,7 @@ static int uart_on( lua_State* L ) if(!lua_isnil(L, -1)){ us->receive_rf = luaL_ref(L, LUA_REGISTRYINDEX); gL = L; - if(id == CONSOLE_UART && run==0) + if(id == CONFIG_ESP_CONSOLE_UART_NUM && run==0) run_input = false; } else { lua_pop(L, 1); @@ -127,7 +125,6 @@ static int uart_on( lua_State* L ) return 0; } -bool uart0_echo = true; // Lua: actualbaud = setup( id, baud, databits, parity, stopbits, echo ) static int uart_setup( lua_State* L ) { @@ -141,13 +138,13 @@ static int uart_setup( lua_State* L ) databits = luaL_checkinteger( L, 3 ); parity = luaL_checkinteger( L, 4 ); stopbits = luaL_checkinteger( L, 5 ); - if(id == CONSOLE_UART && lua_isnumber(L,6)){ + if(id == CONFIG_ESP_CONSOLE_UART_NUM && lua_isnumber(L,6)){ echo = lua_tointeger(L,6); if(echo!=0) - uart0_echo = true; + input_echo = true; else - uart0_echo = false; - } else if(id != CONSOLE_UART && lua_istable( L, 6 )) { + input_echo = false; + } else if(id != CONFIG_ESP_CONSOLE_UART_NUM && lua_istable( L, 6 )) { lua_getfield (L, 6, "tx"); pins.tx_pin = luaL_checkint(L, -1); lua_getfield (L, 6, "rx"); diff --git a/components/platform/CMakeLists.txt b/components/platform/CMakeLists.txt index f25d8043..f8c285d0 100644 --- a/components/platform/CMakeLists.txt +++ b/components/platform/CMakeLists.txt @@ -3,6 +3,6 @@ idf_component_register( "platform_flash.c" "platform_partition.c" "platform_rmt.c" "u8x8_nodemcu_hal.c" "ucg_nodemcu_hal.c" "vfs.c" "wdt.c" "ws2812.c" INCLUDE_DIRS "include" - REQUIRES "spiffs" "u8g2" "ucg" "driver_i2c" - PRIV_REQUIRES "bootloader_support" "driver_console" "lua" "esp32" + REQUIRES "spiffs" "u8g2" "ucg" "driver_i2c" "task" + PRIV_REQUIRES "bootloader_support" "lua" "esp32" ) diff --git a/components/platform/Kconfig b/components/platform/Kconfig index 981f33c4..1c174384 100644 --- a/components/platform/Kconfig +++ b/components/platform/Kconfig @@ -1,66 +1,5 @@ menu "NodeMCU platform config" - choice NODEMCU_CONSOLE_BIT_RATE - prompt "UART console default bit rate" - default NODEMCU_CONSOLE_BIT_RATE_115200 - help - Configure the default bit rate for the UART console. - - The resulting UART setting will be xxx-8N1, where xxx represents - the chosen bit rate. - config NODEMCU_CONSOLE_BIT_RATE_300 - bool "300" - config NODEMCU_CONSOLE_BIT_RATE_600 - bool "600" - config NODEMCU_CONSOLE_BIT_RATE_1200 - bool "1200" - config NODEMCU_CONSOLE_BIT_RATE_2400 - bool "2400" - config NODEMCU_CONSOLE_BIT_RATE_4800 - bool "4800" - config NODEMCU_CONSOLE_BIT_RATE_9600 - bool "9600" - config NODEMCU_CONSOLE_BIT_RATE_19200 - bool "19200" - config NODEMCU_CONSOLE_BIT_RATE_38400 - bool "38400" - config NODEMCU_CONSOLE_BIT_RATE_57600 - bool "57600" - config NODEMCU_CONSOLE_BIT_RATE_74880 - bool "74880" - config NODEMCU_CONSOLE_BIT_RATE_115200 - bool "115200" - config NODEMCU_CONSOLE_BIT_RATE_230400 - bool "230400" - config NODEMCU_CONSOLE_BIT_RATE_460800 - bool "460800" - config NODEMCU_CONSOLE_BIT_RATE_921600 - bool "921600" - config NODEMCU_CONSOLE_BIT_RATE_1843200 - bool "1843200" - config NODEMCU_CONSOLE_BIT_RATE_3683400 - bool "3683400" - endchoice - - config NODEMCU_CONSOLE_BIT_RATE - int - default 300 if NODEMCU_CONSOLE_BIT_RATE_300 - default 600 if NODEMCU_CONSOLE_BIT_RATE_600 - default 1200 if NODEMCU_CONSOLE_BIT_RATE_1200 - default 2400 if NODEMCU_CONSOLE_BIT_RATE_2400 - default 4800 if NODEMCU_CONSOLE_BIT_RATE_4800 - default 9600 if NODEMCU_CONSOLE_BIT_RATE_9600 - default 19200 if NODEMCU_CONSOLE_BIT_RATE_19200 - default 38400 if NODEMCU_CONSOLE_BIT_RATE_38400 - default 57600 if NODEMCU_CONSOLE_BIT_RATE_57600 - default 74880 if NODEMCU_CONSOLE_BIT_RATE_74880 - default 115200 if NODEMCU_CONSOLE_BIT_RATE_115200 - default 230400 if NODEMCU_CONSOLE_BIT_RATE_230400 - default 460800 if NODEMCU_CONSOLE_BIT_RATE_460800 - default 921600 if NODEMCU_CONSOLE_BIT_RATE_921600 - default 1843200 if NODEMCU_CONSOLE_BIT_RATE_1843200 - default 3683400 if NODEMCU_CONSOLE_BIT_RATE_3683400 - config NODEMCU_NODE_DEBUG bool "Enable NODE_DBG() output" default "n" diff --git a/components/platform/include/platform.h b/components/platform/include/platform.h index e1513c8c..9a1cd71e 100644 --- a/components/platform/include/platform.h +++ b/components/platform/include/platform.h @@ -101,12 +101,7 @@ typedef struct { int16_t end_char; } uart_status_t; -typedef struct { - unsigned id; - int type; - size_t size; - char* data; -} uart_event_post_t; +extern uart_status_t uart_status[NUM_UART]; // 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 diff --git a/components/platform/platform.c b/components/platform/platform.c index 76404118..d0178ea9 100644 --- a/components/platform/platform.c +++ b/components/platform/platform.c @@ -1,5 +1,4 @@ #include "platform.h" -#include "driver/console.h" #include "driver/sigmadelta.h" #include "driver/adc.h" #include "driver/uart.h" @@ -10,6 +9,8 @@ #include "lua.h" #include "rom/uart.h" #include "esp_log.h" +#include "task/task.h" +#include "linput.h" int platform_init (void) { @@ -33,42 +34,52 @@ int platform_gpio_output_exists( unsigned gpio ) { return GPIO_IS_VALID_OUTPUT_G #define PLATFORM_UART_EVENT_RX (UART_EVENT_MAX + 3) #define PLATFORM_UART_EVENT_BREAK (UART_EVENT_MAX + 4) +typedef struct { + unsigned id; + int type; + size_t size; + char* data; +} uart_event_post_t; + static const char *UART_TAG = "uart"; uart_status_t uart_status[NUM_UART]; - +task_handle_t uart_event_task_id = 0; SemaphoreHandle_t sem = NULL; extern bool uart_on_data_cb(unsigned id, const char *buf, size_t len); extern bool uart_on_error_cb(unsigned id, const char *buf, size_t len); -task_handle_t uart_event_task_id = 0; void uart_event_task( task_param_t param, task_prio_t prio ) { - uint16_t need_len; - int16_t end_char; - char ch; - unsigned id; - uart_status_t *us; uart_event_post_t *post = (uart_event_post_t *)param; - id = post->id; - us = & uart_status[id]; + unsigned id = post->id; + uart_status_t *us = &uart_status[id]; xSemaphoreGive(sem); if(post->type == PLATFORM_UART_EVENT_DATA) { - for(size_t p = 0; p < post->size; p++) { - ch = post->data[p]; - us->line_buffer[us->line_position] = ch; - us->line_position++; + size_t i = 0; + while (i < post->size) + { + if (id == CONFIG_ESP_CONSOLE_UART_NUM && run_input) { + unsigned used = feed_lua_input(post->data + i, post->size - i); + i += used; + } + else { + char ch = post->data[i]; + us->line_buffer[us->line_position] = ch; + us->line_position++; - need_len = us->need_len; - end_char = us->end_char; - size_t max_wanted = - (end_char >= 0 && need_len == 0) ? LUA_MAXINPUT : need_len; - bool at_end = (us->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, us->line_buffer, us->line_position); - us->line_position = 0; + uint16_t need_len = us->need_len; + int16_t end_char = us->end_char; + size_t max_wanted = + (end_char >= 0 && need_len == 0) ? LUA_MAXINPUT : need_len; + bool at_end = (us->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, us->line_buffer, us->line_position); + us->line_position = 0; + } + ++i; } } free(post->data); @@ -177,88 +188,53 @@ static void task_uart( void *pvParameters ){ // pins must not be null for non-console uart uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int parity, int stopbits, uart_pins_t* pins ) { - if (id == CONSOLE_UART) + int flow_control = UART_HW_FLOWCTRL_DISABLE; + if(pins->flow_control & PLATFORM_UART_FLOW_CTS) flow_control |= UART_HW_FLOWCTRL_CTS; + if(pins->flow_control & PLATFORM_UART_FLOW_RTS) flow_control |= UART_HW_FLOWCTRL_RTS; + + uart_config_t cfg = { + .baud_rate = baud, + .flow_ctrl = flow_control, + .rx_flow_ctrl_thresh = UART_FIFO_LEN - 16, + }; + + switch (databits) { - ConsoleSetup_t cfg; - cfg.bit_rate = baud; - switch (databits) - { - case 5: cfg.data_bits = CONSOLE_NUM_BITS_5; break; - case 6: cfg.data_bits = CONSOLE_NUM_BITS_6; break; - case 7: cfg.data_bits = CONSOLE_NUM_BITS_7; break; - case 8: // fall-through - default: cfg.data_bits = CONSOLE_NUM_BITS_8; break; - } - switch (parity) - { - case PLATFORM_UART_PARITY_EVEN: cfg.parity = CONSOLE_PARITY_EVEN; break; - case PLATFORM_UART_PARITY_ODD: cfg.parity = CONSOLE_PARITY_ODD; break; - default: // fall-through - case PLATFORM_UART_PARITY_NONE: cfg.parity = CONSOLE_PARITY_NONE; break; - } - switch (stopbits) - { - default: // fall-through - case PLATFORM_UART_STOPBITS_1: - cfg.stop_bits = CONSOLE_STOP_BITS_1; break; - case PLATFORM_UART_STOPBITS_1_5: - cfg.stop_bits = CONSOLE_STOP_BITS_1_5; break; - case PLATFORM_UART_STOPBITS_2: - cfg.stop_bits = CONSOLE_STOP_BITS_2; break; - } - cfg.auto_baud = false; - console_setup (&cfg); - return baud; + case 5: cfg.data_bits = UART_DATA_5_BITS; break; + case 6: cfg.data_bits = UART_DATA_6_BITS; break; + case 7: cfg.data_bits = UART_DATA_7_BITS; break; + case 8: // fall-through + default: cfg.data_bits = UART_DATA_8_BITS; break; } - else + switch (parity) { - int flow_control = UART_HW_FLOWCTRL_DISABLE; - if(pins->flow_control & PLATFORM_UART_FLOW_CTS) flow_control |= UART_HW_FLOWCTRL_CTS; - if(pins->flow_control & PLATFORM_UART_FLOW_RTS) flow_control |= UART_HW_FLOWCTRL_RTS; - - uart_config_t cfg = { - .baud_rate = baud, - .flow_ctrl = flow_control, - .rx_flow_ctrl_thresh = UART_FIFO_LEN - 16, - }; - - switch (databits) - { - case 5: cfg.data_bits = UART_DATA_5_BITS; break; - case 6: cfg.data_bits = UART_DATA_6_BITS; break; - case 7: cfg.data_bits = UART_DATA_7_BITS; break; - case 8: // fall-through - default: cfg.data_bits = UART_DATA_8_BITS; break; - } - switch (parity) - { - case PLATFORM_UART_PARITY_EVEN: cfg.parity = UART_PARITY_EVEN; break; - case PLATFORM_UART_PARITY_ODD: cfg.parity = UART_PARITY_ODD; break; - default: // fall-through - case PLATFORM_UART_PARITY_NONE: cfg.parity = UART_PARITY_DISABLE; break; - } - switch (stopbits) - { - default: // fall-through - case PLATFORM_UART_STOPBITS_1: - cfg.stop_bits = UART_STOP_BITS_1; break; - case PLATFORM_UART_STOPBITS_1_5: - cfg.stop_bits = UART_STOP_BITS_1_5; break; - case PLATFORM_UART_STOPBITS_2: - cfg.stop_bits = UART_STOP_BITS_2; break; - } - uart_param_config(id, &cfg); + case PLATFORM_UART_PARITY_EVEN: cfg.parity = UART_PARITY_EVEN; break; + case PLATFORM_UART_PARITY_ODD: cfg.parity = UART_PARITY_ODD; break; + default: // fall-through + case PLATFORM_UART_PARITY_NONE: cfg.parity = UART_PARITY_DISABLE; break; + } + switch (stopbits) + { + default: // fall-through + case PLATFORM_UART_STOPBITS_1: + cfg.stop_bits = UART_STOP_BITS_1; break; + case PLATFORM_UART_STOPBITS_1_5: + cfg.stop_bits = UART_STOP_BITS_1_5; break; + case PLATFORM_UART_STOPBITS_2: + cfg.stop_bits = UART_STOP_BITS_2; break; + } + uart_param_config(id, &cfg); + + if (pins != NULL) { uart_set_pin(id, pins->tx_pin, pins->rx_pin, pins->rts_pin, pins->cts_pin); uart_set_line_inverse(id, (pins->tx_inverse? UART_TXD_INV_M : 0) | (pins->rx_inverse? UART_RXD_INV_M : 0) | (pins->rts_inverse? UART_RTS_INV_M : 0) | (pins->cts_inverse? UART_CTS_INV_M : 0) ); - - if(uart_event_task_id == 0) uart_event_task_id = task_get_id( uart_event_task ); - - return baud; } + + return baud; } void platform_uart_setmode(unsigned id, unsigned mode) @@ -285,7 +261,7 @@ void platform_uart_setmode(unsigned id, unsigned mode) void platform_uart_send_multi( unsigned id, const char *data, size_t len ) { size_t i; - if (id == CONSOLE_UART) { + if (id == CONFIG_ESP_CONSOLE_UART_NUM) { for( i = 0; i < len; i ++ ) { putchar (data[ i ]); } @@ -296,7 +272,7 @@ void platform_uart_send_multi( unsigned id, const char *data, size_t len ) void platform_uart_send( unsigned id, uint8_t data ) { - if (id == CONSOLE_UART) + if (id == CONFIG_ESP_CONSOLE_UART_NUM) putchar (data); else uart_write_bytes(id, (const char *)&data, 1); @@ -304,7 +280,7 @@ void platform_uart_send( unsigned id, uint8_t data ) void platform_uart_flush( unsigned id ) { - if (id == CONSOLE_UART) + if (id == CONFIG_ESP_CONSOLE_UART_NUM) fflush (stdout); else uart_tx_flush(id); @@ -313,38 +289,38 @@ void platform_uart_flush( unsigned id ) int platform_uart_start( unsigned id ) { - if (id == CONSOLE_UART) - return 0; - else { - uart_status_t *us = & uart_status[id]; - - esp_err_t ret = uart_driver_install(id, UART_BUFFER_SIZE, UART_BUFFER_SIZE, 3, & us->queue, 0); - if(ret != ESP_OK) { - return -1; - } - us->line_buffer = malloc(LUA_MAXINPUT); - us->line_position = 0; - if(us->line_buffer == NULL) { - uart_driver_delete(id); - return -1; - } + if(uart_event_task_id == 0) + uart_event_task_id = task_get_id( uart_event_task ); - char pcName[6]; - snprintf( pcName, 6, "uart%d", id ); - pcName[5] = '\0'; - if(xTaskCreate(task_uart, pcName, 2048, (void*)id, ESP_TASK_MAIN_PRIO + 1, & us->taskHandle) != pdPASS) { - uart_driver_delete(id); - free(us->line_buffer); - us->line_buffer = NULL; - return -1; - } - return 0; + uart_status_t *us = & uart_status[id]; + + esp_err_t ret = uart_driver_install(id, UART_BUFFER_SIZE, UART_BUFFER_SIZE, 3, & us->queue, 0); + if(ret != ESP_OK) { + return -1; } + us->line_buffer = malloc(LUA_MAXINPUT); + us->line_position = 0; + if(us->line_buffer == NULL) { + uart_driver_delete(id); + return -1; + } + + char pcName[6]; + snprintf( pcName, 6, "uart%d", id ); + pcName[5] = '\0'; + if(xTaskCreate(task_uart, pcName, 2048, (void*)id, ESP_TASK_MAIN_PRIO + 1, & us->taskHandle) != pdPASS) { + uart_driver_delete(id); + free(us->line_buffer); + us->line_buffer = NULL; + return -1; + } + + return 0; } void platform_uart_stop( unsigned id ) { - if (id == CONSOLE_UART) + if (id == CONFIG_ESP_CONSOLE_UART_NUM) ; else { uart_status_t *us = & uart_status[id];