cancel
Showing results for 
Search instead for 
Did you mean: 

USB Superspeed Peripherals

leda_289486
New Contributor II

CyU3PUsbSendEP0Data fail on Timeout 

Hi there,

I reactive this post because with CX3 and 1.3.4 SDK I still encounter the problem. Here is the situation. We have IN transfers superspeed nearly at maximum data rate of CX3. Typically, it is more than 2 Gbits/s. we use the EP0 for (vendor) commands and thus IN transfer. These IN transfers  on EP0 are very small, typically only 2 bytes returned as IN.

At a point, we get timeout code as result of CyU3PUsbSendEP0 function and after that there is NO way to retrieve the correct behavior even when IN superspeed transfers ends. I find this totally weird. There is no mean to reset this situation ?

On parallel OUT EP0 is still working, exactly as described in this post.

I tried to use the "suspend" code here described but this doesn't work because the suspend operation is not reliable and most of the time doesn't operate any suspend in DMA transfers : the gChannelSuspended variable doesn't commute to suspended state and timeout variable comes to zero itself. "Sometimes" the suspend arises but most of the time it doesn't. By the way we use auto Many to One transfers operations for the superspeed IN high data rate endpoint.

I also didn't find where the GpifToUSB code can help to understand the situation.

Is there a solution for this ? This problem seams to be present since several years now, we would be happy to solve it because this is really a HUGE problem when using CX3 and FX3.

Please give a solution for a RELIABLE EP0 RESET when timeout arises !!

Thank you

Best Regards.

0 Likes
1 Solution
KandlaguntaR_36
Moderator
Moderator

Hello,

CyU3PUsbAckSetup should not be called if CyU3PUsbSendEP0Data success.

We will correct the lowpowertest example firmware in the next revision.

Is the issue solved after the code modification?

Regards,

Sridhar

View solution in original post

0 Likes
46 Replies
KandlaguntaR_36
Moderator
Moderator

Hello,

As said in section 2.3 and sub-section IV of FX3_SDK Troubleshooting Guide (C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\doc\firmware), the FX3 has this problem in high-speed mode, and the work around is provided in the library 1.3.3 on wards. We have not seen this issue in USB Superspeed mode.

Please confirm whether you are operaing in USB 2.0 or USB 3.0 mode.

Can you please share the .c file where you are handling the vendor requests and what is the timeut error you have received for CyU3PUsbSendEP0 API?

0 Likes
leda_289486
New Contributor II

Hi KandlaguntaR_36,

Of course we are in superspeed USB3 mode (IN EP3 data rate >2 Gbits/s).

We use the 1.3.4 library and this is a CX3 board.

CyU3PUSBSendEP0 returns 69 as error code. Is there a way to precise this further ?

I can send you the .c files through e-mail address but this is quite basic code regarding the EP0 handling.

Thank you for your help,

Best Regards,

0 Likes
leda_289486
New Contributor II

Hi again KandlaguntaR_36,

Anyway, could I get a workaround that would be simply to "reset" the EP0 IN ? As I control the driver part of PC either, this would be enough to continue the development of the CX3 board before a complete solution without this 69 blocking error to appear.

Best Regards

0 Likes
KandlaguntaR_36
Moderator
Moderator

Can you help me in re-producing the issue at my end?

0 Likes
leda_289486
New Contributor II

Yes,

however it is our own board and of course firmware.

first, this is the requested file.

You'll see it is quite basic.

All answers on EP0 are 2 bytes long for vendorcommands.

Hope this will help

Best regards,

0 Likes
leda_289486
New Contributor II

Would it be possible to apply the USB 2.0 patch in USB 3.0 mode ?

My case confirms that this issue exists also in USB 3.0 !

Best Regards

0 Likes
leda_289486
New Contributor II

from your answer, I guess the CyU3PUsbSuspendInEpChannels() has to be performed to avoid this.

however this is static function so probably not callable directly from firmware.

I'll try to implement it in my own code.

Best Regards

0 Likes
leda_289486
New Contributor II

if (glUibDeviceInfo.usbSpeed != CY_U3P_SUPER_SPEED)

code is preventing the suspend action in SendEP0 function code while super_speed is performed.

So I have to completly modify this part.

