From 546c8b7fdd20c56cdced7e1fb648f2c9e8d9ceab Mon Sep 17 00:00:00 2001 From: david gauchard Date: Tue, 20 Mar 2018 00:40:50 +0100 Subject: [PATCH 1/3] uart: fix wdt on uart input overrun --- cores/esp8266/uart.c | 21 ++++++++++++++++++++- cores/esp8266/uart.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index 328acca7df..9c2f58d507 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -45,6 +45,7 @@ #include "esp8266_peri.h" #include "user_interface.h" +uint8_t uart_overrun = 0; static int s_uart_debug_nr = UART0; struct uart_rx_buffer_ { @@ -102,13 +103,32 @@ inline size_t uart_rx_fifo_available(uart_t* uart) { return (USS(uart->uart_nr) >> USRXC) & 0x7F; } +char overrun_str [] ICACHE_RODATA_ATTR STORE_ATTR = "uart input full!\r\n"; + // Copy all the rx fifo bytes that fit into the rx buffer inline void uart_rx_copy_fifo_to_buffer(uart_t* uart) { while(uart_rx_fifo_available(uart)){ size_t nextPos = (uart->rx_buffer->wpos + 1) % uart->rx_buffer->size; if(nextPos == uart->rx_buffer->rpos) { + + if (uart_overrun == 0) + { + uart_overrun = 1; + os_printf_plus(overrun_str); + } + + // a choice has to be made here, + // do we discard newest or oldest data? +#if 0 + // discard newest data // Stop copying if rx buffer is full + USF(uart->uart_nr); break; +#else + // discard oldest data + if (++uart->rx_buffer->rpos == uart->rx_buffer->size) + uart->rx_buffer->rpos = 0; +#endif } uint8_t data = USF(uart->uart_nr); uart->rx_buffer->buffer[uart->rx_buffer->wpos] = data; @@ -195,7 +215,6 @@ void uart_stop_isr(uart_t* uart) ETS_UART_INTR_ATTACH(NULL, NULL); } - void uart_write_char(uart_t* uart, char c) { if(uart == NULL || !uart->tx_enabled) { diff --git a/cores/esp8266/uart.h b/cores/esp8266/uart.h index b79745adf5..4728026707 100644 --- a/cores/esp8266/uart.h +++ b/cores/esp8266/uart.h @@ -112,6 +112,7 @@ extern "C" { struct uart_; typedef struct uart_ uart_t; +extern uint8_t uart_overrun; // 1=>detected, can be set to 2 once action taken, or 0 to redetect uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx_size); void uart_uninit(uart_t* uart); From 54cc4634f5997fe2e6c26e13d285d75f86d3dd02 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Tue, 20 Mar 2018 14:53:12 +0100 Subject: [PATCH 2/3] uart: better make overrun an api than a global --- cores/esp8266/uart.c | 18 ++++++++++++++---- cores/esp8266/uart.h | 3 ++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index 9c2f58d507..cad8e77a79 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -45,7 +45,6 @@ #include "esp8266_peri.h" #include "user_interface.h" -uint8_t uart_overrun = 0; static int s_uart_debug_nr = UART0; struct uart_rx_buffer_ { @@ -60,6 +59,7 @@ struct uart_ { int baud_rate; bool rx_enabled; bool tx_enabled; + bool overrun; uint8_t rx_pin; uint8_t tx_pin; struct uart_rx_buffer_ * rx_buffer; @@ -111,9 +111,8 @@ inline void uart_rx_copy_fifo_to_buffer(uart_t* uart) { size_t nextPos = (uart->rx_buffer->wpos + 1) % uart->rx_buffer->size; if(nextPos == uart->rx_buffer->rpos) { - if (uart_overrun == 0) - { - uart_overrun = 1; + if (!uart->overrun) { + uart->overrun = true; os_printf_plus(overrun_str); } @@ -215,6 +214,7 @@ void uart_stop_isr(uart_t* uart) ETS_UART_INTR_ATTACH(NULL, NULL); } + void uart_write_char(uart_t* uart, char c) { if(uart == NULL || !uart->tx_enabled) { @@ -300,6 +300,7 @@ uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, s } uart->uart_nr = uart_nr; + uart->overrun = false; switch(uart->uart_nr) { case UART0: @@ -523,6 +524,15 @@ bool uart_rx_enabled(uart_t* uart) return uart->rx_enabled; } +bool uart_has_overrun (uart_t* uart) +{ + if (uart == NULL || !uart->overrun) { + return false; + } + // clear flag + uart->overrun = false; + return true; +} static void uart_ignore_char(char c) { diff --git a/cores/esp8266/uart.h b/cores/esp8266/uart.h index 4728026707..c3aa0426d0 100644 --- a/cores/esp8266/uart.h +++ b/cores/esp8266/uart.h @@ -112,7 +112,6 @@ extern "C" { struct uart_; typedef struct uart_ uart_t; -extern uint8_t uart_overrun; // 1=>detected, can be set to 2 once action taken, or 0 to redetect uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx_size); void uart_uninit(uart_t* uart); @@ -137,6 +136,8 @@ size_t uart_tx_free(uart_t* uart); void uart_wait_tx_empty(uart_t* uart); void uart_flush(uart_t* uart); +bool uart_has_overrun (uart_t* uart); // returns then clear overrun flag + void uart_set_debug(int uart_nr); int uart_get_debug(); From 9ef14db7249f590892e4aaac0a733af868073337 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 21 Mar 2018 11:47:48 +0100 Subject: [PATCH 3/3] expose uart_has_overrun in HardwareSerial --- cores/esp8266/HardwareSerial.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cores/esp8266/HardwareSerial.h b/cores/esp8266/HardwareSerial.h index 4b384fee53..76c442ec74 100644 --- a/cores/esp8266/HardwareSerial.h +++ b/cores/esp8266/HardwareSerial.h @@ -137,6 +137,11 @@ class HardwareSerial: public Stream bool isRxEnabled(void); int baudRate(void); + bool hasOverrun(void) + { + return uart_has_overrun(_uart); + } + protected: int _uart_nr; uart_t* _uart = nullptr;