UART RX double buffering

Hi Nordic experts,

I'm working for Particle Inc. We are using nRF52840 on our dev boards (Argon / Boron / etc.). We are experiencing a UART RX data lost issue using a single buffer for receiving. We designed our own UART driver that is independent from the nrfx driver. See the soure code for your reference: https://github.com/particle-iot/device-os/blob/develop/hal/src/nRF52840/usart_hal.cpp. Here I'd like your official suggestion about the UART RX path: whether double buffering is the best approach to avoid RX data lost. We have created a PR to refactored our driver to use double buffering for RX path: https://github.com/particle-iot/device-os/pull/2685

Any suggestion would be really appreciated.

Best regards,

Guohui

  • Hi

    I'm sorry, but we can't do reviews of custom drivers as we won't be liable for any drivers developed outside of our R&D team and review process I'm afraid. Additionally we're not too many used to working with C++, so you might not get the most thorough review of a C++ driver.

    Regarding the UART RX buffering, we do not use double buffering in our driver, but you're welcome to implement it on your end to improve data loss, although it should not be necessary. The most common cause for data loss in the buffers is the buffers not being large enough or the UART transmitting more data than the receiver is able to process, thus eventually overflowing buffers eventually no matter the size if you don't give it time to do only processing now and then.

    Best regards,

    Simon

  • The data loss can happen if NRF_UARTE_SHORT_ENDRX_STARTRX is not enabled and the NRF_UARTE_EVENT_ENDRX is not handled in time, i.e. the receiver is not re-started in time while the peer device is sending data, right? Or other ISRs with higher priority may also postpone the handling of the NRF_UARTE_EVENT_ENDRX event, such as SoftDevice interrupts? In our case, the buffer doesn't overflow, but we did lost data in the middle of a transaction.

    Best regards,

    Guohui

  • Hi

    I'm not sure I understand your first sentence, but yes, processes with higher priority can postpone UARTE peripheral handling, and the SoftDevice will always take precedence over other peripherals. If so I think you need to add a STOP event when the UARTE is interrupted for example to make sure the transmitting device stops transmitting when you're interrupted on the receiver for example.

    Best regards,

    Simon

  • Hi Simonr,

    What I meant is by default the NRF_UARTE_SHORT_ENDRX_STARTRX is not enabled, so the receiver is automatically stopped by hardware when the NRF_UARTE_EVENT_ENDRX is asserted, right? If so, we have to re-start the receiver manually by software when servicing the UART ISR to handle the NRF_UARTE_EVENT_ENDRX event. If the UART ISR is interrupted/suspended by whatever ISR that has higher priority, then the receiver is not enabled during this period, so that we might loss data if the peer UART device is keeping sending data.

    Best regards,

    Guohui

  • Hi

    Okay, so even double buffering won't guarantee that you won't lose data when using the UART peripheral, to be certain you're not missing anything you'd need to enable flow control, which is an application choice. 

    Best regards,

    Simon

Related