Browse Source

bugfix(uart): fix esp32 fifo_cnt bug

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.
xiongyu 5 years ago
parent
commit
cf3b2df4a4
2 changed files with 17 additions and 2 deletions
  1. 2 1
      components/driver/test/test_uart.c
  2. 15 1
      components/soc/esp32/include/hal/uart_ll.h

+ 2 - 1
components/driver/test/test_uart.c

@@ -292,7 +292,8 @@ TEST_CASE("uart tx with ringbuffer test", "[uart]")
         .data_bits = UART_DATA_8_BITS,
         .parity = UART_PARITY_DISABLE,
         .stop_bits = UART_STOP_BITS_1,
-        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
+        .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
+        .rx_flow_ctrl_thresh = 120,
         .source_clk = UART_SCLK_APB,
     };
     TEST_ESP_OK(uart_param_config(uart_num, &uart_config));

+ 15 - 1
components/soc/esp32/include/hal/uart_ll.h

@@ -234,7 +234,21 @@ static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
  */
 static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
 {
-    return hw->status.rxfifo_cnt;
+    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 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;
+    } else if (rx_status.wr_addr < rx_status.rd_addr) {
+        len = (rx_status.wr_addr + 128) - rx_status.rd_addr;
+    } else {
+        len = fifo_cnt > 0 ? 128 : 0;
+    }
+
+    return len;
 }
 
 /**