1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

uart: fix wdt input overrun (#4536)

* uart: fix wdt on uart input overrun, expose in HardwareSerial::hasOverrun()
This commit is contained in:
david gauchard 2018-03-21 13:28:34 +01:00 committed by GitHub
parent 6d3f0b4023
commit 6580bf3477
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 0 deletions

View File

@ -137,6 +137,11 @@ public:
bool isRxEnabled(void); bool isRxEnabled(void);
int baudRate(void); int baudRate(void);
bool hasOverrun(void)
{
return uart_has_overrun(_uart);
}
protected: protected:
int _uart_nr; int _uart_nr;
uart_t* _uart = nullptr; uart_t* _uart = nullptr;

View File

@ -59,6 +59,7 @@ struct uart_ {
int baud_rate; int baud_rate;
bool rx_enabled; bool rx_enabled;
bool tx_enabled; bool tx_enabled;
bool overrun;
uint8_t rx_pin; uint8_t rx_pin;
uint8_t tx_pin; uint8_t tx_pin;
struct uart_rx_buffer_ * rx_buffer; struct uart_rx_buffer_ * rx_buffer;
@ -102,13 +103,31 @@ inline size_t uart_rx_fifo_available(uart_t* uart) {
return (USS(uart->uart_nr) >> USRXC) & 0x7F; 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 // Copy all the rx fifo bytes that fit into the rx buffer
inline void uart_rx_copy_fifo_to_buffer(uart_t* uart) { inline void uart_rx_copy_fifo_to_buffer(uart_t* uart) {
while(uart_rx_fifo_available(uart)){ while(uart_rx_fifo_available(uart)){
size_t nextPos = (uart->rx_buffer->wpos + 1) % uart->rx_buffer->size; size_t nextPos = (uart->rx_buffer->wpos + 1) % uart->rx_buffer->size;
if(nextPos == uart->rx_buffer->rpos) { if(nextPos == uart->rx_buffer->rpos) {
if (!uart->overrun) {
uart->overrun = true;
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 // Stop copying if rx buffer is full
USF(uart->uart_nr);
break; 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); uint8_t data = USF(uart->uart_nr);
uart->rx_buffer->buffer[uart->rx_buffer->wpos] = data; uart->rx_buffer->buffer[uart->rx_buffer->wpos] = data;
@ -281,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->uart_nr = uart_nr;
uart->overrun = false;
switch(uart->uart_nr) { switch(uart->uart_nr) {
case UART0: case UART0:
@ -504,6 +524,15 @@ bool uart_rx_enabled(uart_t* uart)
return uart->rx_enabled; 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) static void uart_ignore_char(char c)
{ {

View File

@ -136,6 +136,8 @@ size_t uart_tx_free(uart_t* uart);
void uart_wait_tx_empty(uart_t* uart); void uart_wait_tx_empty(uart_t* uart);
void uart_flush(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); void uart_set_debug(int uart_nr);
int uart_get_debug(); int uart_get_debug();