Code: Select all
void app_main()
{
// Config 2 UARTs
uart_config_t uart_config = {1020833, UART_DATA_8_BITS,
UART_PARITY_DISABLE, UART_STOP_BITS_1, UART_HW_FLOWCTRL_DISABLE};
uart_param_config(UART_NUM_1, &uart_config);
uart_param_config(UART_NUM_2, &uart_config);
uart_set_pin (UART_NUM_1, GPIO_NUM_13, GPIO_NUM_14, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_set_pin (UART_NUM_2, GPIO_NUM_22, GPIO_NUM_23, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
UART1.conf0.err_wr_mask = 1; // require stop bit on byte received
UART2.conf0.err_wr_mask = 1;
while (1)
{
WRITE_PERI_REG (UART_FIFO_AHB_REG (UART_NUM_1), 0x8D);
while (UART1.status.rxfifo_cnt < 2);
int b1 = READ_PERI_REG (UART_FIFO_REG (UART_NUM_1));
//int cnt = UART1.status.rxfifo_cnt;
int b2 = READ_PERI_REG (UART_FIFO_REG (UART_NUM_1));
int cnt = UART1.status.rxfifo_cnt;
// this reads first byte ok but instead of second byte it gets a copy of the first byte (while still clearing it out of the FIFO and decrementing the count)
// if the first line is uncommented and the second commented, then it reads both bytes correctly
printf ("%d - %d, %d\n", cnt, b1, b2);
vTaskDelay (100 / portTICK_RATE_MS);
}
}
The only thing I could find from searching was the following document "Workarounds for Bugs":
https://www.espressif.com/sites/default ... p32_en.pdf
On page 9 it says "Some ESP32 peripherals are mapped to two internal memory buses (AHB & DPORT). When written via DPORT, consecutive writes to the same address may be lost. When writing the same register address (i.e., FIFO-like addresses) in sequential instructions, use the equivalent AHB address not the DPORT address. (For other kinds of register writes, using DPORT registers will give better write performance.)" The table includes the UART FIFOs in the affected items.
Well I am not sequentially writting to the FIFO but rather sequentially reading from it, so it is not the same thing. However, I noticed that my code uses UART_FIFO_AHB_REG to get the address to write to, whereas it uses UART_FIFO_REG to get the address to read from. This seems to match the ESP's own drivers and most of the code samples I looked at. However, I tried changing the read to use UART_FIFO_AHB_REG instead, and it made the bug described stop! This is totally undocumented as far as I can tell, so I don't know that it is an acceptable solution.
So I am wondering the following:
• Do you really have to read the FIFO counter between each sequential FIFO read in order to actually get the next byte, versusgetting the previous byte and losing the actual one?
• Does reading from the UART_FIFO_AHB_REG instead of the UART_FIFO_REG work around the bug in the same way that sequentially writing to it apparently does?
• If either of the above workarounds are viable, which would be better to use?
• Is there some other explanation why the code sample above malfunctions that I am missing?