This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

USB CDC-Device fails reading after some thousand bytes

Hello together! I'm having trouble with the USB CDC-Device Class. After sending some thousand of bytes from the Host (PC, Win 7/8) to my devices (NXP LPC1769/1778) the communication fails.
For example:
After sending a packet of 1002 bytes, the function USBD_CDC_ACM_GetChar() repeats "-1" after reading of 960 bytes. So there seems to be 42 bytes missing. Then, after sending the next packet of 12 bytes, USBD_CDC_ACM_GetChar() does not return the short telegram, but the missing 42 bytes. Exactly after the last byte of the old (large) telegram, the function starts repeating "-1" again. The new (12 byte) telegram is just not recognized. After repeated sending of the 12 byte packet, USBD_CDC_ACM_GetChar() suddenly repeats both (12 byte) telegrams. This is very strange behaviour to me. Seems as if all bytes where received correct inside RL-USB, but the handler is doing something wrong in there.

Any idea what i could do next?

I am using MDK 4.70 and usb_config.c is configured as following:
Bulk Endpoint Settings
. Bulk In Endpoint Number 2
. Bulk Out Endpoint Number 2
. Endpoint Settings
.. Maximum Packet Size 64
Communication Device Settings
. Maximum Comm Dev Send Buffer 1024
. Maximum Comm Dev Recv Buffer 1024

Parents Reply Children
  • Recently updated to 4.74 -> no change.. :-(

  • Can you please specify which microcontroller are you using?

  • That's also stated in the opening post!

  • Hi,

    are you using standalone or RTX variant?

    My guess is that you are constantly calling USBD_CDC_ACM_GetChar which blocks buffer that receives data and thus does not give the CDC engine time to process the received data, if so can you add a delay between USBD_CDC_ACM_GetChar calls and try then.

  • Increase Recv Buffer size to 2048, so that "pending" doesn’t work at 1002 bytes.

    usb_config.c
    
    #define USBD_CDC_ACM_RECEIVEBUF_SIZE    2048
    


    On the wizard, 1024 is the max option.
    You have to directly touch to this macro with the editor.

    > After sending a packet of 1002 bytes, the function USBD_CDC_ACM_GetChar() repeats "-1" after reading of 960 bytes. So there seems to be 42 bytes missing. Then, after sending the next packet of 12 bytes, USBD_CDC_ACM_GetChar() does not return the short telegram, but the missing 42 bytes. Exactly after the last byte of the old (large) telegram, the function starts repeating "-1" again.
    . Maximum Comm Dev Recv Buffer 1024

    Your description suggests that the last packet (42bytes) after 960 (= 64 x 15) bytes on the buffer of 1024 (= 64 x 16) bytes is deferred.

    In an old CDC source code of Keil, picked up from MDK v4.22a, I found a bug, which causes the same behavior as you described.

    MDK v4.22a \Boards\Keil\MCB2300\USBCDC\cdcuser.c
    
    void CDC_BulkOut(void) {
      int numBytesRead;
    
      /* check if we can store the maximum possible received data */
      if ((CDC_BUF_SIZE - CDC_BUF_COUNT(CDC_OutBuf)) <= USB_CDC_BUFSIZE) {  // <----- (1)
        CDC_DepOutPending = 1;                 /* data is pending */
        return;
      }
    
      /* get data from USB into intermediate buffer */
      numBytesRead = USB_ReadEP(CDC_DEP_OUT, &BulkBufOut[0]);
    
      /* store data in a buffer to transmit it over serial interface */
      CDC_WrOutBuf ((char *)&BulkBufOut[0], &numBytesRead);
    
    }
    

    In this implementation, the line (1) has a bug.
    This line should be ( "<=" is replaced to "<"),
    if ((CDC_BUF_SIZE - CDC_BUF_COUNT(CDC_OutBuf)) < USB_CDC_BUFSIZE) {

    By this bug, the last packet, which makes the OUT (Receive) buffer full, is unnecessarily deferred (CDC_DepOutPending = 1).

    I believe this bug is still living in the current USBD_CDC_ACM implementation.

    Tsuneo