app_usbd_cdc_acm_write takes more time to transfer

Hi team,

I'm streaming the sensor data through USB (using hterm) every 2.5ms.

i have configures USB as CDC and using virtual COM port.

In each iteration, i transfer 87 to 95 bytes which varies based on data.

The issue i'm facing is that sometimes app_usbd_cdc_acm_write() takes 153us and sometimes it takes 214us and rarely it takes 30ms to complete the transfer.

Completing the transfer i mean to receive APP_USBD_CDC_ACM_USER_EVT_TX_DONE event.

 app_usbd_cdc_acm_write() never returns any error code.

Could you help me understand why this time difference in transfer and how could i resolve it?

  • Hi

    Do you have any other USB devices connected while running this test? 

    If so, are you able to run a test without any other connected USB devices to see if the erratic write times disappear?

    The CDC class uses USB bulk transfers, which means you are not guaranteed bandwidth or latency, only data integrity (that all the data you send is received successfully, and in the same order). 

    Best regards
    Torbjørn

  • If so, are you able to run a test without any other connected USB devices to see if the erratic write times disappear?

    yes when only one usb device is connected it didn't take 30ms and all but varies from 153 us o 615 us

  • Hi 

    Could you let me know what kind of device it is that is causing the 30ms delays?
    Do you know which USB class it is using?

    If you have a USB sniffer available you might be able to get more information about what is blocking the bus for so long, but this is not something most people have laying around ;)

    Best regards
    Torbjørn

  • Pretty sure that is just the missing zero packet after a complete 64 Byte packet.

    USB bulk transactions end with a packet that is not the full 64 bytes in size. Most USB CDC examples do not  implement this feature (from the USB bulk spec). If you wanted to run a transaction with an integer multiple of 64 bytes, you have to send a "zero packet" in order to properly "finish" the transaction. Otherwise the host will not return the data to the application, and the timeout is several seconds AFAIK.

    The NRF CDC implementation is buffered IIRC, and can thus run multiple full 64 byte packets when the amount of data transmitted happens to be an integer multiple.

    You longer 30ms delay is a result of a long 64 byte packets run, followed by one shorter packet. Should be visible in an USB analyzer app.

Related