The problem is that sometimes when we read the FIFO, its hardware read index does not automatically increment as normal, even though it still automatically decrements its hardware FIFO counter. As a result, the next time we read the FIFO we get the same byte read last time, and this pattern continues with every byte being shifted. Here is an example sequence of what might be received in the UART and how it might be read:
Byte Received Counter (before read) Read Index (before read) Byte Read Counter (after read) Read Index (after read)
1 1 50 1 0 51
2 1 51 2 0 51
3 1 51 2 0 52
4 1 52 3 0 53
5 1 53 4 0 54
The read index shown in yellow is the one that failed to update after the read, causing perpetual FIFO delay/misalignment in bytes read. If the malfunction happens again the shift becomes 2, and so on.
Here is example code that could observe the malfunction above:
Code: Select all
while (1)
{
if (UART [1]->status.rxfifo_cnt)
{
printf ("Counter (before read): %d, Read Index (before read): %d\n", UART [1]->status.rxfifo_cnt, UART [1]->mem_rx_status.rd_addr);
printf ("Byte Read: %d\n", READ_PERI_REG (UART_FIFO_AHB_REG (1)));
printf ("Counter (after read): %d, Read Index (after read): %d\n", UART [1]->status.rxfifo_cnt, UART [1]->mem_rx_status.rd_addr);
}
}
Code: Select all
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);
//Due to hardware issue, we can not use fifo_rst to reset uart fifo.
//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));
}
return ESP_OK;
}
Is there any reference to this particular failure to increment the UART index anywhere in the documentation? What would be the best recommended software fix so the FIFO can be read correctly without incident?