ASMedia FX3 EP hangs on USB 3.0 eXtensible Host Controller

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
JoMa_292246
Level 2
Level 2
10 replies posted 5 replies posted First question asked

Hello,

We have an FX3 based design which we are running on a Windows 10 platform which has both an ASMedia 3.0 eXtensible Host Controller and an ASMedia 3.1 eXtensible Host Controller. On the ASMedia 3.0 xHCI, data will transfer but randomly hang (we cannot communicate with the FX3 over USB when this condition occurs). But on the ASMedia 3.1 xHCI controller, the FX3 will never hang/freeze. A few things to note:

  1. The FX3 firmware is based off the bulk synchronous slave FIFO example. The slave FIFO interface is driven by an FPGA.
  2. The hang/freeze only occurs on USB IN transactions. USB OUT transactions never fail on either of the ASMedia xHCIs. We done several hundred gigabytes worth of data transfers to the USB  OUT endpoint with no failures and zero data errors.
  3. We have tried both the current Windows 10 (update) ASMedia driver (1.16.41.3) and what we believe is the latest version (1.16.55.1) with the same results.
  4. We have tried transferring different PC buffer sizes (Windows application buffer) from 1K to 16MB. Again, this only fails when transferring data from the FX3 device to the PC (IN transaction).
  5. Even though communication over USB is impossible, the FX3 is still live. Through the debugger, we can pause the software or set breakpoints. Since this is a self-powered device, we can move to a new USB port and enumeration and USB communication works fine until the next time the USB interface hangs/freezes.
  6. We have tried different DMA FIFO sizes from 1 KB to 32 KB.
  7. We have tried FIFO counts of 1 and 2.
  8. We have tried USB/DMA burst counts of 1 through 16.
  9. We have implemented both CyU3PUsbLPMDisable and CyU3PUsbSetLinkPowerState (CyU3PUsbLPM_U0) in our code.
  10. We have tried moving the EP to EP1, EP2, EP3, and EP6 with the same failure.
  11. The same results happens on a different computer.
  12. Our USB protocol analyzer shows no error, just the last USB IN transaction. Followed by a check of our other “application specific command” EP with an ERDY response. But again, communication over USB at this point is impossible.
  13. In the hung/frozen state, the FX3 slave FIFO interface has the FIFO full flag and the almost full flag asserted, so no new data can be sent from the FPGA to the FX3. It’s like all the DMA FIFOs got committed but since no data is being transferred over USB, no empty DMA FIFO is returned to the FPGA interface.
  14. Power management for the USB hubs and the CPU have been disabled.
  15. We have had this code base working on other USB 3.0 eXtensible host controllers for years with no issues.
  16. The hang occurs randomly. Sometimes the transfer hangs immediately and sometimes it hangs after 10 minutes of continuous transfers.

Thanks in advance,

Motz

1 Solution
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hi Motz,

A. CY_U3P_USB_EVENT_RESET is a LTSSM Reset. This event occurs when there is a warm reset issued by the Host. CYU3P_USBEP_SS_RESET_EVT occurs when there were lot of protocol level retries and CRC happening on the USB bus. This may happens due to bad cables/bad testing environment.

B. When the USB 3.0 device has no data, it sends NRDY to the Host. And when the device is ready, it sends ERDY.

D, E and F:

So, to handle the CYU3P_USBEP_SS_RESET_EVT event: An endpoint event callback needs to be registered using  CyU3PUsbRegisterEpEvtCallback(CyU3PUsbEpEvtCb_t cbFunc, uint32_t eventMask, uint16_t outEpMask, uint16_t inEpMask).

Here the eventMask indicates for which of the events, the callback needs to be raised. If CYU3P_USBEP_SS_RESET_EVT is set in the mask, then the callback comes only for the registered IN endpoints(using inEpMask) where CYU3P_USBEP_SS_RESET_EVT happens.

When this event is triggered, we need to STALL the IN endpoint.

When the stall is done, then the API in the Host which requests data from the device times out(where the API fails) indicating that there is a STALL condition on the endpoint.

On getting the same, Host needs to send CLEAR_FEATURE request to the device.

The CLEAR_FEATURE handling on the device side, should flush the endpoint memory and reset it. Doing this would recover the IN endpoint.

The following example in the FX3 SDK can be referred where the CYU3P_USBEP_SS_RESET_EVT is handled for 2 IN endpoints:

FX3_Installation_Path\EZ-USB FX3 SDK\1.3\firmware\basic_examples\cyfxgpiftousb

Regards,

Hemanth

Hemanth

View solution in original post

5 Replies
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hi Motz,

1. Are you seeing any USB endpoint event(like CYU3P_USBEP_SS_RESET_EVT) when the failure happens? To know the same, please register for the endpoint event callback using the API CyU3PUsbRegisterEpEvtCallback.

2. When the hang occurs, can you send a CLEAR_FEATURE request over EP0, targeting the End Point which caused the hang (In Endpoint).

You can implement the CLEAR_FEATURE handling for the endpoint as done in the GpifToUsb example in fx3 SDK

(EZ-USB FX3 SDK\1.3\firmware\basic_examples\cyfxgpiftousb)

CLEAR_FEATURE handling in the above example code:

----------------------------------------------------------

