Async UART API in Zephyr timeout to slow

Hello all,

We are working on an nRF52832 and use the UART peripheral in the latests Zephyr release. As we have a lot of data to send from the nRF to the linux host we are using the async uart interface (DMA) and this works flawlessly. Sometimes the Linux host needs to send some small packets to the nRF side and thus we use the `uart_rx_enable` function. In our protocol timings are very strict and this is where the problem arises.

The DMA receive buffer is 128B long but many messages coming from the linux host are much smaller. We therefore need to rely on the timeout to get an interrupt before the receive buffer is full. We enable receiving as follows:

uart_rx_enable(uart_dev, rx_bufs[0], RX_BUF_SIZE, USEC_PER_MSEC);

We would thus expect an interrupt every millisecond, as soon as at least one byte was received by the DMA. The problem is that the timeout that we are measuring is much, much longer and we have determined a minimum of about 16ms. 

We suspect it may have something to do with the clock source of the interrupt but we need some pointers on how to fix this. 

Kind regards,
Daan

Parents
  • Hello Daan, 

    We would thus expect an interrupt every millisecond, as soon as at least one byte was received by the DMA.

    First of all, I would like to clarify that when using the Asynchronous API, there is no interrupt function. The triggered events are handled by a callback function instead.  

    The problem is that the timeout that we are measuring is much, much longer and we have determined a minimum of about 16ms. 

    That being said, the timeout of the uart_rx_enable() function defines an inactivity period. I assume that you might want to do some modifications there. 

    We suspect it may have something to do with the clock source of the interrupt but we need some pointers on how to fix this. 

    Otherwise, the uart_event_type gives quite a decent description of how this API is supposed to work. 

    Cheers, 

    Markus 

    1. Documentation states that “Inactivity period after receiving at least a byte which triggers uart_event_type::UART_RX_RDY event.” & “If some data was received and timeout occurred uart_event_type::UART_RX_RDY event will be generated. It can happen multiples times for the same buffer. RX timeout is counted from last byte received i.e. if no data was received, there won’t be any timeout event.” Can you confirm that at least one byte was sent in this particular case?

    Yes this is the case

    1. As already mentioned, if you change the timeout to a different value, how long will the offset be then? I asked this because it would be interesting to know if you can see any pattern.

     Anything below 16ms gets unstable and gives timeouts around 16ms. Above 16ms it works as expected.

Reply
    1. Documentation states that “Inactivity period after receiving at least a byte which triggers uart_event_type::UART_RX_RDY event.” & “If some data was received and timeout occurred uart_event_type::UART_RX_RDY event will be generated. It can happen multiples times for the same buffer. RX timeout is counted from last byte received i.e. if no data was received, there won’t be any timeout event.” Can you confirm that at least one byte was sent in this particular case?

    Yes this is the case

    1. As already mentioned, if you change the timeout to a different value, how long will the offset be then? I asked this because it would be interesting to know if you can see any pattern.

     Anything below 16ms gets unstable and gives timeouts around 16ms. Above 16ms it works as expected.

Children
No Data
Related