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

How to properly implement RX timeout in usbd_ble_uart example

I am trying to implement the central side code for the usbd_ble_uart example.  My current target is the nRF52840 Development Kit but the final target is the nRF52840-Dongle.

My development environment is EWARM 8.30.1 with Nordic SDK 15.2

In the peripheral example given (sdk\examples\peripheral\usbd_ble_uart\main.c) the cdc_acm_user_ev_handler() case for APP_USBD_CDC_ACM_USER_EVT_RX_DONE handles data received from the PC over the USB interface using the CDC (virtual serial port) protocol.

My problem is the example code does not send data across the BLE NUS link until either a carriage return or a new line character is seen or until the buffer is full.  I want to remove the check for new line or carriage return and add a timeout.

The problem is this code only gets called if a character is received from the USB port - any checks for timeout would not be performed until a new character was received.  If several characters were received and then a 50 ms pause happened before the next character, the buffered data would be delayed for that 50 ms pause.

What is the proper/expected way to handle this problem?  This isn't an unusual issue so my guess is the USB CDC library has some mechanism designed in to handle it that I haven't found.  I do not want to use single byte buffers since I don't know if the underlying library layers will queue the multiple byte writes up into a single BLE transmission.

Parents
  • Hello,

    As you say, single byte buffers is not an ideal solution, as every packet sent using ble_nus_data_send() will be sent as a separate packet, so this would cause an unnecessary amount of headers in your data transfer.

    Unfortunately, if you remove the new line or buffer checks, the USB stack doesn't have a way of detecting that there are no more characters coming. You would have to implement this using a timer:

    Start a timer with e.g. 50ms timeout whenever you receive a character. Before you start the timer, you would have to stop it (in case it was started by a character received earlier). If you get the timeout event, you can interpret this as if the USB is done sending you characters and call the ble_nus_data_send.

    To get access to the buffer, you will either have to store this as an array in your application layer, so that the timeout handler can access it, or send it as a pointer in the timer.

    Best regards,

    Edvin

Reply
  • Hello,

    As you say, single byte buffers is not an ideal solution, as every packet sent using ble_nus_data_send() will be sent as a separate packet, so this would cause an unnecessary amount of headers in your data transfer.

    Unfortunately, if you remove the new line or buffer checks, the USB stack doesn't have a way of detecting that there are no more characters coming. You would have to implement this using a timer:

    Start a timer with e.g. 50ms timeout whenever you receive a character. Before you start the timer, you would have to stop it (in case it was started by a character received earlier). If you get the timeout event, you can interpret this as if the USB is done sending you characters and call the ble_nus_data_send.

    To get access to the buffer, you will either have to store this as an array in your application layer, so that the timeout handler can access it, or send it as a pointer in the timer.

    Best regards,

    Edvin

Children
No Data
Related