if ((bTarget == CY_U3P_USB_TARGET_ENDPT) && (bRequest == CY_U3P_USB_SC_CLEAR_FEATURE)

                && (wValue == CY_U3P_USBX_FS_EP_HALT))

        {

            if (glIsApplnActive)

            {

                if (wIndex == CY_FX_EP_CONSUMER)

                {

                   .....

--------------------------------------------------------------

Let me know the test results and also regarding the first point.

(It would be better if you test the above when LPM is disabled)

Regards,

Hemanth

Hemanth
0 Likes

Hi Hemanth,

Thank you very much for helping us out. We have been banging our heads on this for a couple of weeks.

  1. Yes, we hang on a CYU3P_USBEP_SS_RESET_EVT event. As you suggested, I created an event callback. As soon as we get a CYU3P_USBEP_SS_RESET_EVT event, the FX3 USB interface is 100% non-responsive.
  2. You have suggested that we send a CLEAR_FEATURE request over EP0. But this requires us to know when the FX3 USB interface has had a reset event and then we would have to launch a thread to do a CLEAR_FEATURE. Is there no way to clear the error condition in the CYU3P_USBEP_SS_RESET_EVT callback routine? Self-recovery would be so much easier for us to do.

Thanks again,

Motz

0 Likes

Hi Hemanth,

I have a follow on question:

3. Do you know what would cause a CYU3P_USBEP_SS_RESET_EVT event to occur? Maybe if we know the reason for the reset, we can do something to avoid this condition.

Best,

Motz

0 Likes

Hello,

I have a little more information to add. Our USB IN data is burst-y. What we think is happening is that every so many hundreds of Kilo-Bytes, we have a few micro-seconds of delay before we start filling the FX3 FIFO again. We are wondering if this is causing a delay of packets to be sent to the host controller. This is hard to verify as it is difficult to get a logic analyzer (on the FX3 FIFO interface) to trigger at the right moment that the CYU3P_USBEP_SS_RESET_EVT occurs on the USB bus.

What we do notice is that there are a series of CYU3P_USBEP_NAK_EVT events before the CYU3P_USBEP_SS_RESET_EVT occurs. So we’re wondering if the host controller is getting too many NAKs, so it then throws out a reset? I do have a few follow on questions:

  1. What is the difference between a CY_U3P_USB_EVENT_RESET and a CYU3P_USBEP_SS_RESET_EVT? Is one a USB bus reset and the other a LFPS Warm Reset?
  2. In Auto DMA mode, when there is no FX3 FIFO buffer to consume to the USB bus, does the FX3 NAK until the FIFO interface socket produces a new buffer to be sent over the USB (IN transaction)?
  3. If "B" is yes, why doesn't the FX3 USB IN endpoint sent a NRDY to the host controller while it's waiting for the next FIFO buffer instead of NAK-ing? And when it does receive the next Producer buffer, it could then send an ERDY?
  4. Below is a code snippet we tried in a callback. It helped a lot. We still eventually got a CY_U3P_USB_EVENT_RESET but it took a very long time. Unfortunately, it reduced our bandwidth by 20% which is undesirable. Is there some other faster option to pacify the host controller? FYI, we had to use CYU3P_WAIT_FOREVER or the calls would occasionally fail. Again, this worked very well but not perfectly. Is there something else we should be doing?

else if (evType == CYU3P_USBEP_NAK_EVT)

{

                CyU3PDmaChannelSuspendUsbConsumer(&glChHandleSlFifoPtoU, CYU3P_WAIT_FOREVER);

                status = CyU3PDmaChannelGetBuffer (&glChHandleSlFifoPtoU, &buf_p, CYU3P_WAIT_FOREVER);

                if (status != CY_U3P_SUCCESS)

                {

                                CyU3PDebugPrint (4, "CyU3PDmaChannelGetBuffer failed, Error code = %d\n", status);

                }

                CyU3PDmaChannelResumeUsbConsumer (&glChHandleSlFifoPtoU);

}

E. We are also thinking that the above code actually did nothing, but the delay (for whatever reason) was what helped things. The reason we think this, is that just putting in a simple CyU3PThreadSleep helped. But it did not help as much as the above code. When your in a CyU3PUsbRegisterEpEvtCallback, what exactly is happening with the USB bus?

F. Again, is there someway we can recover (without host intervention) from a CY_U3P_USB_EVENT_RESET. If we could do this (quickly) this would solve all our issues.

Thanks,

Motz

0 Likes
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hi Motz,

A. CY_U3P_USB_EVENT_RESET is a LTSSM Reset. This event occurs when there is a warm reset issued by the Host. CYU3P_USBEP_SS_RESET_EVT occurs when there were lot of protocol level retries and CRC happening on the USB bus. This may happens due to bad cables/bad testing environment.

B. When the USB 3.0 device has no data, it sends NRDY to the Host. And when the device is ready, it sends ERDY.

D, E and F:

So, to handle the CYU3P_USBEP_SS_RESET_EVT event: An endpoint event callback needs to be registered using  CyU3PUsbRegisterEpEvtCallback(CyU3PUsbEpEvtCb_t cbFunc, uint32_t eventMask, uint16_t outEpMask, uint16_t inEpMask).

Here the eventMask indicates for which of the events, the callback needs to be raised. If CYU3P_USBEP_SS_RESET_EVT is set in the mask, then the callback comes only for the registered IN endpoints(using inEpMask) where CYU3P_USBEP_SS_RESET_EVT happens.

When this event is triggered, we need to STALL the IN endpoint.

When the stall is done, then the API in the Host which requests data from the device times out(where the API fails) indicating that there is a STALL condition on the endpoint.

On getting the same, Host needs to send CLEAR_FEATURE request to the device.

The CLEAR_FEATURE handling on the device side, should flush the endpoint memory and reset it. Doing this would recover the IN endpoint.

The following example in the FX3 SDK can be referred where the CYU3P_USBEP_SS_RESET_EVT is handled for 2 IN endpoints:

FX3_Installation_Path\EZ-USB FX3 SDK\1.3\firmware\basic_examples\cyfxgpiftousb

Regards,

Hemanth

Hemanth