cancel
Showing results for 
Search instead for 
Did you mean: 

USB Superspeed Peripherals

samhe
New Contributor

Hi

I experience an FX3 EP_IN data transfer stop problem. Our design is based on the uvc_cdc example design.

UVC channel is auto_many_to_one DMA, the setting is:

dmaMultiConfig.size = 16384;
dmaMultiConfig.count = 4;
dmaMultiConfig.validSckCount = 2;
dmaMultiConfig.prodSckId [0] = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_0;
dmaMultiConfig.prodSckId [1] = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_1;
dmaMultiConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaMultiConfig.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT;

dmaMultiConfig.consSckId [0] = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_0 | CY_FX_SOCKET_UVC);
dmaMultiConfig.prodAvailCount = 0;
dmaMultiConfig.prodHeader = 0; /* 0 byte UVC header to be added. */
dmaMultiConfig.prodFooter = 0; /* 0 byte footer to compensate for the 12 byte header. */
dmaMultiConfig.consHeader = 0;
dmaMultiConfig.cb = CyFxUvcDmaCallback; /* use Capture mode's DMA callback */

apiRetStatus = CyU3PDmaMultiChannelCreate (&glChHandleUVCStream,
CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE,
&dmaMultiConfig);

 

CDC channel is manual DMA, the setting is:

/* Create a DMA_MANUAL channel between UART producer socket and USB consumer socket
* Use a smaller buffer size (32 bytes) to ensure that packets get filled in a short time.
*/
dmaCfg.size = 32;
dmaCfg.count = 32;
dmaCfg.prodSckId = (CyU3PDmaSocketId_t)(CY_U3P_LPP_SOCKET_UART_PROD);
dmaCfg.consSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_0 | CY_FX_SOCKET_CDC);
dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;
dmaCfg.cb = CyFxUART2USBDmaCallback;

apiRetStatus = CyU3PDmaChannelCreate (&glChHandleUarttoUsb,CY_U3P_DMA_TYPE_MANUAL, &dmaCfg);

 

Test setting is:

An app from host PC connect with FPGA through CDC channel. This app enable FPGA to generate UVC traffic, after this the app doing nothing, so there is no traffic flow on CDC channel.

Window "Camera" play video FPGA generated (sent to host PC through UVC channel). The rate is about 320M Bytes per second (90% of GPIF bus bandwidth)

The traffic stop is random, some time in a few minute, sometime a few hours, most time never happens. I am able to reproduce this problem by adding 4 hubs between host PC and device. 

Most time when UVC traffic stop, CDC upstream traffic stop as well, CDC downstream traffic is still ok.

If I build FX3 firmware with SDK1.3.3, I can resume CDC upstream traffic by close and re-open host PC app(close and open uart port). UVC traffic can be recovered by changing video channel (in side FX3, uvc related endpiont and DMA channel will be deleted and re-created).

If I build FX3 firmware with SDK1.3.4, this problem will happen much much less often, but once happens, host PC apps freeze, I have to unplug USB cable to close apps, but in one time after about 20 seconds, CDC and UVC channel recovered by itself.

I used a USB analyser to capture traffic to and from FX3, there is no CRC error, the traffic stop is because FX3 send a NRDY transaction packet to host PC (there is no ERDY transaction packet send out by FX3 after NRDY)

Following is a screen shot of some captured data, there are about 30 to 50 unexpected transaction (in class view of usb analyzer) before NRDY, but they look the same as those good one.

fx3_IN_EP_stop.PNG

Any one has any idea about this please give me a help, Thanks! 

0 Likes
1 Solution
Rashi_Vatsa
Moderator
Moderator

Hello Sam,

From the tests we see that CYU3P_USBEP_SS_RESET_EVT is triggered after some retry events. This happens if FX3 is operating on a USB 3.0 link with poor signal quality, and there are a
number of protocol level CRC errors and retries happening.

Please refer to part IV of section 2.3 of the FX3 SDK Troubleshooting Guide of the FX3 SDK. follow the workaround provided in the GPIFtoUSB example of the SDK to recover from the error.

Workaround

