Merge branch 'bugfix/uart_fifo_ovf_workaround' into 'master'
driver(uart): fix uart rx fifo length error after overflow. See merge request !1735
This commit is contained in:
commit
f482e9e54c
3 changed files with 32 additions and 13 deletions
|
@ -271,8 +271,11 @@ esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flo
|
||||||
static esp_err_t uart_reset_rx_fifo(uart_port_t uart_num)
|
static esp_err_t uart_reset_rx_fifo(uart_port_t uart_num)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||||
// Read all data from the FIFO
|
//Due to hardware issue, we can not use fifo_rst to reset uart fifo.
|
||||||
while (UART[uart_num]->status.rxfifo_cnt) {
|
//See description about UART_TXFIFO_RST and UART_RXFIFO_RST in <<esp32_technical_reference_manual>> v2.6 or later.
|
||||||
|
|
||||||
|
// we read the data out and make `fifo_len == 0 && rd_addr == wr_addr`.
|
||||||
|
while(UART[uart_num]->status.rxfifo_cnt != 0 || (UART[uart_num]->mem_rx_status.wr_addr != UART[uart_num]->mem_rx_status.rd_addr)) {
|
||||||
READ_PERI_REG(UART_FIFO_REG(uart_num));
|
READ_PERI_REG(UART_FIFO_REG(uart_num));
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
@ -542,7 +545,6 @@ static void uart_rx_intr_handler_default(void *param)
|
||||||
int rx_fifo_len = 0;
|
int rx_fifo_len = 0;
|
||||||
uart_event_t uart_event;
|
uart_event_t uart_event;
|
||||||
portBASE_TYPE HPTaskAwoken = 0;
|
portBASE_TYPE HPTaskAwoken = 0;
|
||||||
|
|
||||||
while(uart_intr_status != 0x0) {
|
while(uart_intr_status != 0x0) {
|
||||||
buf_idx = 0;
|
buf_idx = 0;
|
||||||
uart_event.type = UART_EVENT_MAX;
|
uart_event.type = UART_EVENT_MAX;
|
||||||
|
@ -691,13 +693,11 @@ static void uart_rx_intr_handler_default(void *param)
|
||||||
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
||||||
uart_event.type = UART_BUFFER_FULL;
|
uart_event.type = UART_BUFFER_FULL;
|
||||||
}
|
}
|
||||||
} else if(uart_intr_status & UART_RXFIFO_OVF_INT_ST_M) {
|
|
||||||
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
|
||||||
// Read all data from the FIFO
|
|
||||||
rx_fifo_len = uart_reg->status.rxfifo_cnt;
|
|
||||||
for (int i = 0; i < rx_fifo_len; i++) {
|
|
||||||
READ_PERI_REG(UART_FIFO_REG(uart_num));
|
|
||||||
}
|
}
|
||||||
|
// When fifo overflows, we reset the fifo.
|
||||||
|
else if(uart_intr_status & UART_RXFIFO_OVF_INT_ST_M) {
|
||||||
|
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
||||||
|
uart_reset_rx_fifo(uart_num);
|
||||||
uart_reg->int_clr.rxfifo_ovf = 1;
|
uart_reg->int_clr.rxfifo_ovf = 1;
|
||||||
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
||||||
uart_event.type = UART_FIFO_OVF;
|
uart_event.type = UART_FIFO_OVF;
|
||||||
|
|
|
@ -1105,11 +1105,24 @@
|
||||||
|
|
||||||
#define UART_MEM_RX_STATUS_REG(i) (REG_UART_BASE(i) + 0x60)
|
#define UART_MEM_RX_STATUS_REG(i) (REG_UART_BASE(i) + 0x60)
|
||||||
/* UART_MEM_RX_STATUS : RO ;bitpos:[23:0] ;default: 24'h0 ; */
|
/* UART_MEM_RX_STATUS : RO ;bitpos:[23:0] ;default: 24'h0 ; */
|
||||||
/*description: */
|
/*description: This register stores the current uart rx mem read address
|
||||||
|
and rx mem write address */
|
||||||
#define UART_MEM_RX_STATUS 0x00FFFFFF
|
#define UART_MEM_RX_STATUS 0x00FFFFFF
|
||||||
#define UART_MEM_RX_STATUS_M ((UART_MEM_RX_STATUS_V)<<(UART_MEM_RX_STATUS_S))
|
#define UART_MEM_RX_STATUS_M ((UART_MEM_RX_STATUS_V)<<(UART_MEM_RX_STATUS_S))
|
||||||
#define UART_MEM_RX_STATUS_V 0xFFFFFF
|
#define UART_MEM_RX_STATUS_V 0xFFFFFF
|
||||||
#define UART_MEM_RX_STATUS_S 0
|
#define UART_MEM_RX_STATUS_S 0
|
||||||
|
/* UART_MEM_RX_RD_ADDR : RO ;bitpos:[12:2] ;default: 11'h0 ; */
|
||||||
|
/*description: This register stores the rx mem read address */
|
||||||
|
#define UART_MEM_RX_RD_ADDR 0x000007FF
|
||||||
|
#define UART_MEM_RX_RD_ADDR_M ((UART_MEM_RX_RD_ADDR_V)<<(UART_MEM_RX_RD_ADDR_S))
|
||||||
|
#define UART_MEM_RX_RD_ADDR_V (0x7FF)
|
||||||
|
#define UART_MEM_RX_RD_ADDR_S (2)
|
||||||
|
/* UART_MEM_RX_WR_ADDR : RO ;bitpos:[23:13] ;default: 11'h0 ; */
|
||||||
|
/*description: This register stores the rx mem write address */
|
||||||
|
#define UART_MEM_RX_WR_ADDR 0x000007FF
|
||||||
|
#define UART_MEM_RX_WR_ADDR_M ((UART_MEM_RX_WR_ADDR_V)<<(UART_MEM_RX_WR_ADDR_S))
|
||||||
|
#define UART_MEM_RX_WR_ADDR_V (0x7FF)
|
||||||
|
#define UART_MEM_RX_WR_ADDR_S (13)
|
||||||
|
|
||||||
#define UART_MEM_CNT_STATUS_REG(i) (REG_UART_BASE(i) + 0x64)
|
#define UART_MEM_CNT_STATUS_REG(i) (REG_UART_BASE(i) + 0x64)
|
||||||
/* UART_TX_MEM_CNT : RO ;bitpos:[5:3] ;default: 3'b0 ; */
|
/* UART_TX_MEM_CNT : RO ;bitpos:[5:3] ;default: 3'b0 ; */
|
||||||
|
|
|
@ -335,6 +335,12 @@ typedef volatile struct {
|
||||||
uint32_t status: 24;
|
uint32_t status: 24;
|
||||||
uint32_t reserved24: 8;
|
uint32_t reserved24: 8;
|
||||||
};
|
};
|
||||||
|
struct {
|
||||||
|
uint32_t reserved0: 2;
|
||||||
|
uint32_t rd_addr: 11; /*This register stores the rx mem read address.*/
|
||||||
|
uint32_t wr_addr: 11; /*This register stores the rx mem write address.*/
|
||||||
|
uint32_t reserved: 8;
|
||||||
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} mem_rx_status;
|
} mem_rx_status;
|
||||||
union {
|
union {
|
||||||
|
|
Loading…
Reference in a new issue