UVC firmware only sending 1-2 packets despite FPGA constantly supplying data

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

cross mob
lock attach
Attachments are accessible only for community members.
jnagy
Level 5
Level 5
5 solutions authored 100 replies posted 100 sign-ins

I am attempting to make a FX3 firmware which extracts UVC data from a FIFO populated by an FPGA, attaches UVC headers and then sends the packets to the USB host however my video data is not being consistently sent to the host. Looking at the USB bus in Wireshark I can see 1 or 2 full packets of UVC data are sent to the host but after that the FX3 seems to ignore requests from the host for more data and I am not sure why. The packets that are sent are full, so they should not be marked as EOF and I can verify that by looking at the packet's headers in Wireshark. Additionally, the FPGA is constantly outputting data to the FIFO therefore the FIFO should have data and the FX3 should be able to fill its buffers with that information and invoke the callback functions. Since the sending of the UVC data handled by a callback function, I don't think the issue is a failing API call which results in an endless loop but I cannot verify this. I am basing my firmware off the AN75779 and USBVideoClassBulk example firmwares and I am following the same setup and logic for sending UVC packets to the host. The descriptors only allow for 1080p60 and the parameter negotiation with the host seems to complete successfully.

I have included my firmware as well as 2 different Wireshark captures showing 1 and 2 packets being sent. Help diagnosing why my firmware is hanging would be appreciated. Unfortunately I do not have access to the debug logs despite them being activated in the firmware.

0 Likes
1 Solution
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

As discussed here  How to setup external clock for GPIF - Infineon Developer Community  - We recommend programming FX3 before FPGA is ready to send the data. Please refer to section 12.5 of AN65974 for the steps for testing. And also confirm if the external clock is stable.

 

Regards,
Rashi

View solution in original post

0 Likes
13 Replies
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

I have gone through the shared firmware and USB traces. I understand that only the USB_UVC_CLASS macro is enabled, USE_DMA_OVERRIDE is disabled and the video data is sent in non-override mode. Is my understanding correct? If yes, please set CY_FX_UVC_DMA_RESET_EVENT in the DMA callback when Commit buffer API fails and also track the producer and consumer events in the DMA callback.

Also, please make sure that the probe control structure reports the frame size correctly. You can refer to this KBA  Debug UVC application firmware in FX3 – KBA226722 - Infineon Developer Community  

We recommend not to use CyU3PDebugPrints in the callback functions

Regards,
Rashi
0 Likes

Yes, that understanding is correct. I have added the CY_FX_UVC_DMA_RESET_EVENT event to the DMA callback and the to "UVCAppThread_Entry" where the event calls "CyFxUVCApplnStop" and "CyFxUVCApplnStart", like the AN75779  example. I also added the DMA failure counter. I am not sure what you mean by "track the producer and consumer events in the DMA callback". Do you mean count the times each event is encountered?

The descriptors and control structure look correct for 1080p60 streaming, which is what we are aiming for, however I think there might be a possible issue with the buffer size. I am streaming 1920x1080 video with 2 bytes per pixel. This gives bytes per frame = 1920 * 1080 * 2 = 4147200 bytes. Using 16KB buffers (16384 bytes), the number of full buffers per frame = floor( 4147200 / (16384 - 16) ) = floor ( 4147200 / 16368 ) = floor(253) = 253 according to KBA226722.  Since a full frame fits evenly into 253 buffers, that means a partial EOF frame wont get sent. How can I avoid this? Is it just using smaller buffers?

I commented all CyU3PDebugPrints in the callback functions. I included my updated firmware as well as a capture with the new firmware. In the capture a single packet is sent.

0 Likes
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

 I am not sure what you mean by "track the producer and consumer events in the DMA callback". Do you mean to count the times each event is encountered?

>> To understand how much data is received by FX3. Please count the number of times CY_U3P_DMA_CB_PROD_EVENT and CY_U3P_DMA_CB_CONS_EVENT are triggered. You can use global variables for counting and print the values in the for loop of thread entry function