- Stall the endpoint when CYU3P_USBEP_SS_RESET_EVT is received

- The host is expected to send Clear feature request on seeing the stalled endpoint

- The clear feature request (from the host) needs to be handled in the firmware as done in GpifToUSB example.

You can try using USB IF certified good USB cable between the fx3 and host to reduce the link errors.

Please let me know if the device recovers automatically after the workaround is implemented in the firmware (SDK 1.3.4)

Regards,
Rashi

View solution in original post

0 Likes
16 Replies
Rashi_Vatsa
Moderator
Moderator

Hello,

Please find my comments below:

I used a USB analyser to capture traffic to and from FX3, there is no CRC error, the traffic stop is because FX3 send a NRDY transaction packet to host PC (there is no ERDY transaction packet send out by FX3 after NRDY)

>>Please let me know the following:

- Can the firmware be modified to change the UVC channel to MANUAL mode so that we can track the DMA buffers and check the status when the issue is seen.

- Is the issue seen when the device is directly connected to the host (without hubs)

- Please let me know if the issue is seen with different  PCs

Also, share the complete USB traces  captured when issue is seen. This will help us to debug the issue.

Regards,
Rashi
0 Likes
samhe
New Contributor

Hi Rashi,

Thank you for your reply.

1. I changed UVC channel to manual DMA mode, I can't produce the problem in my test environment in one hour. If it is auto DMA mode, the problem can occur in 10 minutes most time, sometime the problem won't occur. Manual DMA mode, the video throughput is about 2.4Gbit, auto DMA mode the video throughput is about 3.0Gbit.

2. I connected the device direct to host PC, the problem did not occur in one hour.

Our device is a high speed camera, it connect to host PC through two hub in an equipment. I haven't seen this problem when I test the camera independently (no hub involved), we picked up this problem when we did life cycle test to our equipment. Actually it is very hard to re-produce the problem at the beginning, I only able to re-produce it after add a extra hubs. 

3. The problem was seen with different PCs

4. Please find attached captured data. I use Total Phase's Beagle USB 5000 SuperSpeed Protocol Analyzer captured this data. You can download their DataCenter software to read this data set.

5. The key point of this problem is both CDC and UVC IN endpoint stop (both send out a NRDY) even though there is only UVC traffic at the time of testing. I delete CDC channel and the problem also occurred.  

UVC traffic resume by switch video channel, inside FX3 the actions are :

/*
*
*/
void
CyFxUvcStop()
{
/* Disable the GPIF state machine. */
CyU3PGpifDisable (CyFalse);

/* Place the EP in NAK mode before cleaning up the pipe. */
CyU3PUsbSetEpNak (CY_FX_EP_UVC_CONS, CyTrue);
CyU3PBusyWait (125);

/* Reset and flush the endpoint pipe. */
CyU3PDmaMultiChannelReset (&glChHandleUVCStream);
CyU3PUsbFlushEp (CY_FX_EP_UVC_CONS);
CyU3PUsbSetEpNak (CY_FX_EP_UVC_CONS, CyFalse);
CyU3PBusyWait (125);

}

/*
*
*/
void
CyFxCdcStart()
{
CyU3PReturnStatus_t apiRetStatus;

/* Make sure we return to an active USB link state and stay there. */
CyU3PUsbLPMDisable ();
if (CyU3PUsbGetSpeed () == CY_U3P_SUPER_SPEED)
{
CyU3PUsbSetLinkPowerState (CyU3PUsbLPM_U0);
CyU3PBusyWait (200);
}
else
{
CyU3PUsb2Resume ();
}

/* Place the EP in NAK mode before cleaning up the pipe. */
CyU3PUsbSetEpNak (CY_FX_EP_CDC_IRQ_CONS, CyTrue);
CyU3PUsbSetEpNak (CY_FX_EP_CDC_CONS, CyTrue);
CyU3PUsbSetEpNak (CY_FX_EP_CDC_PROD, CyTrue);
CyU3PBusyWait (125);

/* Reset and flush the endpoint pipe. */
CyU3PUsbFlushEp (CY_FX_EP_CDC_IRQ_CONS);
CyU3PUsbFlushEp (CY_FX_EP_CDC_CONS);
CyU3PUsbFlushEp (CY_FX_EP_CDC_PROD);


CyU3PDmaChannelReset (&glChHandleUsbtoUart);
CyU3PDmaChannelReset (&glChHandleUsbtoUartB);
CyU3PDmaChannelReset (&glChHandleUarttoUsb);

/* Set DMA Channel transfer size, first producer socket */
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleUsbtoUart, 0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyFxAppErrorHandler (apiRetStatus);
}

apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleUarttoUsb, 0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyFxAppErrorHandler (apiRetStatus);
}

CyU3PUsbSetEpNak (CY_FX_EP_CDC_IRQ_CONS, CyFalse);
CyU3PUsbSetEpNak (CY_FX_EP_CDC_CONS, CyFalse);
CyU3PUsbSetEpNak (CY_FX_EP_CDC_PROD, CyFalse);
CyU3PBusyWait (125);

}

 

Thanks!

0 Likes
samhe
New Contributor

Hi Rashi:

Sorry, I paste a wrong piece of code in above code. It is CyFxUvcStart not CyFxCdcStart is called. 

void
CyFxUvcStart()
{
CyU3PReturnStatus_t apiRetStatus;

/* Make sure we return to an active USB link state and stay there. */
CyU3PUsbLPMDisable ();
if (CyU3PUsbGetSpeed () == CY_U3P_SUPER_SPEED)
{
CyU3PUsbSetLinkPowerState (CyU3PUsbLPM_U0);
CyU3PBusyWait (200);
}
else
{
CyU3PUsb2Resume ();
}

/* Place the EP in NAK mode before cleaning up the pipe. */
CyU3PUsbSetEpNak (CY_FX_EP_UVC_CONS, CyTrue);
CyU3PBusyWait (125);

/* Reset and flush the endpoint pipe. */
CyU3PUsbFlushEp (CY_FX_EP_UVC_CONS);
CyU3PDmaMultiChannelReset (&glChHandleUVCStream);

/* Set DMA Channel transfer size */
apiRetStatus = CyU3PDmaMultiChannelSetXfer (&glChHandleUVCStream, 0, 0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyFxAppErrorHandler (apiRetStatus);
}

CyU3PUsbSetEpNak (CY_FX_EP_UVC_CONS, CyFalse);
CyU3PBusyWait (125);

/* Start the state machine from the designated start state. */
apiRetStatus = CyU3PGpifSMSwitch(CY_FX_UVC_INVALID_GPIF_STATE,
START_SCK0,
CY_FX_UVC_INVALID_GPIF_STATE,
ALPHA_START_SCK0,
CY_FX_UVC_GPIF_SWITCH_TIMEOUT);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyFxAppErrorHandler (apiRetStatus);
}


}

0 Likes
Rashi_Vatsa
Moderator
Moderator

Hello,

Thank you for the details.

From the traces I see that ACK with sequence number 9 is sent twice by the host after which there errors seen.

Please let me know if any endpoint related errors are handled from the firmware.

To know the reason for both endpoints to stop please print the USB logs in the firmware and also check for endpoint errors.

- For USB logs, you can refer to bulksrcsink firmware of the SDK which uses CyU3PUsbInitEventLog/CyU3PUsbGetEventLogIndex for getting the USB logs.

- Also register for CyU3PUsbRegisterEpEvtCallback and let me know if there are any endpoint errors seen

- Please call CyU3PUsbGetErrorCounts API to check the number of USB 3.0 PHY and LINK error counts detected by FX3

Please share the UART debug prints for us to check usb logs

Regards,
Rashi
0 Likes
samhe
New Contributor

Hi Rashi,

Thanks for your help.

I added following your proposal to my fx3 design

/* Register a buffer into which the USB driver can log relevant events. */
gl_UsbLogBuffer = (uint8_t *)CyU3PDmaBufferAlloc (CYFX_USBLOG_SIZE);
if (gl_UsbLogBuffer)
CyU3PUsbInitEventLog (gl_UsbLogBuffer, CYFX_USBLOG_SIZE);