Hope this is possible simply or I'll have to recompile the library without itself. Maybe You can help for this  ?

Best Regards

0 Likes
leda_289486
New Contributor II

Hi,

I have implemented the SendEP0 code with the only modification is to unset to == SUPER_SPEED tests and then authorize the suspend modification even in super_speed.

However, this does'nt prevent the issue to appear.

So I'd like to have the way to reset the EP0 IN to re-authorize transfers. The error is handled in driver so resetting the EP0 and restart IN EP0 transfer is not a problem.

Thank you for your help,

Best Regards.

0 Likes
leda_289486
New Contributor II

Hi

It is quite hard to understand why it is so difficult to simply reset the endpoint IN 0. I cannot find any reliable code for this. In the library there is following code :

static CyBool_t

CyU3PUsbIsNewCtrlRqtRecvd (

        void)

{

    if ((glUibDeviceInfo.newCtrlRqt) || (UIB->dev_ctl_intr & CY_U3P_UIB_SUDAV) ||

            (USB3PROT->prot_intr & CY_U3P_UIB_SUTOK_EV))

        return CyTrue;

    return CyFalse;

}

when it returns CyFalse, it is bye bye, no way to answer on IN EP0 after. Could you explain how to handle this ?

Thank you for your help,

Best Regards

0 Likes
leda_289486
New Contributor II

Hello

Is anybody there ??

Is this issue so difficult to be solved ?

This problems lasts for several years now. It's time to bring a reliable solution.

Best Regards

0 Likes
leda_289486
New Contributor II

Hi,

the problem lays in the SendEP0 function with this test :

                     /* Wait until the DMA socket and EPM are in ready state. */

                     while ((((UIB->sck[0].status & CY_U3P_UIB_STATE_MASK) >> CY_U3P_UIB_STATE_POS) != CY_U3P_UIB_STATE_ACTIVE) ||

                             ((UIB->eepm_endpoint[0] & CY_U3P_UIB_EEPM_EP_READY) == 0))

when this is never succeed in 500 ms (so called "tmo error") in code, then how to reset the EP0 IN correctly ?

I just want this information, I can manage otherwise.

Best Regards,

0 Likes
leda_289486
New Contributor II

precisely, on the previous test the problem is when :

((UIB->eepm_endpoint[0] & CY_U3P_UIB_EEPM_EP_READY) == 0))

is set to true to TRUE, ie UIB->eepm_endpoint[0] stays at 0x200 instead of (1<<30) | 0x200

hope this can help.

Can you explain how to turn this bit ON thus solving th e problem ? Of course setting it directly doesn't work. It auto returns to 0.

Best regards.

0 Likes
leda_289486
New Contributor II

Hi,

If you could tell me how to reset the CY_U3P_UIB_EEPM_EP_READY bit of UIB->eepm_endpoint[0]  when it is blocked at zero value, thus preventing all send to process normally, that would be great help.

Thank you for you help

Best Regards.

0 Likes
leda_289486
New Contributor II

Hi

Is there a solution to (re)set the CY_U3P_UIB_EEPM_EP_READY bit of  UIB->eepm_endpoint[0]  when this  bit stays at 0 all the time ?

Because when this bit is stuck to 0, whatever the timeout value is programmed there is no way to send something on EP0 IN.

How to retrieve the correct behavior after we are in this situation please ?

Thank you for your help.

Best regards

0 Likes
leda_289486
New Contributor II

Hi,

so what can we do if CY_U3P_UIB_EEPM_EP_READY  never happens after CyU3PDmaChannelSendData ? how to reset this situation ?

Is there a way to create case and have support ?

Thank you for your help.

Best Regards.

0 Likes
leda_289486
New Contributor II

Hi,

I'd like to have some explaination about this CY_U3P_UIB_EEPM_EP_READY bit behavior. Is there some documentation for this ? It is the key point of the encountered problem. What can cause this bit to stay forever at 0 ?? How to reset to correct behavior ? Why the out ep0 hasn't a similar problem ?

Thank you for your help,

Best Regards

0 Likes
KandlaguntaR_36
Moderator
Moderator

In your host application, you are doing BULK IN data transfer over EP3 (> 2 Gbps) and Vendor commands on EP0 IN.

