From 508fb79a26a9b62e9b3007b98169a2bc2005594d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 15 Oct 2018 20:08:16 +0800 Subject: [PATCH] uart: fix uart_tx_wait_idle to wait for fifo empty In some cases, when data was just written into UART FIFO, transmitter state could be still zero while the FIFO did contain some data. This resulted in uart_tx_wait_idle occasionally returning before all the data was sent out. Fix by checking both UART transmitter state and TX FIFO count. --- components/esp32/include/rom/uart.h | 8 +++++--- components/esp32/sleep_modes.c | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/components/esp32/include/rom/uart.h b/components/esp32/include/rom/uart.h index 0a3e1aeb64..8722445734 100644 --- a/components/esp32/include/rom/uart.h +++ b/components/esp32/include/rom/uart.h @@ -267,9 +267,11 @@ void uart_tx_flush(uint8_t uart_no); * here for compatibility. */ static inline void IRAM_ATTR uart_tx_wait_idle(uint8_t uart_no) { - while(REG_GET_FIELD(UART_STATUS_REG(uart_no), UART_ST_UTX_OUT)) { - ; - } + uint32_t status; + do { + status = READ_PERI_REG(UART_STATUS_REG(uart_no)); + /* either tx count or state is non-zero */ + } while ((status & (UART_ST_UTX_OUT_M | UART_TXFIFO_CNT_M)) != 0); } /** diff --git a/components/esp32/sleep_modes.c b/components/esp32/sleep_modes.c index da4a5f11a5..f3bd071f3f 100644 --- a/components/esp32/sleep_modes.c +++ b/components/esp32/sleep_modes.c @@ -159,7 +159,9 @@ static void IRAM_ATTR suspend_uarts() { for (int i = 0; i < 3; ++i) { REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); - uart_tx_wait_idle(i); + while (REG_GET_FIELD(UART_STATUS_REG(i), UART_ST_UTX_OUT) != 0) { + ; + } } }