/*register endpoint event call, endpoint 4 is used by UVC, endpoint6 is used by CDC */

CyU3PUsbRegisterEpEvtCallback (CyFxApplnEpCallback, 0x000001B0, 0x0040, 0x0050);

CyFxApplnEpCallback (
CyU3PUsbEpEvtType evtype,
CyU3PUSBSpeed_t usbSpeed,
uint8_t epNum)
{
if (epNum == CY_FX_EP_UVC_CONS)
{
if (evtype == CYU3P_USBEP_SS_RESET_EVT)
{
UvcConsEpEvtCount[0]++;
}
else if (evtype == CYU3P_USBEP_SS_BTERM_EVT)
{
UvcConsEpEvtCount[1]++;
}
else if (evtype == CYU3P_USBEP_SS_STREAMERR_EVT)
{
UvcConsEpEvtCount[2]++;
}
else if (evtype == CYU3P_USBEP_SS_SEQERR_EVT)
{
UvcConsEpEvtCount[3]++;
}
else if (evtype == CYU3P_USBEP_SS_RETRY_EVT)
{
UvcConsEpEvtCount[4]++;
}
}

if (epNum == CY_FX_EP_CDC_CONS)
{
....
}

CyU3PEventSet (&glFxEvent, CY_FX_EP_EVENT, CYU3P_EVENT_OR);
}


/* If there is a registed event, send debug info to FPGA buffer */
if ((CY_FX_EP_EVENT) != 0)
{
....

 

Test is done by:
1) Running UVC traffic until it stops, read UVC/CDC endpoint event count, read phy_err_cnt/lnk_err_cnt, read log
2) Ressume UVC traffic by switch video channel, wait until UVC traffic stops, do reading,
3) Repeat 2)
4) Repeat 2)

** For SDK1.3.3

Every time UVC traffic stop:
1) there is one UVC endpoint reset event
2) Reading of 5 elements of phy_err_cnt pointer are: 0x0000, 0xefef, 0x0000, 0x0000, 0x0000
Reading of 6 elements of lnk_err_cnt pointer are: 0x0000, 0x4006, 0x001b, 0x1000, 0x000a, 0x0000, 0x0000,
Note: phy_err_cnt[0] is not 0 first time call to CyU3PUsbGetErrorCounts(phy_err_cnt,lnk_err_cnt), after first call, all other reading are the same as above.
3) log reading
The 2nd time UVC traffic stop: 0x06, 0x12, 0x25, 0x26, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, ...
The 3rd time UVC traffic stop: 0x06, 0x12, 0x25, 0x26, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, ...
The 4th time UVC traffic stop: 0x06, 0x12, 0x25, 0x26, 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, ...


** For SDK1.3.4

Every time UVC traffic stop:
1) there is one UVC endpoint reset event, and a few UVC endpoint retry event.
2) Reading of 5 elements of phy_err_cnt pointer are: 0x0000, 0xefef, 0x0000, 0x0000, 0x0000
Reading of 7 elements of lnk_err_cnt pointer are: 0x0000, 0x4006, 0x001b, 0x1000, 0x000a, 0x0000, 0x0000,
Note: phy_err_cnt[0] is not 0 first and second time call to CyU3PUsbGetErrorCounts(phy_err_cnt,lnk_err_cnt), after that, all other reading (50 endpoint events) are the same as above.
3) log reading
The 2nd time UVC traffic stop:
0x06 0x12 0x25 0x26 0x17 0xAB 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0x17 0xAB
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

The 3rd time UVC traffic stop:
0x06 0x12 0x25 0x26 0x17 0xAB 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0x17 0xAB
0xAB 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

The 4th time UVC traffic stop:
0x06 0x12 0x25 0x26 0x17 0xAB 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0xAE 0x11
0x25 0x26 0xAE 0x11 0x25 0x26 0x17 0xAB
0xAB 0xAB 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

 

 

Regards,

Sam

0 Likes
samhe
New Contributor

Hi Rashi,

Extra information:

After UVC/CDC traffic stop,  UVC traffic can be resumed by switch video channel and CDC traffic can be resumed by reconnect uart port. I just confirmed that they resume not because of user code ( CyFxUvcStop, CyFxUvcStart), is most likely because of host sending "Clear Endpoint Feature" and "Control Transfer" on endpoint 0 to the device.

Regards,

sam

0 Likes
Rashi_Vatsa
Moderator
Moderator

Hello Sam,

From the tests we see that CYU3P_USBEP_SS_RESET_EVT is triggered after some retry events. This happens if FX3 is operating on a USB 3.0 link with poor signal quality, and there are a
number of protocol level CRC errors and retries happening.

Please refer to part IV of section 2.3 of the FX3 SDK Troubleshooting Guide of the FX3 SDK. follow the workaround provided in the GPIFtoUSB example of the SDK to recover from the error.

Workaround

- Stall the endpoint when CYU3P_USBEP_SS_RESET_EVT is received

- The host is expected to send Clear feature request on seeing the stalled endpoint

- The clear feature request (from the host) needs to be handled in the firmware as done in GpifToUSB example.

You can try using USB IF certified good USB cable between the fx3 and host to reduce the link errors.

Please let me know if the device recovers automatically after the workaround is implemented in the firmware (SDK 1.3.4)

Regards,
Rashi

View solution in original post

0 Likes
samhe
New Contributor

Hi Rashi,

I haven't got time to implement above your workaround, will let you know once I have it done and test.

I have a question about CyU3PUsbGetErrorCounts(phy_err_cnt,lnk_err_cnt), according to briefing of this function,

 phy_err_cnt point to counters of

  • 8b/10b Decode errors.
  • Elastic buffer overflow/underflow errors.
  • CRC errors.
  • Training sequence errors.
  • PHY lock loss.

lnk_err_cnt point to counter of :

  • Link credit timeout.
  • Missing LGOOD_x / LCRD_x error.
  • Tx/Rx header sequence number errors.
  • Link power management timeout (missing LAU/LXU).\n
  • Link header sequence number / credit advertisement timeout.\n
  • Link header or LGO_x received before sequence number / credit advertisement.

These counters are cleared after they are read. In my test, not all of them are cleared after read. Following items always read back following value:

  • phy_err_cnt [1] = 0xefef
  • lnk_err_cnt[1] = 0x4006
  • lnk_err_cnt[2] = 0x001b
  • lnk_err_cnt[3] = 0x1000
  • lnk_err_cnt[4] = 0x000a

Can you please let me know why?

 

Thanks!

sam

0 Likes
Rashi_Vatsa
Moderator
Moderator

Hello Sam,

I haven't got time to implement above your workaround, will let you know once I have it done and test.

>> Okay

These counters are cleared after they are read. In my test, not all of them are cleared after read. 

>> Yes, both error counts are cleared to zero whenever a query is performed.

You can check this in API implementation.

Following items always read back following value

>>Do you mean every time the error counts are read it is always in the same sequence as shared?

If yes, can you share code so that we can understand where and how is the API called. 

Regards,
Rashi
0 Likes
samhe
New Contributor

Hi Rashi,

An endpoint event flag CY_FX_EP_EVENT is raised in CyFxApplnEpCallback () when there is an CYU3P_USBEP_SS_RESET_EVT. CyU3PUsbGetErrorCounts( ) is called when CY_FX_EP_EVENT is handled in UvcAppThread_Entry ( ). I only noticed that phy_err_cnt[0] is cleared when CyU3PUsbGetErrorCounts() is called.

