Can you please post the snippet where exactly you have called CyU3PGpifGetSMState API in your code?
This is because of the presence of mirror states in the CX3 state machine. Please refer section 4.5.1 " Mirror states" of gpif2_designer_userguide for more details about mirror states.
thank you for this document and precision.
I'd like to precise some point on CX3 :
We can have data flux streaming during hours correctly at more the 1 Gbit/s typical. However, sometimes we observed a 0xC0000001 IRP return from camera in driver and streaming is stopped (no more answer on video endpoint because no more answer from CX3). Have you a code snippet for firmware after this particular situation ? others endpoints such are EP0 are answering correctly.
We have also sometimes another issue, related to previous one. After stopping flux completly because of previous issue, we restart and then frames are corrupted as if the dma buffers run with bad socket : Is there a way to reset socket and buffers of CX3 between two frames to restart always on same socket and a way to "clean" all buffers (producers+consumer) between two frames after all dma+Usb transfers are done (and of course before new data incoming from sensor) ?
Thank you for your help,
Can you please check the section IV USB Data Corruption (Page #8) in FX3_SDK_TroubleShooting_Guide.PDF (attached for reference) and implement the work around?
Refer GpifToUsb example firmware for the implementation.
Put a flag in USBEP_SS_RESET_EVT and print it in the infinite for loop.
I am trying to know whether there is SS_RESET_EVT in your case. If yes, we can reset the endpioints and DMA channel over a Clear Feature request.
this implementation doesn't change the behavior : it is never triggered so I guess this mean the usb 3 signal is rather correct.
Here is the situation : for some reason it happens that there is no more transfers because consumer socket is stuck whereas producer is present but of course buffers are very quickly full.
Is there a way to clean correctly all buffers from producer and consumer point of view so that transfers can happen again without stopping from driver ?
I think the problem is really in firmware part because I see the IRP request from driver that is not satisfied and no other transfer after that is satisfied.
Again this is quite rare but painful. For example, streaming @ 1.7 Gbits/s all week-end with no error.
I've tried everything to restart flux when driver receives an 0xC0000001 answer (and nothing else after) from CX3 to an IRP. We have a 4 producer buffers configuration (2 sockets, 2 buffers each). Each time we aren't able to restart consumer socket correct handling and the only way is to stop/restart flux from driver side which is not a correct solution.
In firmware, we are detecting correctly the situation after few ms. We are trying to reset the sockets to restart flux but if this seems to work for producer sockets this never works for consumer socket : what can prevent the consumer to restart on firmware side ?
Thank you for your help.
I also have implemented the usb log debug feature. When streaming normal, I've got no message at all.
Once it is stalled i have :
DEBUG LOG : AF
DEBUG LOG : AF
DEBUG LOG : AB
DEBUG LOG : AB
Hope this can help.
I confirm the debug log behavior.
Each time streaming is stopped, I've got these messages.
Sometimes there is only one DEBUG LOG : AF but always DEBUG LOG AF and then DEBUG LOG AB.
Is there a document to explain what this means exactly ?
Thank you for your help,
here is the snippet code form USBBulkSourceSink example.
/* Compare the current USB driver log index against the previous value. */
if (gl_UsbLogBuffer == NULL)
tmp1 = CyU3PUsbGetEventLogIndex ();
if (tmp1 != prevUsbLogIndex)
tmp2 = prevUsbLogIndex;
while (tmp2 != tmp1)
CyU3PDebugPrint (4, "DEBUG LOG: %x\r\n", gl_UsbLogBuffer[tmp2]);
if (tmp2 == CYFX_USBLOG_SIZE)
tmp2 = 0;
/* Store the current log index. */
prevUsbLogIndex = tmp1;
The log 0xAF corresponds to CYU3P_USB_LOG_EP_UNDERRUN and 0xAB corresponds to CYU3P_USB_LOG_EPM_RESET.
EP underruns happen when the DMA channel is suddenly reset just when the PC asks for data. The USB controller will then receive conflicting information on buffer availability and an underrun is reported.
- Can you check if you do any DMA channel resets in your code (other than the clear_feature reset)? Also, do you see this underrun reported in USB 2 only or in USB 3 too?
- Can you please share your firmware?
In order to over come the Underrun error kindly follow the following code .
When you get a UNDERRUN in the call back , set a flag in the call back . In your main thread check for this flag and if the flag is set the reset the end point memory , DMA channel and starting the transfer again . The following line of code does the same .
CyU3PUsbSetEpNak(ep,1); // NAK the USB transfers until your endpoint memory is ready to recive
CyU3PDmaChannelReset(&gDmaCh); // Reset the DMA buffer to reset the pointer
CyU3PUsbGetEpSeqNum(ep,&seq); // Continue with the Old sequence number
CyU3PUsbResetEndpointMemories() // This API is used to reset reset and re-initialize the memory block, so that USB data transfers can resume.
CyU3PDmaChannelSetXfer(&gDmaCht,0); // Start the transfer again
CyU3PUsbSetEpNak(ep,0); // Remove the NAK to start USB transfers again.
Let us know if you are still facing any issue.
thank you for this information.
For the first point, I've logged with DebugPrint every dmareset places. It is not called while this condition is triggered.
I can send parts of firmware but not all.
I've included the flag detection while underrun comes. I include your code, check and tell the results.
thank you for your help,
I confirm that firmware doesn't call dmaMultiChannelReset while streaming. By the way it is a multichannel many_to_one configuration, so I used the corresponding function ("multi") for SetXfer and channel reset.
But the issue is still present : the callback is triggered with an CY_U3P_USB_EVENT_EP_UNDERRUN event from endpoint 0x83 but the code doesn't "unblock" the situation : no transfer after.
Thank you for you help