RS485 + Wifi. uart_read_bytes() reads less bytes than requested
Posted: Mon Mar 04, 2024 11:00 am
I have a custom ESP32 board which polls 4Mbit/s data to other ESP32 custom board via custom RS485 protocol at baudrate of 115200*120. Then it has to send that data via wifi TCP socket.
I am using only core 0, as core 1 is full busy with a task that does SPI transfers to an ADC. I spawn two tasks one that reads the data from RS485 and other that sends that data out via wifi TCP socket. Wifi and TCP/IP tasks are pinned to core 0. UART interrupt is pinned to core 0 with level 3. SPI interrupt is pinned to core 1.
For UART, I setup RX TOUT = 15, and rx full thresh = 55.
This setup works most of the time, i. e. the UART reads correctly all bytes and sends them through wifi with no failure.
There are some times (randomly, maybe not happen in minutes) that the data UART read by uart_read_bytes() is less than the data required in length parameter.
Without sending the data through wifi, it works without any failure.
To debug, I am using gpio and a logic analyzer. In the uart isr handler uart_rx_intr_handler_default(), inside uart driver i turn on a gpio at the top of the function and turn it off at the end of it. So I can see the exact time it spends inside uart isr. A correct rs485 data transaction would look like this:
First row (brown) is the packet sent through rs485 asking for data.
Second row (white) is the data that has to be read.
We can see the uart isr (red line) is triggering at a fixed rate, caused by rx full threshold interrupt.
An error transaction look like this:
We see there is a uart interrupt that delays to rise. This delay is enough to overflow the FIFO. After some more debug I constated that an overflow is what is happening.
Thanks
I am using only core 0, as core 1 is full busy with a task that does SPI transfers to an ADC. I spawn two tasks one that reads the data from RS485 and other that sends that data out via wifi TCP socket. Wifi and TCP/IP tasks are pinned to core 0. UART interrupt is pinned to core 0 with level 3. SPI interrupt is pinned to core 1.
For UART, I setup RX TOUT = 15, and rx full thresh = 55.
This setup works most of the time, i. e. the UART reads correctly all bytes and sends them through wifi with no failure.
There are some times (randomly, maybe not happen in minutes) that the data UART read by uart_read_bytes() is less than the data required in length parameter.
Without sending the data through wifi, it works without any failure.
To debug, I am using gpio and a logic analyzer. In the uart isr handler uart_rx_intr_handler_default(), inside uart driver i turn on a gpio at the top of the function and turn it off at the end of it. So I can see the exact time it spends inside uart isr. A correct rs485 data transaction would look like this:
First row (brown) is the packet sent through rs485 asking for data.
Second row (white) is the data that has to be read.
We can see the uart isr (red line) is triggering at a fixed rate, caused by rx full threshold interrupt.
An error transaction look like this:
We see there is a uart interrupt that delays to rise. This delay is enough to overflow the FIFO. After some more debug I constated that an overflow is what is happening.
Thanks