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

USBD CDC ACM issue

I am using SDK 15.0 with the Nordic NRF52840 development board. I wrote my own custom bootloader using CDC ACM as the transport. I am using  app_usbd_cdc_acm_read_any to read the data read from the USB. The client on the other side is sending data to the bootloader. I noticed that  I need to put nrf_delay_ms(20) for my bootloader to work properly. If I don't put delay of some time, then after a while I stop getting data from USBD. I just want to check if my usage is ok and why do I need to add delay of 20 ms? One more thing, that if I am running the bootloader using debugger in Keil then it works fine without the delay of 20ms. But when I run without the debugger , then it stops working and delay of 20ms is making it work for now.

 case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
        {
      ret_code_t ret;
     
     do
     {
           size_t size = app_usbd_cdc_acm_rx_size(&m_app_cdc_acm);     

//processing the data     
         
      nrf_delay_ms(20);
     ret = app_usbd_cdc_acm_read_any(&m_app_cdc_acm,
                                                   m_rx_buffer,
                                                  sizeof(m_rx_buffer));
    }while(ret == NRF_SUCCESS);

        } break;

Parents Reply Children
  • In the previous SDK 14.2 when I used app_usbd_cdc_acm_read I didn't see any issue. But with SDk 15.0 I don't want to use app_usbd_cdc_acm_read  as I don't want to read just one byte at a time or fix the number of bytes to be read before

  • Hi,

    First note that you can just call the read function where you expect the data - you do not have to do it inside the APP_USBD_CDC_ACM_USER_EVT_RX_DONE event.

    Also note that calling app_usbd_cdc_acm_read_any() inside a do-while loop like that is not ideal. You can also get a NRF_ERROR_IO_PENDING returned. So you should at least add that to the loop ending condition.

    }while(ret == NRF_SUCCESS || ret == NRF_ERROR_IO_PENDING);

    NRF_SUCCESS - we have data in the buffer already

    NRF_ERROR_IO_PENDING - we would wait for another APP_USBD_CDC_ACM_USER_EVT_RX_DONE for the data

  • Hi Sigurd,

    I didn't add the check for NRF_ERROR_IO_PENDING because the code I showed is called when we get the event APP_USBD_CDC_ACM_USER_EVT_RX_DONE. I would think that you don't want to be stuck in while loop inside the APP_USBD_CDC_ACM_USER_EVT_RX_DONE  event if the data is not available. we would only process the data which is already available in the buffer and then wait for the event APP_USBD_CDC_ACM_USER_EVT_RX_DONE  when it is IO_PENDING. That's what the logic of the code above is. Let me know if there is something I misunderstood.

    Thanks,

    Jyoti

  • Hi,

    Is your project based on the USB CDC ACM bootloader in SDK 15?
    What version of the nRF52840-PDK do you have?

    Maybe the nrf_logs could reveal something useful.
    Let’s try to output the logs over UART, and use e.g. Putty as terminal.

    Please make sure that you are using the bootloader project with _debug, and that you have the following configuration in sdk_config.h :

    NRF_LOG_ENABLED 1
    NRF_LOG_DEFAULT_LEVEL 4
    NRF_LOG_BACKEND_UART_ENABLED 1
    NRF_LOG_BACKEND_RTT_ENABLED 0
    USBD_CONFIG_LOG_ENABLED 1
    USBD_CONFIG_LOG_LEVEL 4
    APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED 1
    APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL 4
    NRF_LOG_ALLOW_OVERFLOW 0

    Then compare the logs with, and without the delay added.

Related