When the error happens, please print the following register values:

   1. UIB->sck[0].status: 0xE004800C - 17:15 bits of register

   2. CY_U3P_UIB_EEPM_EP_READY:  0xE0031C40 - 30 bit of this register

Looks like you have checked the status of EEPM_EP_READY which is not ready.

Please check the 1 and 2 again this time.

How frequent you see this issue?

Can you please send a Zero Length packet instead of two bytes and see if there is timeout error?

Is it feasible to capture a USB trace either with software analyzer (Like USBLyzer) or hardware analyzer ( Like Lecroy)?

0 Likes
KandlaguntaR_36
Moderator
Moderator

We cannot directly write to CY_U3P_UIB_EEPM_EP_READY and can only read this register in the firmware. Hardware can only do read, write.

0 Likes
leda_289486
New Contributor II

Hi,

did you manage to read the usblyzer file ? What do you think about it ?

I have to switch to another process for 1 week since the current day, so if you'll answer next week, I'll make delayed answers.

Sorry for this, thank you for your help,

Best Regards

0 Likes
leda_289486
New Contributor II

By the way, I also test a change in size count : from 2 bytes to maximum 512 bytes at each eP0 in transfer.

Doesn't affect the observed behavior.

Best regards,

0 Likes
KandlaguntaR_36
Moderator
Moderator

As per the below code (copied from SDK 1.3.4 source code of CyU3PUsbSendEP0Data),

the while loop will exit after 500 ms delay and wait for CyU3PDmaChannelWaitForCompletion. If the DMAChannelWaitForComplettion time out for five times (5000 ms in total), then we go and reset the EP0 channel and flush the endpoint as well.

Please let me know what is the timeout for control Xfer you have set in the host application code.

Can you please set it as more than or equals to 5000 ms and check?

if (glUibDeviceInfo.ackPending != CyFalse)

        {

            uint32_t tmo = 500;     /* 500 ms delay is allowed. */

            while ((((UIB->sck[0].status & CY_U3P_UIB_STATE_MASK) >> CY_U3P_UIB_STATE_POS) != CY_U3P_UIB_STATE_ACTIVE) ||

                    ((UIB->eepm_endpoint[0] & CY_U3P_UIB_EEPM_EP_READY) == 0))

            {

                if (tmo == 0)

                {

                    /* If the socket and EP state have not changed even after 500 ms, try to go ahead and push the data

                       out. Errors from this transfer will be handled below.

                     */

                    break;

                }

                CyU3PThreadSleep (1);

                tmo--;

            }

            /* Clear the busy bit. */

            CyU3PUsbAckSetup ();

        }

0 Likes
leda_289486
New Contributor II

Hi,

thank you for this feedback. I'll try to proceed as you say.

In the host application code, the timeout was set to the maximum delay for an usb answer, ie 5000ms indeed.

However, you'll probably agree that 5s to send 2 bytes and triggers an error, there is a problem somewhere...

This delay is far far too long.

Furthermore when CY_U3P_UIB_EEPM_EP_READY bit is null, I guess the problem is not DMA but hardware in a maner of speaking.

Best Regards.

0 Likes
leda_289486
New Contributor II

Hi

I've checked out the code : the timeout is set to 100 ms BUT the problem is not the DMA completion, it is the CY_U3P_UIB_EEPM_EP_READY bit that is not set. Again 100ms to send 2 bytes, I think this is far sufficient for this kind of timeout.

Is there any mean to reset this "not ready situation" ? When you say "reset the channel EP0 and reset as well" are these operations done in CyU3PUsbSendEP0Data when tmo == 0 ? If this is it, this doesn't flush anything and the bit is still at "Not ready" after. Have you a reliable sequence for this?

Thank you for your help,

Best Regards.

0 Likes
leda_289486
New Contributor II

Hi,

any solution regarding the "hardware" not ready situation ?

Is there any means to reset this bit ?

Thank you for your help,

Best Regards.

0 Likes
KandlaguntaR_36
Moderator
Moderator

I am trying to find the solution for this.

Can you please let me know how did you confirm the CY_U3P_UIB_EEPM_EP_READY is set to 0?

0 Likes
leda_289486
New Contributor II

