Let me explain why the Frame Blanking Time is critical.
In general the CX3 firmware adds the UVC header for every buffer and adds EOF header for the last buffer of a frame in the DMA Callback Producer Event.
Note that DMA Callback Producer Event comes when there is a buffer full or when we wrap the buffer using CyU3PDmaMultiChannelSetWrapUp.
Since the last buffer of a frame partially full, we wrapup the buffer in the firmware. This needs CPU intervention.
For this, we should detect the Frame end in the GPIF state machine (Refer AN75779 example firmware) and Interrupt the CPU then wrap up the buffer. Then again we switch handle to GPIF state machine.
Refer CyFxGpifCB in AN75779 firmware.
Hence, we need some time to do this job. 10us time may be very less for this job. You can try 100 us and check.
In your case, please check whether FV high and Low time to ensure that the sensor is streaming the data as per your frame rate.
If yes, set the Vertical Blanking time to maximum (100 us) then see when there is frame rate drop in the host side.
If there is frame drop with maximum possible blanking time, do the following changes and check.
1. Select the DMA Size to appropriate value so that the frame size = Integer multiple of Buffer Size
2. Count the buffer number in the DMA Callback producer event add the EOF UVC header for the last buffer then the reset the counter.
This avoid manually wrapping the buffer when compared to the previous data flow.
Thank you very much for your detailed explanation and advice, that really help a lot. I will try immediately. Thanks again.
Thanks a lot for your previous suggestion. However, we tried but it shows little improvement and the frame drop was just as before.
I read again the "AN75779-- How to Implement an Image Sensor Interface....." to get more information about the mechanism the CX3 switch frames. Section 3.3, 3.4, 3.5 and 4.1 introduce lots of relevant contents. I have summarized some points as below and need your confirmation.
(1) What happens when a full DMA buffer is produced by GPIF in a frame?
The GPIF automatically wrap-up this buffer and commit it to CX3 RAM ----- The CPU is interrupted to add the UVC header information to this buffer and then commits it to the consumer (UIB).
>> Answer: Correct. Adding to the above info., the DMA producer event interrupt will be generated immediate after the buffer is wrap-up automatically. In the Producer event of call back, we manually commit buffer to the USB side.
(2) What happens when a full DMA buffer is produced by GPIF at the end of a frame?
The GPIF automatically wrap-up this buffer and commit it to CX3 RAM ----- The CPU is interrupted to add the EOF header information to this buffer and then commits it to the consumer (UIB) ----- The CPU wait for the consumer socket (USB) to transmit this last buffer ----- The CPU enters into the cleanup procedure during which the DMA channel and GPIF state-machine is reset ----- GPIF could respond to the next frame.
>> Answer: The CPU is interrupted via DMA Call back Producer Event. This is correct. But in the call back, we check full buffer or partial buffer. If it is partial buffer then only we add EOF else we add normal ( NOT EOF) header. Hence, we must need partial buffer to add EOF header. If the frame size = integer multiple of DMA buffer size, we can not add EOF in the firmware. To make frame size != integer multiple of DMA buffer size, we need to modify the buffer size.
(3) What happens when a partial DMA buffer is produced by GPIF at the end of a frame?
The CPU is interrupted to manually wrap-up this last partial DMA buffer ----- The CPU adds the EOF header information to this buffer and then commits it to the consumer (UIB) ----- The CPU wait for the consumer socket (USB) to transmit this last buffer ----- The CPU enters into the cleanup procedure during which the DMA channel and GPIF state-machine is reset ----- GPIF could respond to the next frame.
>> Answer: The clean up procedure is not mandatory. Please refer the firmware associated with the AN75779 and OV5640 example firmware provided in the SDK. You can see that there is no cleanup procedure.
Is the above summary are correct or not? I appreciate your comments and after that we might find some ways to cut some step to save the time consuming between frame switching.
Thank you very much!
I have added the answers inline in the above response.
Please refer the text starts with " >> Answer ".
Thank you very much for your great support and careful explanation.
With some modifications from the example firmware in SDK 1.3.4, the tested minimum vertical blanking time is reduced to about 18us without frame drop, which is improved significantly from the previous 200us.
This improvement has covered most of our applications, except one special case requiring the minimum blanking time as short as 9us. So we still try to shorten this time.
Based on the following two facts:
(1) The in-frame full DMA buffer is transferred smoothly to the UIB with small blanking time.
(2) Switching frame requires minimum blanking time as we tested as 18us.
For next step, we want to modify the GPIF state-machine to ignore the relevant states triggered by !FV(frame end), that is state 9/10/11/12 as shown in Page18 of AN75779. As such, the GPIF always switches between state0 to state8 and seems never encounter frame end. Whenever one DMA buffer is full, it is wrapped-up to CX3 RAM and then committed to UIB to transfer to host. From host side, it continuously receives DMA buffers and do frame segmentation based on buffer count.
Is it allowed to modify the state machine of GPIF in CX3 and can you comment on the feasibility of the above mentioned method?
Thank you very much!!!
The GPIF II state machine for CX3 is fixed one. It is not recommended to change.
Please let me know frame resolution, bytes per pixel, fps to know the bandwidth required your case.
Also DMA buffer size in the firmware. This will help to know how many buffers are needed for frame to reach host.
In your case, you do NOT have partial buffer at end of the frame. Is it correct?
If yes, how are you adding EOF to UVC header.