Hi,
I am working on an application with ncs 2.5.0 that is based on a combination of the central_uart example and the hci_lpuart as I'm trying to pass data around between the nRF52840 and the nRF9160 on the nRF9160DK. I'm running into some issues that don't really seem to consistent with the documentation of the UART_ASYNC_API, or I am interpreting it incorrectly.
It seems that my issues are related to this issue, however since I'm using v2.5.0, I would expect it's not the same bug.
When I keep the UART_RX_TIMEOUT at 50000 (same as in the central_uart example), it seems to work well, however, when I send messages quickly after another, I notice messages are grouped together. Therefore, I was thinking to reduce the UART_RX_TIMEOUT to a value that should ensure that UART_RX_RDY is triggered after every single message. Since the uart speed is set to 1000000, I thought having a UART_RX_TIMEOUT of a little over 1 (us) should be enough to ensure that UART_RX_RDY is triggered after a burst of characters.
However, when I set the UART_RX_TIMEOUT to 5 (us), I notice that UART_RX_RDY does get triggered, but it doesn't lead to the uart_rx_disable because the \r \n (indicating the end of a single message) are not identified. When logging the length of the buffer, I see that indeed not the full message is received yet when UART_RX_RDY is called. I see that data only gets added to the FIFO when the buffer is full after receiving more messages, which results in calling UART_RX_BUF_RELEASED after UART_RX_BUF_REQUEST.
The strange thing is, when I increase the UART_RX_TIMEOUT, the length of the buffer in my repeated UART_RX_RDY logs increases, but UART_RX_RDY is not called when the full message is received for some reason unless I increase the UART_RX_TIMEOUT to a high value. For a message of length 14 (including the \r \n), these are my findings. With UART_RX_TIMEOUT set to 5us, I see UART_RX_RDY triggered at lengths 3 and 6, with the timeout set to 50us it is triggered at length 6 and 7, at 500 us timeout it is triggered at length 10, and at 5000us it is finally triggered at length 14 and the message is added to the FIFO since the last bytes match \r \n.
This raises 3 questions:
1. It makes sense that UART_RX_RDY is called multiple times if the UART_RX_TIMEOUT is close to the time it takes to send a byte and if there are other things happening on the sender side that may slightly delay sending bytes. However I was under the impression that the Async API would result in a pretty consistent 'time between bytes' independent of activity in other threads. Am I misunderstanding that with a uart_speed set to 1000000, the average time between bytes should be around 1us?
2. When I do seem to get multiple calls of UART_RX_RDY after receiving some bytes, I don't seem to get UART_RX_RDY after getting the full 14 bytes unless I increase the timeout to ensure that I received the full message in one go. If UART_RX_RDY is triggered in between receiving full messages, shouldn't it also be triggered after receiving the full message since this will also result in a timeout when no new bytes are being transmitted?
3. The documentation indicates that the timeout is counted from the last byte received. With a relatively stable transmit speed, I would expect that UART_RX_RDY would be called either after every byte or after receiving a full burst of bytes (aka the full message), depending on the timeout selected. From my measurements, it seems however that the buffer length is increasing with increasing timeout. This seems to point towards the timeout not counting from the last byte received, but from the first byte received. What could be the reason for this behavior?
I can implement a work around to split up a buffer in multiple messages if this happens when the timeout is set to a large value, but I wanted to make sure I understand the operation of the UART Async API since it will play a critical role in the application ensuring data integrity. I hope you can help me understand why i'm seeing what I'm seeing.
Best,
Wout