When the (tmo==0) error triggers, I've added a debugprint message inside SendEP0 routine to confirm.

As there are 2 possible conditions to trigger it, this is done to know which condition happens.

Nothing else changed. here the position of debugprint inside the original code.

Thank you for your help,

Best Regards.

        /* Wait until the DMA socket and EPM are in ready state. */

        while (

        (((UIB->sck[0].status & CY_U3P_UIB_STATE_MASK) >> CY_U3P_UIB_STATE_POS) != CY_U3P_UIB_STATE_ACTIVE)

        ||

                ((UIB->eepm_endpoint[0] & CY_U3P_UIB_EEPM_EP_READY) == 0)

               )

        {

            if (tmo == 0)

            {

                /* If the socket and EP state have not changed even after 500 ms, try to go ahead and push the data

                   out. Errors from this transfer will be handled below.

                 */

CyU3PDebugPrint(4, "\r\ntmo error 0x%x 0x%x - should be 0x%x 0x%x ",

    ((UIB->sck[0].status & CY_U3P_UIB_STATE_MASK) >> CY_U3P_UIB_STATE_POS), (UIB->eepm_endpoint[0] & CY_U3P_UIB_EEPM_EP_READY),CY_U3P_UIB_STATE_ACTIVE,CY_U3P_UIB_EEPM_EP_READY );

0 Likes
leda_289486
New Contributor II

Hi,

Have you look at the code including the error cause if imeout identifier ?

Is it Ok ?

Best Regards

0 Likes
leda_289486
New Contributor II

Hi,

have you checked the code ?

with it we can confirm that the timeout comes from the CY_U3P_UIB_EEPM_EP_READY part. It is set at 0 when this timeout condition triggers and cannot be resetted after.

Best Regards.

0 Likes
KandlaguntaR_36
Moderator
Moderator

I checked the code.

Thank you for the confirmation that the timeout comes from CY_U3P_UIB_EEPM_EP_READY.

0 Likes
leda_289486
New Contributor II

Hi,

have you a solution to try ? Even if this is not completly functionnal, I can test it.

This bit is telling us that hardware is not ready to send data on EP0. Is there a way to check that the endpoint 0 is still considered connected (functionnal) ? I've tried to use CyU3PUsbStart and CyU3PUsbStop to "force" a kind of connection when sendEP0 tmo error arrises but these functions don't work that way. If this exists (check working connection on EP) can I use it for all endpoints for debugging purposes ?

Best Regards

0 Likes
leda_289486
New Contributor II

Hi,

have you some solution to be tested for resetting the hardware bit preventing the EP0 in to work correctly ?

This is quite important, we must have a reliable EP0 feature, if not, we cannot control cameras correctly with CX3.

Thank you for your help,

Best Regards.

0 Likes
leda_289486
New Contributor II

Hi,

Have you some solution for this issue ? I would like to test some workarounds if possible. It has been near 14 days since previous answer.

Thank you for your help,

Best Regards

0 Likes
KandlaguntaR_36
Moderator
Moderator

Hello,

I can see the following in your code.

Please replace this part with the code below line (-----).

txApiRetStatus = VendorInterpreter(); // processing the command here. no EP0 handling in it

if (txApiRetStatus == CY_U3P_SUCCESS)

{

if ((setupReqType & 0x80) == 0x80)

{

txApiRetStatus = CyU3PUsbSendEP0Data(RequestedReturnSize, AnswerToPC); // direct answer

CyU3PUsbAckSetup(); // useful or not ???

}

else

{

CyU3PUsbAckSetup();

}

}

else

{

CyU3PUsbAckSetup();

if (ValidDebugMessage) CyU3PDebugPrint(4, "Bad return 0x%x\r\n", txApiRetStatus);

}

if (txApiRetStatus != CY_U3P_SUCCESS)

{

uint8_t ret2; //ret2,ret3,ret4;

CyU3PUsbSetEpNak(DEFINITION_OF_ZERO_EP, CyTrue);

CyU3PUsbResetEp(DEFINITION_OF_ZERO_EP);

CyU3PUsbFlushEp(DEFINITION_OF_ZERO_EP);

CyU3PBusyWait(100);

CyU3PUsbSetEpNak(CY_FX_EP_BULK_VIDEO, CyFalse);

ret2 = CyU3PUsbStall(DEFINITION_OF_ZERO_EP, CyTrue, CyTrue);

/* Error handling from EP0Send at this level. */

if (ValidDebugMessage) CyU3PDebugPrint(4, "\r\nError EP0 (0x%x - 0x%x) %d size = %d ret = %d ",

CopySetupDat0, CopySetupDat1, txApiRetStatus, RequestedReturnSize, ret2);

CyU3PTimerStart(&UvcTimer); // launch timer -> ClearFeaturefunction(0,0)

}

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

txApiRetStatus = VendorInterpreter(); // processing the command here. no EP0 handling in it

if (txApiRetStatus == CY_U3P_SUCCESS)

{

if ((setupReqType & 0x80) == 0x80)

     {

          txApiRetStatus = CyU3PUsbSendEP0Data(RequestedReturnSize, AnswerToPC); // direct answer

          if(txApiRetStatus != CY_U3P_SUCCESS)

              {

               /* There was some error. We should try stalling EP0. */

                CyU3PUsbStall(0, CyTrue, CyFalse);

               }

     }

else

     {

              CyU3PUsbAckSetup();

     }

}

else

{

     CyU3PUsbAckSetup();

     if (ValidDebugMessage) CyU3PDebugPrint(4, "Bad return 0x%x\r\n", txApiRetStatus);

}

if (txApiRetStatus != CY_U3P_SUCCESS)

{

uint8_t ret2; //ret2,ret3,ret4;

CyU3PUsbSetEpNak(DEFINITION_OF_ZERO_EP, CyTrue);

CyU3PUsbResetEp(DEFINITION_OF_ZERO_EP);

CyU3PUsbFlushEp(DEFINITION_OF_ZERO_EP);

CyU3PBusyWait(100);

CyU3PUsbSetEpNak(CY_FX_EP_BULK_VIDEO, CyFalse);

ret2 = CyU3PUsbStall(DEFINITION_OF_ZERO_EP, CyTrue, CyTrue);

/* Error handling from EP0Send at this level. */

if (ValidDebugMessage) CyU3PDebugPrint(4, "\r\nError EP0 (0x%x - 0x%x) %d size = %d ret = %d ",

CopySetupDat0, CopySetupDat1, txApiRetStatus, RequestedReturnSize, ret2);

CyU3PTimerStart(&UvcTimer); // launch timer -> ClearFeaturefunction(0,0)

}

0 Likes
leda_289486
New Contributor II

Hi

thank you for your feedback. I'll try the modification asap and I'll tell you the result.

Thank you for your help,

Best Regards.

0 Likes
leda_289486
New Contributor II

Hi,

as said, i've implemented your code.

However, there are still cases where the hardware error condition is triggered and when this happens, there is no way to retrieve correct behavior.

Can you propose a solution to clear this condition please ?

Thank you for your help,

Best Regards.

0 Likes
KandlaguntaR_36
Moderator
Moderator

We cannot clear the hardware error condition in the firmware.

It looks like you are not handling a few things in the firmware properly. Hence, it is hitting the error condition.


Do not call CyU3PUsbAckSetup(); after CyU3PUsbSendEP0Data API in all the cases in the firmware.

0 Likes
leda_289486
New Contributor II

Hi,

thank you for you answer. So when do we call CyU3PUsbAckSetup exactly ? our api framework is retrieved from cypress examples.

So you are telling me that when error is triggered, there is nothing we can do ? is there a way to reset hardware in this case : camera is supposed to be always active.

Best Regards,

0 Likes
leda_289486
New Contributor II

Hi,

I've checked out some code examples from cypress with SendEP0Data in it. For example, in cyfxlowpowertest, after the SendEP0Data, firmware calls a CyU3PUsbAckSetup procedure when ok and CyU3PUsbStall when a problem has arisen. So I'm quite confused with your sentence "Do not call CyU3PUsbAckSetup(); after CyU3PUsbSendEP0Data API in all the cases in the firmware". What does it mean precisely ?

What are the cases to be processed with a CyU3PUsbAckSetup exactly ?

Thank you for your help,

Best Regards

0 Likes