Hello,
I'm developing a new class driver for a CCID device (Kinetis K20DN512VLK10) but can't manage to find why the low level driver only reports reception of the first bulk-out message from the host and NAKs all the rest.
QUESTIONS:::: Has someone experienced this before? Does any one have any idea why or what could cause the silicon IP to NAK all (but the first) OUT transactions from the host on the bulk-out endpoint?
Here is a USB analyser capture showing this situation. The transaction marked in blue color is the first command received in the bulk-out endpoint, I receive it, process it and return the SlotStatus message using the bulk-in endpoint. The following 234 NAKed IN transactions are OK and correspond to requests to the Interrupt-in endpoint (nothing changed inside the device so nothing is reported).
The problem is with the (323.902) NAKed OUT transactions shown at the end. That is not supposed to hapend, the controller (silicon IP on the Kinetis microcontroller) is automatically NAKing the transactions without reporting the data reception. No error is reported either (see more comment under the figure).
While tracking down the situation we found one potential bug in the Kinetis low level USB driver. In the function named _usb_device_usbfs_service_err_intr(), file: khci_dev_main.c, there are hardware error situations that could trigger the callback for the service USB_SERVICE_ERROR for errors not included in the mask. In this case the USB_SERVICE_ERROR service is called indicating a 0x00 error code. It can be replicated by configuring the Kinetis CPU clock for 100MHz instead of 96MHz in the BSP so the USB is driven at 50MHz instead of 48MHz and CRC5/CRC16 errors are reported. This code corrects the issue:
if (device_error)
{
/* Initialize the event strucutre to be passed to the upper layer*/
event.handle = (_usb_device_handle)state_ptr;
event.ep_num = ep_num;
event.setup = FALSE;
event.direction = (boolean)(stat >> 3 & 1);
event.buffer_ptr = (uchar*)&device_error;
event.len = ZERO_LENGTH;
/* Invoke Service Call */
(void)_usb_device_call_service(USB_SERVICE_ERROR,&event);
}
Thanks a lot in advance,
--Victor
已解决! 转到解答。
Hi All,
Applying the old method "you're wasting your time anyway so dive inside the full source code tree and master it"... in the CDC class the bulk out EP handler USB_Service_Dic_Bulk_Out() receives the BULK OUT event and calls one application callback with event code USB_APP_DATA_RECEIVED. The handler for this event ends calling the USB_Class_CDC_Recv_Data() function which in turn calls _usb_device_recv_data()... and that function seems to make the magic.
--Victor
Hi All,
Applying the old method "you're wasting your time anyway so dive inside the full source code tree and master it"... in the CDC class the bulk out EP handler USB_Service_Dic_Bulk_Out() receives the BULK OUT event and calls one application callback with event code USB_APP_DATA_RECEIVED. The handler for this event ends calling the USB_Class_CDC_Recv_Data() function which in turn calls _usb_device_recv_data()... and that function seems to make the magic.
--Victor