This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

UART and SoftDevice interrupts

Some context: I am using an nRF51 with SoftDevice S130, which acts takes both central and peripheral roles, and uses UART to communicate to a peer MCU. I am currently facing the problem of making UART communication reliable when there is BLE activity going on. This could easily be solved by using hardware flow control, provided the peer can react fast enough to changes on the nRF's RTS (which it could). Unfortunately, the board has no more traces connecting the peer to the nRF that could be used as RTS/CTS and, for reasons I won't get into, modifying the board is not an option. What I *can* do is modify the code in both the nRF and the peer MCU.

I'll be using app high priority for UART interrupts. The first issue is preventing buffer overrun in the nRF - buffer overrun in the peer MCU is not a problem for me because it has nothing that can significantly delay interrupts. I am concerned about the longest time a SoftDevice priority 0 interrupt can last.

The answer to this question pointed me to interrupt durations for central and peripheral events.

From those, I gathered that the longest delay could come from a peripheral's event post processing at 775 us. I do need to know if my reasoning was correct, though:

- Are there any other interrupt sources I should be worrying about?
- Could any interrupts (central, peripheral or other) happen back to back, effectively lengthening the duration of the SoftDevice interrupt?
- Similarly, is it a safe assumption that I always have enough time between interrupts to empty the RX buffer into RAM when, say, using nrf_drv_uart?

Let's assume 775 us is correct. Since the nRF51's UART peripheral's RX buffer is 6 bytes long, a safe baud would be given by:

bytes in 775 us < 6

baud / 10 * bytes / 775 us < 6

baud < 77419 bits / second

So 76800 bits / second is looking like a good option.

On the TX side, you can only queue a single byte. This means at best I can use the 775 us to transmit a single byte (if I queue it right before the interrupt happens), or completely waste that time at worst. Throughput is a bit of a concern for my particular application since I am transmitting 20 byte samples at 100 Hz and looking into increasing this rate.

Supposing I knew average RX/TX packet length and connection interval for both central and peripheral connections, I think I should be able to calculate expected throughput, although it would be great if this analysis had already been done:

- Do you happen to know how to estimate the possible UART throughput given BLE connection parameters?

Lastly, maybe it would be better to treat the UART as unreliable, use some reliable protocol and use a higher baud. Maybe this is the easier option, I don't know.

- Do you think it's better to solve this by adding a reliable protocol on top of UART?

  • It seems you have thought of everything I could think of already, but just to confirm what you already write:

    - Are there any other interrupt sources I should be worrying about?
    - Could any interrupts (central, peripheral or other) happen back to back, effectively lengthening the duration of the SoftDevice interrupt?
    - Similarly, is it a safe assumption that I always have enough time between interrupts to empty the RX buffer into RAM when, say, using nrf_drv_uart?

     No, No, Yes (presuming you don't have any application interrupts that prevent this). 

    So 76800 bits / second is looking like a good option.

    Presuming the FIFO is empty at the start of the interrupt. 

    - Do you happen to know how to estimate the possible UART throughput given BLE connection parameters?

    No.

    - Do you think it's better to solve this by adding a reliable protocol on top of UART?

    I think that is a good idea. 

    A better idea may be to use the nRF52832, which can use EasyDMA to write directly to RAM.

Related