nRF52 receive UART data via interrupt

With our nRF52832/52840 products, the UART sometimes drops characters.

I'm using nrf_drv_uart (SDK12) with two, one-byte buffers, and an interrupt called when data is received. However the 1 byte buffers are just not enough even at 9600 baud when writing to flash and characters arrive.

But if you raise the buffer length, you then don't get an interrupt when a character arrives (it seems the buffer has to be full before you get an IRQ).

I saw a post at  nrf52 uarte receive timeout suggesting you could use a GPIOTE on the RX pin and then call nrf_drv_uart_rx_abort after a period of inactivity, and that it might be built into the SDK at some point. That was 6 years ago though.

So is there any way to do this via the SDK at the moment? I see nrf_serial in SDK15+ but it would appear to be synchronous (eg there's no way to get an interrupt when data is available).

Or is there an example of doing this just with SDK12? While I can definitely watch the RX pin and start a timer, I'm a bit concerned about how to call nrf_drv_uart_rx_abort and restart reception in such a way that we don't end up losing data if transmission restarts at just the wrong time.

thanks!

Parents
  • Hi,

    But if you raise the buffer length, you then don't get an interrupt when a character arrives (it seems the buffer has to be full before you get an IRQ).

    Yes, that is correct. This is a limitation with the UARTE peripheral. To get interrupt per character you need to use the older UART (not UARTE) peripheral, but that has the limitation you have seen.

    Libuarte is a library that uses GPIOTE and PPI to overcome the limitations of the UART and UARTE peripherals, but that is only present in later SDKs and is quite complex.

    Another option could be to use flow control (unless the HW is already set in stone).

Reply
  • Hi,

    But if you raise the buffer length, you then don't get an interrupt when a character arrives (it seems the buffer has to be full before you get an IRQ).

    Yes, that is correct. This is a limitation with the UARTE peripheral. To get interrupt per character you need to use the older UART (not UARTE) peripheral, but that has the limitation you have seen.

    Libuarte is a library that uses GPIOTE and PPI to overcome the limitations of the UART and UARTE peripherals, but that is only present in later SDKs and is quite complex.

    Another option could be to use flow control (unless the HW is already set in stone).

Children
Related