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.
This commit is contained in:
parent
b52ed2d2a5
commit
46713a5275
4 changed files with 11 additions and 5 deletions
|
@ -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_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_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));
|
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_rxfifo_rst(&(uart_context[uart_num].hal));
|
||||||
uart_hal_txfifo_rst(&(uart_context[uart_num].hal));
|
uart_hal_txfifo_rst(&(uart_context[uart_num].hal));
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
|
@ -111,7 +111,8 @@ void IRAM_ATTR esp_restart_noos(void)
|
||||||
|
|
||||||
// Reset timer/spi/uart
|
// Reset timer/spi/uart
|
||||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,
|
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);
|
DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0);
|
||||||
|
|
||||||
// Set CPU back to XTAL source, no PLL, same as hard reset
|
// Set CPU back to XTAL source, no PLL, same as hard reset
|
||||||
|
|
|
@ -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
|
* @brief Reset the UART txfifo
|
||||||
|
* @note On ESP32, this function is reserved for UART1 and UART2.
|
||||||
*
|
*
|
||||||
* @param hal Context of the HAL layer
|
* @param hal Context of the HAL layer
|
||||||
*
|
*
|
||||||
|
|
|
@ -219,14 +219,20 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
|
||||||
/**
|
/**
|
||||||
* @brief Reset the UART hw txfifo.
|
* @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.
|
* @param hw Beginning address of the peripheral registers.
|
||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*/
|
*/
|
||||||
static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
|
static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->conf0.txfifo_rst = 1;
|
if (hw == &UART0) {
|
||||||
hw->conf0.txfifo_rst = 0;
|
hw->conf0.txfifo_rst = 1;
|
||||||
|
hw->conf0.txfifo_rst = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue