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
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