MQX USB Kinetis Driver Bug and... Why can't I receive output from host controller?

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

MQX USB Kinetis Driver Bug and... Why can't I receive output from host controller?

ソリューションへジャンプ
700件の閲覧回数
VictorLorenzo
Contributor IV

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

NAKs-01.png

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

0 件の賞賛
返信
1 解決策
420件の閲覧回数
VictorLorenzo
Contributor IV

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

元の投稿で解決策を見る

0 件の賞賛
返信
1 返信
421件の閲覧回数
VictorLorenzo
Contributor IV

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

0 件の賞賛
返信