Since a full frame fits evenly into 253 buffers, that means a partial EOF frame wont get sent. How can I avoid this? Is it just using smaller buffers?

>>  ( 4147200 / 16368 )  = 253 full buffers and 1 partial buffer will 6096 bytes. The DMA bufferm size seems fine. Please confirm if video line size is multiple of GPIF bus width. 

You can also call CyU3PGpifGetSMState in the for loop of thread entry function to check if GPIF SM is not stuck

Regards,
Rashi
0 Likes

Sorry, I was using the Windows calculator in "Programmer" mode and forgot it doesn't provide fractional results. Nevermind the buffer size issue.

I am working to enable access to the UART console prints and will post back when they are available.

0 Likes

Looking at the UART prints there are no buffers being produced or consumed (my added counters are stuck at 0). What could be the issue be that my callbacks aren't getting ran?

Ive modified the GPIF bus to be 16-bit from 32-bit and included the updated firmware. 

0 Likes
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

The firmware implementation to track producer-consumer events looks fine.

If the producer events are not seen then the data from GPIF is not committed. As requested earlier, you can  call CyU3PGpifGetSMState in the for loop of thread entry function to check if GPIF SM is not stuck

Regards,
Rashi
0 Likes

Looking at the states, the machine seems to be stuck in RESET. The transition from RESET to IDLE is LOGIC_ONE so it should advance regardless of the control signals. The machine says it is in the RESET state before I start streaming, which makes sense since the machine is idle however after starting streaming it stays in RESET. This makes me think that the machine is getting constantly reset or stopped. However I don't get continuous debug prints from CyFxApplnGpifStart or CyFxApplnGpifStop which are the only functions which modify the state machine's execution.

I also looked at the DMA channel used for transfers with CyU3PDmaChannelGetStatus and once I start streaming the state of the DMA channel is CY_U3P_DMA_ACTIVE, which is expected as the channel is set up for an infinite transfer. The producer and consumer counts available from the API call also match my manual counters in the GPIF callback.

How does the LOGIC_ONE transition work? What drives the state machine to make this transition?

0 Likes
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

If CyU3PGpifSMStart passed successfully and the GPIF state remains RESET then the issue could be due to an external clock. Please check if the external clock to GPIO16 of FX3 is stable

Regards,
Rashi
0 Likes

I checked the external clock and it is stable. It is also driving other components on the board and we are experiencing no issues with those components. I also made sure that the GPIF state machine was set to "External" clock.

0 Likes

I am going to try using a slower clock. Is there any settings that need to be modified in firmware I used a 78.125MHz external clock from an FPGA? I have external clock selected in GPIF with the firmware configured to  the following to initialize the GPIF port.

pibclock.clkDiv      = 2;
pibclock.clksrc=CY_U3P_SYS_CLK;
pibclock.isDllEnable = CyFalse;
pibclock.isHalfDiv   = CyFalse;

And the device clock is configured with

clockConfig.setSysClk400  = CyFalse;
clockConfig.cpuClkDiv     = 2;
clockConfig.dmaClkDiv     = 2;
clockConfig.mmioClkDiv    = 2;
clockConfig.useStandbyClk = CyFalse;
clockConfig.clksrc=CY_U3P_SYS_CLK;

Looking at the TRM I can see I can modify "setSysClk400" to select a 384MHz base clock but am unsure if there needs to be any other  clocking modifications

0 Likes
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

The external clock from FPGA needs to be connected to the PCLK pin if FX3 (GPIO 16)

No, changes need to be done in the firmware if the external clock is changed other than choosing external clock option in the GPIF II Designer Tool

Also, please let me know when does the FPGA start providing the external clock to FX3

Regards,
Rashi
0 Likes

I answered this clock question in this thread since I think the question is better suited for its own thread.

0 Likes
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

As discussed here  How to setup external clock for GPIF - Infineon Developer Community  - We recommend programming FX3 before FPGA is ready to send the data. Please refer to section 12.5 of AN65974 for the steps for testing. And also confirm if the external clock is stable.

 

Regards,
Rashi
0 Likes