Whe you say USB layer breaks down, what is teh behaviour seen? Please detail the same so that we can try to reproduce that here and test.
By endpoint configuration with isoPkts = 1, FX3 starts sending packets with 1 packet/ microframe, until isoPkts is set back to higher values. If endpoint configuration can be done more fastly by writing to the endpoint configuration register directly. We have tried that out here, and could not see any issues. One more point that I would like to bring to notice is that this issue exists only for USB 2.0 ISO transfers, and not in USB 3.0 with FX3. In case, you are using USB 2.0 ISO transfers with FX3 and facing such issues, endpoint reconfiguration with proper isoPkts value should do the job I think. Please let us know if are facing any issues in this.
When I call the CyU3PSetEpConfig() to reconfigure just the ISO IN endpoint (3) while streaming then ALL endpoints stops working and Windows cannot connect anylonger, this is what I ment by "USB layer breaks down".
This means that the function has some side effects or I am not allowed to call it in the CyFxDMACallback() function.
How do I reconfigure the isoPkt value for end point 3 directly (by writing to a register) ? I don't have any documentation for the registers.
Yes, you have guessed correctly we only use USB 2.0 highspeed.
My goal was to change the isoPkt right after a USB ISO package has been transferred, this should give me sufficent time to reconfigure.
But for some reason my subscribtion for the CY_U3P_DMA_CB_XFER_CPLT event does not work, the CyFxDMACallback() is not called on this event.
Do you know other ways to subscribe for events/interrupts when a USB package has been transferred ?
You may keep a variable as to know how many buffers are there in the queue to be read by USB (let us call it queue_count). For every commit after PROD_EVENT, increment the queue_count, and decrement the queue_count for every CONS_EVENT. When you get a short packet (understood by reading the buffer.count following PROD_EVENT), check for the queue_count. Wait until that is zero, change the EP configuration by accessing the registers. When the queue_count = 0, it imples no more data in queue which has been committed. Once you change teh EP configuration, commit, and then as you get the next CONS_EVENT you may change back the isoPkts value. Please feel free to get back in case of any issues in this method.
Please create a tech support case at "www.cypress.com -> Support -> Tech support " for the register settings. We can provide you the regiser setting for configuring isoPkts = 1 directly, through the case.
I believe CY_U3P_DMA_CB_XFER_CPLT events only occur on MANUAL_OUT DMA channels in response to a call to CyU3PDmaChannelSetupSendBuffer(). If your application is using a MANUAL channel to transfer directly from GPIF to USB you will have to react to CY_U3P_DMA_CB_CONS_EVENT instead.
I have not had my application crash when invoking CyU3PSetEpConfig() in a DMA callback, but I am concerned that that function likely has much more overhead than is needed since it was designed for "first-time" configuration not the on-the-fly tweaking that is needed in this case. Be sure not to call CyU3PDebugPrint() within the DMA handler though.
Are you streaming video to a Linux-based host? My experience is that sometime in the last few months the Linux UVC driver became much more sensitive to EHCI XACT errors. Windows XP and 7 seem much more tolerant.
In my case, on-the-fly reconfiguration of isoPkts has eliminated XACT errors with ZLPs between video frames. But I am still struggling with ZLPs within a video frame due to a consumer (USB) bandwidth that exceeds the producer (GPIF) bandwidth. For a fixed-bandwidth (e.g., uncompressed) video stream, the frequency of these errors can be reduced by making the endpoint bytes per packet more closely match the average bandwidth of an incoming video frame, and allocating sufficient DMA buffers to absorb bursts of data during a video line. But that won't work for compressed video, and even for uncompressed video it doesn't eliminate all the XACT errors.
If we wait for the queue_count to go to zero, wont the next producer event come within that time.
And the queue_count goes to zero only if the consumer event comes and as it is handled in the same callback , how is it possible to wait before the endpoint configuration ?
Please elaborate !!
Multithreading is the magic for that.
You do not need to wait inside callback. Return from callback without committing buffers and commit them on next callback calls.
Thank you Kalev, I am trying it and its working..