CyFxApplnEpCallback (
CyU3PUsbEpEvtType evtype,
CyU3PUSBSpeed_t usbSpeed,
uint8_t epNum)
{
if (epNum == CY_FX_EP_UVC_CONS)
{
if (evtype == CYU3P_USBEP_SS_RESET_EVT)
{
UvcConsEpEvtCount[0]++;
}
else if (evtype == CYU3P_USBEP_SS_BTERM_EVT)
{
UvcConsEpEvtCount[1]++;
}
else if (evtype == CYU3P_USBEP_SS_STREAMERR_EVT)
{
UvcConsEpEvtCount[2]++;
}
else if (evtype == CYU3P_USBEP_SS_SEQERR_EVT)
{
UvcConsEpEvtCount[3]++;
}
else if (evtype == CYU3P_USBEP_SS_RETRY_EVT)
{
UvcConsEpEvtCount[4]++;
}
}

if (epNum == CY_FX_EP_CDC_CONS)
{
if (evtype == CYU3P_USBEP_SS_RESET_EVT)
{
CdcConsEpEvtCount[0]++;
}
else if (evtype == CYU3P_USBEP_SS_BTERM_EVT)
{
CdcConsEpEvtCount[1]++;
}
else if (evtype == CYU3P_USBEP_SS_STREAMERR_EVT)
{
CdcConsEpEvtCount[2]++;
}
else if (evtype == CYU3P_USBEP_SS_SEQERR_EVT)
{
CdcConsEpEvtCount[3]++;
}
else if (evtype == CYU3P_USBEP_SS_RETRY_EVT)
{
CdcConsEpEvtCount[4]++;
}
}

// if (evtype == CYU3P_USBEP_SS_RESET_EVT)
// {
// if (epNum == CY_FX_EP_UVC_CONS)
// {
// CyU3PUsbStall (CY_FX_EP_UVC_CONS, CyTrue, CyFalse);
// }
// if (epNum == CY_FX_EP_CDC_CONS)
// {
// CyU3PUsbStall (CY_FX_EP_CDC_CONS, CyTrue, CyFalse);
// }
// }

if (evtype == CYU3P_USBEP_SS_RESET_EVT)
{
CyU3PEventSet (&glFxEvent, CY_FX_EP_EVENT, CYU3P_EVENT_OR);
}
}

 

