CyU3PDmaChannelSuspendUsbConsumer in FX3 SDK 1.3.4

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

cross mob
MiWa_2226056
Level 1
Level 1
First like given

Hi guys,

as discussed in some other threads, there is this issue with bulk IN and control IN transfers at USB 2.0 speed. This has been fixed in SDK 1.3.3 by suspending the other USB consumers until the control transfer is done. So far so good.

The release notes of brand-new SDK 1.3.4 now tell us that this time has been optimized:

Updated the CyU3PDmaChannelSuspendUsbConsumer() implementation to minimize the time for which other endpoints are halted while handling USB-HS control IN transfers.

We have a UVC application at USB 2.0 speed running. Sometimes we have to do EP0 control IN transfers while the video is streaming via a bulk IN endpoint. And with SDK 1.3.3 we measured roughly 21 ms until the whole EP0 request including CyU3PUsbSendEP0Data (which suspends the other endpoints) is done. I tried this with SDK 1.3.4 and got practically the same time. Those 20ms can sometimes corrupt my video stream due to buffer overruns while the data endpoint is suspended. I have a workaround for this, but of course I would prefer if the EP0 request would be faster.

My question is: What do you mean with "minimizing" the time? Should it be 10% faster or 10 times faster compared with SDK 1.3.3? And is 20 ms for a EP0 control IN request a reasonable time or do you expect it to be faster? In this case I would have to dig deeper in my code.

Best regards,

Michael

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

Hi Michael,

You can see the difference in the implementation of CyU3PDmaChannelSuspendUsbConsumer() in the SDK 1.3.4 vs 1.3.3. Specifically the following:

In SDK 1.3.4:

CyU3PReturnStatus_t

CyU3PDmaChannelSuspendUsbConsumer (CyU3PDmaChannel *handle, uint32_t         waitOption)

{

...

...

        if (((sck.status & CY_U3P_SUSPENDED) == 0) && (waitOption != CYU3P_NO_WAIT))

        {

            /* Convert waitOption value into 50 us units. */

            pollCnt = waitOption * 20;

            do {

                CyU3PThreadRelinquish ();

                CyU3PBusyWait (50);

                CyU3PDmaSocketGetConfig (handle->consSckId, &sck);

                if ((sck.status & CY_U3P_SUSPENDED) != 0)

                    break;

            } while (pollCnt--);

        }

...

...

}

whereas in SDK 1.3.3:

CyU3PReturnStatus_t

CyU3PDmaChannelSuspendUsbConsumer (CyU3PDmaChannel *handle, uint32_t         waitOption)

{

...

...

if (waitOption != CYU3P_NO_WAIT)

            {

                while (waitOption--)

                {

                    CyU3PDmaSocketGetConfig (handle->consSckId, &sck);

                    if ((sck.status & CY_U3P_SUSPENDED) != 0)

                        break;

                    CyU3PThreadSleep (1);

                }

            }

...

...

}

As you can notice, that after the socket is suspended, we take less time in exiting this function because of BusyWait implementation instead of ThreadSleep.

But the point here is that, the time taken for the socket to get suspended is not controlled here. What it depends on is: if there is data in the active buffer in the DMA channel whose socket is getting suspended, then how fast that data is taken out matters. If that is delayed then the suspend gets delayed.

So, Host should be taking that data over the Bulk endpoint quick enough.

So, you need to consider this point and check where exactly you are measuring the time ( the duration of 20mS that you have mentioned)

Regards,

Hemanth

Hemanth

View solution in original post

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

Hi Michael,

You can see the difference in the implementation of CyU3PDmaChannelSuspendUsbConsumer() in the SDK 1.3.4 vs 1.3.3. Specifically the following:

In SDK 1.3.4:

CyU3PReturnStatus_t

CyU3PDmaChannelSuspendUsbConsumer (CyU3PDmaChannel *handle, uint32_t         waitOption)

{

...

...

        if (((sck.status & CY_U3P_SUSPENDED) == 0) && (waitOption != CYU3P_NO_WAIT))

        {

            /* Convert waitOption value into 50 us units. */

            pollCnt = waitOption * 20;

            do {

                CyU3PThreadRelinquish ();

                CyU3PBusyWait (50);

                CyU3PDmaSocketGetConfig (handle->consSckId, &sck);

                if ((sck.status & CY_U3P_SUSPENDED) != 0)

                    break;

            } while (pollCnt--);

        }

...

...

}

whereas in SDK 1.3.3:

CyU3PReturnStatus_t

CyU3PDmaChannelSuspendUsbConsumer (CyU3PDmaChannel *handle, uint32_t         waitOption)

{

...

...

if (waitOption != CYU3P_NO_WAIT)

            {

                while (waitOption--)

                {

                    CyU3PDmaSocketGetConfig (handle->consSckId, &sck);

                    if ((sck.status & CY_U3P_SUSPENDED) != 0)

                        break;

                    CyU3PThreadSleep (1);

                }

            }

...

...

}

As you can notice, that after the socket is suspended, we take less time in exiting this function because of BusyWait implementation instead of ThreadSleep.

But the point here is that, the time taken for the socket to get suspended is not controlled here. What it depends on is: if there is data in the active buffer in the DMA channel whose socket is getting suspended, then how fast that data is taken out matters. If that is delayed then the suspend gets delayed.

So, Host should be taking that data over the Bulk endpoint quick enough.

So, you need to consider this point and check where exactly you are measuring the time ( the duration of 20mS that you have mentioned)

Regards,

Hemanth

Hemanth
0 Likes