UART hardware flow control with interrupts

Hello,

I have an application where I send the data I receive over UART, directly to a phone connected with BLE. However, the BLE connection is often not fast enough to send the large quantities of data I receive on my UART lines. This results in buffers being overrun inside my application. Currently I have hardware flow control enabled, interrupts enabled, and I'm not using the HAL layer of the SDK. Because of the interrupts, the hardware flow control is not signaling the sender of the data that it has no more space left to buffer the incoming data.

My question is: can I somehow tell the UART driver to halt reading until the data has been send via BLE while using interrupts, do I have to implement the RTS and CTS toggling myself, or is there a better way to fix this, preferably without having to rewrite the interrupt way of receiving data over UART.

Thanks in advance!

(SDK v16.0.0)

Parents
  • Hi

    From the description in the documentation on Transmission in the UARTE/UART peripheral in our PS. "If HW flow control is enabled the RTS signal will be deactivated when the receiver is stopped via the STOPRX task or when the UARTE is only able to receive four more bytes in its internal RX FIFO." The RTS should toggle when you have received too much data for the nRF to be able to handle. I assume what's happening is that the UART is interrupted before this RTS is toggled, causing this overflow. Unless the interrupts that are causing these issues can be set to a lower priority than the UART peripheral I think you might need to toggle the RTS whenever an interrupt is triggered yourself.

    Best regards,

    Simon

Reply
  • Hi

    From the description in the documentation on Transmission in the UARTE/UART peripheral in our PS. "If HW flow control is enabled the RTS signal will be deactivated when the receiver is stopped via the STOPRX task or when the UARTE is only able to receive four more bytes in its internal RX FIFO." The RTS should toggle when you have received too much data for the nRF to be able to handle. I assume what's happening is that the UART is interrupted before this RTS is toggled, causing this overflow. Unless the interrupts that are causing these issues can be set to a lower priority than the UART peripheral I think you might need to toggle the RTS whenever an interrupt is triggered yourself.

    Best regards,

    Simon

Children
  • Hi,

    From what you've mentioned and what is written in the documentation you linked I have figured out a way to accomplish what I need. The documentation states: "The RTS signal will also be deactivated when the receiver is stopped through the STOPRX task".

    The driver has the function "nrfx_uart_rx_disable" to trigger this STOPRX task. The documentation also states here that: "the UART is able to receive four to five additional bytes if they are sent in succession immediately after the RTS signal has been deactivated." This is not a problem when you trigger the STOPRX task when the buffer is not completely full yet.

    To enable it again after the buffer is sufficiently empty, the driver contains the function "nrfx_uart_rx_enable". Then, to enable the interrupts again, you will have to call "nrfx_uart_rx" once (or twice when you are using a double buffer). Don't assert on NRF_SUCCESS, as the result could be NRF_ERROR_BUSY when the buffers both still contain data.

    So in my case with a double buffer:

    // Disable UART rx, deactivates RTS signal
    nrfx_uart_rx_disable(&m_uartInstance);
    
    
    // Enable UART rx, activates RTS signal
    nrfx_uart_rx_enable(&m_uartInstance);
    
    nrfx_uart_rx(&m_uartInstance, pByte1, 1);
    nrfx_uart_rx(&m_uartInstance, pByte2, 1);
    

    Thanks for your help!

Related