driver(uart): fix uart module reset issue

On ESP32, due to fifo reset issue, UART2 will work incorrectly if reset the fifo of UART1(TX fifo and RX fifo). The software can workaround the RX fifo reset issue,

        while the TX fifo reset issue can not. When UART2 is used and UART1 is used as the log output port, a software reset can reproduce this issue. So we should reset the UART memory

        before the software reset to solve this problem.
pull/5452/head
houwenxiang 2020-05-01 20:40:24 +08:00
rodzic b52ed2d2a5
commit 46713a5275
4 zmienionych plików z 11 dodań i 5 usunięć

Wyświetl plik

@ -632,8 +632,6 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
uart_hal_set_tx_idle_num(&(uart_context[uart_num].hal), UART_TX_IDLE_NUM_DEFAULT);
uart_hal_set_hw_flow_ctrl(&(uart_context[uart_num].hal), uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh);
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
// The module reset do not reset TX and RX memory.
// reset FIFO to avoid garbage data remained in the FIFO.
uart_hal_rxfifo_rst(&(uart_context[uart_num].hal));
uart_hal_txfifo_rst(&(uart_context[uart_num].hal));
return ESP_OK;

Wyświetl plik

@ -111,7 +111,8 @@ void IRAM_ATTR esp_restart_noos(void)
// Reset timer/spi/uart
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,
DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_UART_RST | DPORT_UART1_RST | DPORT_UART2_RST);
//UART TX FIFO cannot be reset correctly on ESP32, so reset the UART memory by DPORT here.
DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_UART_RST | DPORT_UART1_RST | DPORT_UART2_RST | DPORT_UART_MEM_RST);
DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0);
// Set CPU back to XTAL source, no PLL, same as hard reset

Wyświetl plik

@ -150,6 +150,7 @@ void uart_hal_write_txfifo(uart_hal_context_t *hal, const uint8_t *buf, uint32_t
/**
* @brief Reset the UART txfifo
* @note On ESP32, this function is reserved for UART1 and UART2.
*
* @param hal Context of the HAL layer
*

Wyświetl plik

@ -219,14 +219,20 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
/**
* @brief Reset the UART hw txfifo.
*
* Note: Due to hardware issue, reset UART1's txfifo will also reset UART2's txfifo.
* So reserve this function for UART1 and UART2. Please do DPORT reset for UART and its memory at chip startup
* to ensure the TX FIFO is reset correctly at the beginning.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None
*/
static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
{
hw->conf0.txfifo_rst = 1;
hw->conf0.txfifo_rst = 0;
if (hw == &UART0) {
hw->conf0.txfifo_rst = 1;
hw->conf0.txfifo_rst = 0;
}
}
/**