The error code 0x47 for CyU3PDmaMultiChannelCommitBuffer() after some time of streaming indicates that the host is not able to issue IN tokens fast enough to pull out the data from the U Port. Eventually the DMA buffers associated with the channel between P Port and U Port will be filled and hence FLAGA and FLAGB stay low. Please try the suggestions mentioned in the following KBA and let me know the result:
What's define START_SCK0 and ALPHA_START_SCK0,
I get failure when build the code.
in my orign code, for start gpif, we onlyl CyU3PGpifSMStart (RESET,ALPHA_RESET). no call CyU3PGpifSMSwitch (257, 0, 257, 0, 2);
for fix the issues, we must use your call logic?
Please let me know the following:
1. Did you try increasing the DMA buffer size allocated with the P to U channel? If you tried increasing, please let me know what is the buffer size you are using now.
2. The maximum supported clock for GPIF II block is 100MHz. Please confirm that your clock frequency is less than 100MHz.
Regarding your query in previous response, you can call the CyU3PGpifSMStart (RESET,ALPHA_RESET) instead of the call mentioned in the KBA. This is because the changes mentioned in the KBA are meant for the firmware that comes along with AN75779 and the corresponding state machine. It is okay to modify it based on your application. Also, you can call the CyU3PGpifSMSwitch() as mentioned in the KBA without any changes as it wont make any undesirable effects.
For single Thread, DMA size is 15*1024 + 16, count is 8.
For two thread , DMA size is 15*1024 + 16, count is 4.
if I use count 8 with two thread DMA size is 15*1024 + 16, count is 8, I will get malloc memory failure error code.
I try to increasing the DMA buffer size to 5, I still see the 0x47 error code.
Now my GPIF block clock frequency is 100MHz.
It is a little strange that we use single thread, I don't see the error.
it get more lower transfer speed with dual thread.
We just want to improve camera frame rate , what's more best soluation?
Please try increasing the buffer size to 31*1024+16 and reducing the buffer count in steps so that the memory failure error is not seen. Then check if you are facing the error again. If you are still facing the error, then try increasing buffer size further and decrease the buffer count so that memory failure error is not seen.
If you still face the error, please perform the suggestions mentioned in the KBA shared before. While implementing the changes, please check if any of the APIs are failing. Please let me know if no APIs are failing and still you are seeing this error.
Can you help us confirm if dual thread mode get higher performance.
Currently, the app working ok under single thread(50fps) , But app get the error under dual thread(50fps) .
When single thread is used, the producer socket will fill up a buffer and then switch to the next buffer. This buffer switching takes a bit long to happen. Hence there will be a reduction in data rate. When multiple producer sockets are used, you can fill the DMA buffers associated with each socket alternatively by performing a socket switch. The socket switching takes relatively less time compared to buffer switching and hence can increase data rate.
The error occurs because the host application is too slow to issue IN tokens to clear the filled buffers associated with the producer sockets. The workaround for this is to increase the buffer size so that we match the rate at which producer fills the buffer and USB emptying it.
Please let us know if this application is UVC compliant or not.
Our application is UVC compliant.
I don't think the host application is slow,
I don't see the commit failure (CY_U3P_ERROR_INVALID_SEQUENCE) when frame rate to 50fps with single thread 8 dma buffer.
But I see the commit failure (CY_U3P_ERROR_INVALID_SEQUENCE) even if the frame rate set to 20fps with dual thread 6 dma buffer with the same application as single threade mode
1. Can you please confirm all reason on the commit buffer error (CY_U3P_ERROR_INVALID_SEQUENCE).
2. Are there any uvc sample code with dual thread mode?
3. Also,Can you help us confirm following releated code (use 16bit mode)?
#if (CY_FX_SLFIFO_GPIF_16_32BIT_CONF_SELECT == 0)
CyU3PGpifSocketConfigure(0, CY_U3P_PIB_SOCKET_0, 12*1024/4, CyFalse, 1);
CyU3PGpifSocketConfigure(1, CY_U3P_PIB_SOCKET_1, 12*1024/4, CyFalse, 1);
if (CY_FX_SLFIFO_GPIF_16_32BIT_CONF_SELECT == 1)
About Create MultiChannel:
CyU3PMemSet ((uint8_t *)&dmaMultiConfig, 0, sizeof(dmaMultiConfig));
dmaMultiConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaMultiConfig.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT;
dmaMultiConfig.cb = CyFxUvcApplnDmaCallback;
dmaMultiConfig.prodHeader = CY_FX_UVC_MAX_HEADER;
dmaMultiConfig.prodFooter = CY_FX_UVC_MAX_FOOTER;
dmaMultiConfig.consHeader = 0;
dmaMultiConfig.prodAvailCount = 0;
/* Create a DMA AUTO channel for P2U transfer. */
dmaMultiConfig.size = CY_FX_UVC_STREAM_BUF_SIZE; //increase buffer size for higher performance
dmaMultiConfig.count = CY_FX_UVC_STREAM_BUF_COUNT; // increase buffer count for higher performance
CyU3PDebugPrint(4, " dmaMultiConfig.size = %d\n", dmaMultiConfig.size);
CyU3PDebugPrint(4, " dmaMultiConfig.count = %d\n", dmaMultiConfig.count);
dmaMultiConfig.validSckCount = 2;
//dmaMultiConfig.prodSckId = CY_FX_PRODUCER_PPORT_SOCKET; // Thread0 ==> EP 0x83
dmaMultiConfig.prodSckId  = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_0;
dmaMultiConfig.prodSckId  = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_1;
dmaMultiConfig.consSckId  = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_0 | CY_FX_EP_VIDEO_CONS_SOCKET);
apiRetStatus = CyU3PDmaMultiChannelCreate (&glChHandleSlFifoPtoU, CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE,&dmaMultiConfig);
if (apiRetStatus != CY_U3P_SUCCESS)
CyU3PDebugPrint(4, "CyU3PDmaMultiChannelCreate failed, Error code = %d\n", apiRetStatus);
Let's provide update more infomation:
Commit Err1: 47 369 //Show get CY_U3P_ERROR_INVALID_SEQUENCE)
Commit Err1: 47 370
Commit Err1: 47 371
Clear feature request detected.. //windows send feature request then stream been stopped.
CYU3P_PIB_ERR_THR0_WR_OVERRUN // FPGA write the data to P port only when the FLAG is High state, why still see CYU3P_PIB_ERR_THR0_WR_OVERRUN and CYU3P_PIB_ERR_THR1_WR_OVERRUN.
By my understand if see CYU3P_PIB_ERR_THR1_WR_OVERRUN, it means that FPGA write to P Port when FLAGA/B stay Low level , is it correctly?
For detail information on GPIF design file please refer to the first comment's attached file.
Update debug information Bus hound:
Some founds between single/dual thread mode.
UVC head packet seqnumber is continue and Bus Hound Delta time(between two packet) = 70~160us
UVC head packet seqnumber is not continue(02/05/04/07/06/09/08/0b/0a/0d) and Bus Hound Delta time(between two packet) = 70~100us
so, I have two question:
1. Dual thread mode don't keep the packet seq that it been send out on usb bus by call CyU3PDmaMultiChannelCommitBuffer()?
2. Dual thread mode will lead packet ready to send out to usb slow?
Please find my comments for your response 8,9 and 10.
Regarding your questions in response 8,
1. We have seen the error code 0x47 for CyU3PDmaMultiChannelCommitBuffer() when there is a DMA overflow. This is again confirmed in your debug prints shown in response 9.
2. Yes, we do have an implementation of image sensor interface using FX3 in UVC Framework. Please refer to the following link which has the complete documentation and project for this implementation
3. Please let me know why you have used the watermark value as 12*(1024/4). Also, please confirm that the macro CY_FX_SLFIFO_GPIF_16_32BIT_CONF_SELECT when set to 0 is 16 bit mode and is 32 bit mode when set to 1.
Regarding your question in response 9, the overrun error occurs when a write to a socket is done beyond the available buffer size. Your understanding is correct, FPGA might also be writing to the socket when the buffers are full.
Regarding your question in response 10,
1. Packet sequence will be followed properly. This happens because in between transmission of buffers from P Port to U Port, some buffers are not sent because the API CyU3PDmaMultiChannelCommitBuffer() fails. This is why you do not see the sequence continuously.
2. Generally dual thread will increase data rate.
According to the logs shared in your response 10, I find that the data buffer size is not changed to 31*1024+16 as I recommended in Response 7. Also, please let me know the logical implementation on the FPGA side. I understand that the thread switching is done by the FPGA. Please let me know how you are implementing this.
Also, please let me know what is the value of the macro CY_FX_EP_BULK_VIDEO_PKT_SIZE.
I find that in the GPIF II project that you shared before, Watermark flags are not used. Generally, Ready flags are to be monitored for starting a data transfer and watermark flags are to be monitored for ending the data transfer. You can understand more about this by going through AN65974. The link to the same is given below:
Please refer to Figure 4 of the above document. From this, you can understand that there is a 3 cycle latency between last WR signal (buffer full) and FLAG going low. So, during these clock cycles, the READY flag will stay HIGH and FPGA will keep on writing data which can cause overrun. To avoid this, you need to use watermark flag. To understand more about watermark flag and how to use it, you can go through from section 9.3 of AN65974(link shared before). Please make use of watermark flag also in the project. For start of the data transfer to a particular socket, you need to check ready flag and for ending the data transfer, you need to check watermark flag for that socket. Please implement this and let me know if you are still seeing overrun error.