Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

USBD_CDC_ACM 1st byte missing on second message sent when messages are greater than 64 Bytes

Dear Nordic Support team,

Currently I am in the process of adding the USBD_CDC_ACM driver code to our existing application following your usbd_ble_uart example. I can receive messages okay if they are less than 64 bytes long but when a message is greater than 64 bytes then the next message received has the first byte missing. I am using SDK 15.2 and running a SES project.

This is the message I am sending with a line feed at the end.

{"mac":"68B9D3D0BEC0","idonly":0,"duration":10,"fctrl":1,"cloud":1,"utc":1606456028,"type":"MQTT","fsrvid":"0%0","msg":"shake","rssi":-40,"scanenable":0}

Here is the RX event code

case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
{
   ret_code_t ret;
   NRF_LOG_INFO("Bytes waiting: %d, Index %d", app_usbd_cdc_acm_bytes_stored(p_cdc_acm), rxIndex);

do
{
   /*Get amount of data transfered*/
   size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
   // NRF_LOG_INFO("RX: size: %lu char: %c", size, m_rx_buffer[0]);
   //NRF_LOG_INFO("RX: %c", m_rx_buffer[0]);
   /* Fetch data until internal buffer is empty */


   if(firstRx)       /* Breakpoint B */
   {
      ret = app_usbd_cdc_acm_read(&m_app_cdc_acm,
                                                         &m_rx_buffer[++rxIndex],
                                                         1);
       //NRF_LOG_INFO("P2 %d", rxIndex);
   }
   else
   {
      ret = app_usbd_cdc_acm_read(&m_app_cdc_acm,
                                                         &m_rx_buffer[rxIndex++],
                                                         1);
      //NRF_LOG_INFO("P3 %d",rxIndex );
   }

   //nrf_delay_ms(1);
   } while (ret == NRF_SUCCESS);

   if(m_rx_buffer[rxIndex-1] == '\n')
   {

      
      NRF_LOG_INFO("Rx %s",m_rx_buffer);    /* breakpoint A */
      NRF_LOG_INFO("P1");
      rxIndex =0;
      firstRx = false;
      memset(m_rx_buffer, 0x00, sizeof(m_rx_buffer));

   }
      //bsp_board_led_invert(LED_CDC_ACM_RX);
   break;
}

To reproduce this problem I first place a breakpoint at position A

I then ran the application and sent the message via a serial terminal with a Line Feed at the end.

It hits breakpoint A and the contents is as shown below with the complete message.

image 1

I then activate breakpoint B and click play.

I then resend the message changing it slightly i.e.

{"maw":"68B9D3D0BEC0","idonly":0,"duration":10,"fctrl":1,"cloud":1,"utc":1606456028,"type":"MQTT","fsrvid":"0%0","msg":"shake","rssi":-40,"scanenable":0}

At breakpoint B I look into my message buffer which should be NULLED from the memset but see it has the first character of the second message at index 154

image 2

I then step into function 'app_usbd_cdc_acm_read' as shown below

image 3

This shows that the message was received by the USB_CDC_ACM HAL layer okay but the index last_read is off by 1 byte thereby causing m_rx_buffer to be off by one and the 2nd byte of the sent message be in the first byte of my m_rx_buffer.

image 4

It looks like once the APP_USBD_CDC_ACM_USER_EVT_RX_DONE is hit, the first byte of the sent message has already been read by the HAL layer before function 'app_usbd_cdc_acm_read' has been executed.

Can you please fix this issue or suggest a way around it when processing APP_USBD_CDC_ACM_USER_EVT_RX_DONE events for messages greater than 64 bytes

Regards,

Jes

Related