UvcAppThread_Entry (
uint32_t input)
{
//
.....
//
int ep_event_count = 0;
for (;;)
{
apiRetStatus = CyU3PEventGet (&glFxEvent, CY_FX_USB_SUSPEND_EVENT_HANDLER |
CY_FX_DEBUG_CMD_CFG_EVENT |
CY_FX_UVC_DMA_RESET_EVENT |
CY_FX_UVC_STREAM_EVENT |
CY_FX_UVC_STREAM_EVENT_B |
CY_FX_CDC_STREAM_EVENT |
CY_FX_ALL_STREAM_ABORT_EVENT |
CY_FX_UVC_STREAM_ABORT_EVENT |
CY_FX_CDC_STREAM_ABORT_EVENT |
CY_FX_DEBUG_STREAM_ABORT_EVENT |
CY_FX_CDC_USB2UART_DMA_CB_EVENT |
CY_FX_GPIF_BUS_CHK_EVENT |
CY_FX_EP_EVENT ,
CYU3P_EVENT_OR_CLEAR,
&flag, LOOP_TIMEOUT);

if (apiRetStatus == CY_U3P_SUCCESS)
{
//[sh:f2]
if ((flag & CY_FX_EP_EVENT) != 0)
{
//
uint32_t address = 0x5004000;
for (int i=0; i<5; i++)
{
FPGAControl_registerWrite(address + i ,UvcConsEpEvtCount[i]);
}
address = 0x5004008;
for (int i=0; i<5; i++)
{
FPGAControl_registerWrite(address + i ,CdcConsEpEvtCount[i]);
}

//
uint16_t phy_err_cnt[8];
uint16_t lnk_err_cnt[8];
CyU3PUsbGetErrorCounts(phy_err_cnt,lnk_err_cnt);

address = 0x5005000 + 0x10*ep_event_count;
for (int i=0; i<8; i++)
{
FPGAControl_registerWrite(address + i, phy_err_cnt[i]);
}

address = 0x5005008 + 0x10*ep_event_count;
for (int i=0; i<8; i++)
{
FPGAControl_registerWrite(address + i, lnk_err_cnt[i]);
}

//
address = 0x5006000;
for (int i=0; i<CYFX_USBLOG_SIZE; i++)
{
FPGAControl_registerWrite(address + i ,gl_UsbLogBuffer[i]);
}

//
address = 0x5004010;
FPGAControl_registerWrite(address,ep_event_count);
if (ep_event_count < 50) ep_event_count ++;
}

0 Likes
samhe
New Contributor

Hi Raish,

[Your Question] Do you mean every time the error counts are read it is always in the same sequence as shared?

Yes.

 

Regards

Sam

 

0 Likes
Rashi_Vatsa
Moderator
Moderator

Hello,

I only noticed that phy_err_cnt[0] is cleared when CyU3PUsbGetErrorCounts() is called.

>> uint16_t bit variable needs to be passed to   CyU3PUsbGetErrorCounts API

CyU3PReturnStatus_t
CyU3PUsbGetErrorCounts (
uint16_t *phy_err_cnt, /**< Return parameter to be filled with phy error count. */
uint16_t *lnk_err_cnt /**< Return parameter to be filled with link error count. */
);

From the code snippet I noticed that array of uint16_t is passed to the API, i.e. is the reason that only element 0 of the array holds the actual values of the phy and link error.

You can try this

for(i=0; i<8; i++)

CyU3PUsbGetErrorCounts(phy_err_cnt[i],lnk_err_cnt[i]);

Regards,
Rashi
0 Likes
samhe
New Contributor

Hi Rashi,

1) CyU3PUsbGetErrorCounts () need two uint16_t type pointers as argument. I pass two unit16_t array when I call this function, I think I call this function correctly. Your proposal will cause compiler issues an warning.

2) As I haven't seen any CRC error on USB analyser when traffic stop, I will need these counters to give me information about what happens inside FX3.

Regards,

Sam

0 Likes
Rashi_Vatsa
Moderator
Moderator

Hello,

Please refer to this KBA  PHY Errors in FX3 - KBA225226 - Cypress Developer Community with similar implementation. 

You can pass a uint16_t variable (not array) to the API and then store the returned value in the array and use in the rest of the code. Please let me know if this works.

or You can try the code snippet attached. The code can be compiled successfully.

Regards,
Rashi
0 Likes
samhe
New Contributor

Hi Rashi,

Thank you very much for your support.

1) CyU3PUsbGetErrorCounts() works and phy_err_cnt and lin_err_cnt can be cleared after they are read. I misunderstood the briefing of API CyU3PUsbGetErrorCounts(uint16_t *phy_err_cnt, uint16_t *lnk_err_cnt). phy_err_cnt points to one counter which will count when there is an PHY error of 8b/10b decode error, or CRC error, or ..., not five counters of each PHY error type.

2) So in my test setup (many to one auto DMA UVC channel, maximum data rate, 3 hubs between FX3 and host PC, FX3 SDK 1.3.4), when both UVC/CDC IN lockup, there is no any physical layer and link layer error. Most time when UVC/CDC IN lockup, there is an end point reset event raised on UVC IN endpoint and both UVC/CDC channel can be recovered by the method you recommended. But during two weeks test period, two times I had only UVC lockup but there is no end point reset event raised, when this occurred FX3 stuck at always send Nready to host when host try to talk to it. I have to implement UVC traffic monitoring in addition of usb endpoint call back event, I think the stall recovery method you recommended will work on this situation as well but I haven't verified it as I have not reproduced this lockup after I implemented UVC traffic monitoring.

 

0 Likes
Rashi_Vatsa
Moderator
Moderator

Hello,

Thank you for the confirmation that the workaround works for UVC/CDC.

But during two weeks test period, two times I had only UVC lockup but there is no end point reset event raised, when this occurred FX3 stuck at always send Nready to host when host try to talk to it.

>> Please share the UART debug prints which prints the USB logs as shared earlier.

 

 I have to implement UVC traffic monitoring in addition of usb endpoint call back event, I think the stall recovery method you recommended will work on this situation as well but I haven't verified it as I have not reproduced this lockup after I implemented UVC traffic monitoring.

>> Please explain meaning of "UVC traffic monitoring in addition of USB endpoint call back event". Let me know the changes done to the firmware

Regards,
Rashi
0 Likes