mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/fix_uart_module_enable_issue_v4.2' into 'release/v4.2'
driver(uart): fix uart module reset issue (release V4.2) See merge request espressif/esp-idf!11969
This commit is contained in:
commit
7dbd5e1855
@ -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;
|
||||
@ -961,7 +959,7 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param)
|
||||
// then postpone interrupt processing for next interrupt
|
||||
uart_event.type = UART_EVENT_MAX;
|
||||
} else {
|
||||
// Workaround for RS485: If the RS485 half duplex mode is active
|
||||
// Workaround for RS485: If the RS485 half duplex mode is active
|
||||
// and transmitter is in idle state then reset received buffer and reset RTS pin
|
||||
// skip this behavior for other UART modes
|
||||
UART_ENTER_CRITICAL_ISR(&(uart_context[uart_num].spinlock));
|
||||
|
@ -121,7 +121,9 @@ 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_SPI2_RST | DPORT_SPI3_RST | DPORT_SPI_DMA_RST | DPORT_UART_RST | DPORT_UART1_RST | DPORT_UART2_RST);
|
||||
DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_SPI2_RST | DPORT_SPI3_RST | DPORT_SPI_DMA_RST |
|
||||
//UART TX FIFO cannot be reset correctly on ESP32, so reset the UART memory by DPORT here.
|
||||
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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,8 +247,8 @@ static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
uint32_t fifo_cnt = hw->status.rxfifo_cnt;
|
||||
typeof(hw->mem_rx_status) rx_status = hw->mem_rx_status;
|
||||
uint32_t len = 0;
|
||||
|
||||
// When using DPort to read fifo, fifo_cnt is not credible, we need to calculate the real cnt based on the fifo read and write pointer.
|
||||
|
||||
// When using DPort to read fifo, fifo_cnt is not credible, we need to calculate the real cnt based on the fifo read and write pointer.
|
||||
// When using AHB to read FIFO, we can use fifo_cnt to indicate the data length in fifo.
|
||||
if (rx_status.wr_addr > rx_status.rd_addr) {
|
||||
len = rx_status.wr_addr - rx_status.rd_addr;
|
||||
@ -277,12 +283,12 @@ static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit)
|
||||
{
|
||||
//workaround for hardware issue, when UART stop bit set as 2-bit mode.
|
||||
//workaround for hardware issue, when UART stop bit set as 2-bit mode.
|
||||
if(stop_bit == UART_STOP_BITS_2) {
|
||||
hw->rs485_conf.dl1_en = 1;
|
||||
hw->conf0.stop_bit_num = 0x1;
|
||||
} else {
|
||||
hw->rs485_conf.dl1_en = 0;
|
||||
hw->rs485_conf.dl1_en = 0;
|
||||
hw->conf0.stop_bit_num = stop_bit;
|
||||
}
|
||||
}
|
||||
@ -297,7 +303,7 @@ static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_b
|
||||
*/
|
||||
static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit)
|
||||
{
|
||||
//workaround for hardware issue, when UART stop bit set as 2-bit mode.
|
||||
//workaround for hardware issue, when UART stop bit set as 2-bit mode.
|
||||
if(hw->rs485_conf.dl1_en == 1 && hw->conf0.stop_bit_num == 0x1) {
|
||||
*stop_bit = UART_STOP_BITS_2;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user