Discard old console driver.

The IDF provides all we need these days, and the old driver was just
needlessly conflicting with the IDF settings and setup.

This also simplifies our uart input path as we no longer need to
duplicate the raw byte handling for when "run_input" is false.
This commit is contained in:
Johny Mattsson 2021-08-23 23:00:54 +10:00
parent 3af14a367b
commit fbef7feae1
13 changed files with 179 additions and 601 deletions

View File

@ -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 ();

View File

@ -1,5 +0,0 @@
idf_component_register(
SRCS "console.c"
INCLUDE_DIRS "include"
REQUIRES "task" "esp32"
)

View File

@ -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 <jmattsson@dius.com.au>
*/
#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 <unistd.h>
#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));
}

View File

@ -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 <jmattsson@dius.com.au>
*/
#include "esp_rom_uart.h"
#include "task/task.h"
#include <stdint.h>
#include <stdbool.h>
#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);

View File

@ -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"
)

View File

@ -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
}

View File

@ -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 <stdbool.h>
#include <stddef.h>
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 */

View File

@ -7,7 +7,6 @@
#include <stdlib.h>
#include <string.h>
#include "user_version.h"
#include "driver/console.h"
#include "linput.h"
#define lua_c

View File

@ -3,15 +3,13 @@
#include "module.h"
#include "lauxlib.h"
#include "platform.h"
#include "driver/console.h"
#include "linput.h"
#include <stdint.h>
#include <string.h>
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");

View File

@ -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"
)

View File

@ -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"

View File

@ -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

View File

@ -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];