USB device transfer freezes

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USB device transfer freezes

1,549 Views
dusek_martin
Contributor IV

Hi,

my USB composite device:

- generic HID

- virtual COM

- custom class with interrupt IN, interrupt OUT and bulk IN endpoint

runs on MK22FN512VLL12. I use USB stack from SDK 2.1

The device communicates with host for several hours but then suddenly I get one of my custom class'es IN endpoints frozen in transfer state. For this frozen endpoint, endpoint state structure (in s_UsbDeviceKhciState structure) contains e.g.:

transferLength = 0x11

tranferDone = 0x00

state = 0x4040

It means that the endpoint is in transfer state waiting for host to read the data from the device.

My USB host (libusb library on Win 10) tries to read the data. However, the read function (libusb_interrupt_transfer or libusb_bulk_transfer) always timeouts with no data read. The USB_DeviceKhciIsrFunction is not executed when the transfer is initiated by the host.

There is no issue with data transfers from the host to the device on interrupt OUT endpoint, these always work, even when IN tranfers are frozen as described above.

To send data from the device to the host using interrupt IN or bulk IN endpoint I use USB_DeviceSendRequest() function. If this call succeeds I set my internal flag indicating that the transfer is in progress. Once callback function of the endpoint is called I clear the flag. I initiate next transfer only when the flag is cleared.

Can you please recommend how to troubleshoot this issue?

Labels (2)
0 Kudos
6 Replies

1,206 Views
bobpaddock
Senior Contributor III

You mention 'running for hours' and setting and clearing flags.
This has all the classic signs of a race condition in the flag handling.

Is the flag marked volatile?

Is it set in the IRQ and cleared outside of the IRQ (or other way around)?

0 Kudos

1,206 Views
dusek_martin
Contributor IV

Hi Bob,

thanks. Yes, the flag caused the issue. I had these two lines in my code without disabling interrupts before and enabling them after:

USB_DeviceSendRequest(...)

busy = 1;

Quite a surprise for me that that interrupt indicating transfer completion (and clearing busy flag) can happen so quickly, that it happens inside USB_DeviceSendRequest. (CPU runs at 120 MHz, USB is full speed - 12 MHz). I used exactly same construction also in my other project and I never had any issue with that device. But that project was sending 2x - 3x larger packets over USB....

But of course, stupid mistake.

0 Kudos

1,206 Views
bobpaddock
Senior Contributor III

My solution to this flag issue is to increment a byte inside the IRQ on an event.
Then outside the IRQ compare that value to a previous copy to see if the event happened.

Gets rid of the whole set/clear race mess.

0 Kudos

1,206 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Martin,

 

We do not recommend you to use SDK 2.1. Could you please try using our latest SDK version (2.5.0).

 

You can download it from the following link:

https://mcuxpresso.nxp.com/en/welcome

 

Regards,

Felipe

0 Kudos

1,206 Views
dusek_martin
Contributor IV

This is my usb communication when the communication freezes. Host wants to read data from endpoint 4 (that is interrupt in endpoint) but the transaction ends with NAK.

endpoint.png

At the same time, this is the state of endpoint 4:

endpointstate.png

(endpointState[0] has also always tranferring = 1, all other endpoints has transferring = 0)

Also, no there are no USB interrupts at that time.

0 Kudos

1,206 Views
dusek_martin
Contributor IV

Hi Felipe,

unfortunately, my app built with SDK2.5 has exactly same issue.

Martin

0 Kudos