- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I use a DMA to transfer from FX3 to PC and libUSB driver. I have two problems now.
1) I noticed the IN endpoint only receives 1 transfer at PC then refuse to CyU3PDmaChannelGetBuffer. I can verify the received transfer is correct. In a multi-DMA IN EP, I could get 7 transfers before CyU3PDmaChannelGetBuffer fails. I believe the two issues share the same root cause.
2) I would rather like to have the FPGAInterrupt to be called directly from CyFxGpifCB(), but it seems not working. I had to create a thread to poll for FPGA_Intr_called status and emulate an interrupt.
Source segments below.
void FPGAInterrupt()
{
CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
CyU3PDebugPrint(CY_FX_DEBUG_PRIORITY, "FPGAInterrupt() called \r\n");
apiRetStatus = CyU3PDmaChannelGetBuffer (&glChHandleUVCControlIN, &buf_p_1, CYU3P_NO_WAIT);
if (apiRetStatus != CY_U3P_SUCCESS) {
CyU3PDebugPrint(CY_FX_DEBUG_PRIORITY, "FPGAInterrupt.CyU3PDmaChannelGetBuffer failed, Error code = %d\n", apiRetStatus);
}
if (apiRetStatus == CY_U3P_SUCCESS) {
CyU3PMemSet (buf_p_1.buffer, 0, 16*CY_FX_EP_BULK_VIDEO_PKT_SIZE);
for (int i=0; i<16*CY_FX_EP_BULK_VIDEO_PKT_SIZE; i++) {
buf_p_1.buffer = FPGAInterrupt_header[i%24];
}
buf_p_1.buffer[0] = intr_cnt;
CyU3PDebugPrint(CY_FX_DEBUG_PRIORITY, "FPGAInterrupt() memset done \r\n");
/* Commit the full buffer with default status. */
apiRetStatus = CyU3PDmaChannelCommitBuffer (&glChHandleUVCControlIN, buf_p_1.size, 0);
if (apiRetStatus != CY_U3P_SUCCESS) {
CyU3PDebugPrint(CY_FX_DEBUG_PRIORITY, "CyFxUVCDmaDownloadCallback.CyU3PDmaChannelCommitBuffer failed, Error code = %d\n", apiRetStatus);
}
CyU3PDebugPrint(CY_FX_DEBUG_PRIORITY, "FPGAInterrupt() memset done \r\n");
}
CyU3PDebugPrint(CY_FX_DEBUG_PRIORITY, "FPGAInterrupt() exits \r\n");
return;
}
CyFxGpifCB (
uint8_t currentState /* GPIF state which triggered the interrupt. */
)
{
/* The ongoing video frame has ended. If we have a partial buffer sitting on the socket, we need to forcibly
* wrap it up. We also need to toggle the FW_TRG a couple of times to get the state machine ready for the
* next frame.
*
* Note: DMA channel APIs cannot be used here as this is ISR context. We are making use of the raw socket
* APIs.
*/
switch (currentState)
{
case FPGA_DO_INTR:
intr_cnt++;
FPGA_Intr_called = CyTrue;
// if (FPGA_Intr_called == CyTrue) {
// FPGAInterrupt();
// FPGA_Intr_called = CyFalse;
// }
}
}
void
uvcFPGAIntrThread_Entry (uint32_t input)
{
for (;;) {
if (FPGA_Intr_called == CyTrue) {
FPGAInterrupt();
FPGA_Intr_called = CyFalse;
}
// CyU3PThreadSleep(10);
/* Allow other ready threads to run. */
CyU3PThreadRelinquish ();
}
}
dmaCfg.size = 16*CY_FX_EP_BULK_VIDEO_PKT_SIZE;
dmaCfg.count = 1;
dmaCfg.prodSckId = CY_U3P_UIB_SOCKET_PROD_5;
dmaCfg.consSckId = CY_U3P_CPU_SOCKET_CONS;
dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT;
dmaCfg.cb = CyFxUVCControlDmaCallback;
dmaCfg.prodHeader = 0;
dmaCfg.prodFooter = 0;
dmaCfg.consHeader = 0;
dmaCfg.prodAvailCount = 0;
<cut>
/* Create a DMA MANUAL_OUT channel for the consumer socket. */
dmaCfg.notification = CY_U3P_DMA_CB_CONS_EVENT;
dmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
dmaCfg.consSckId = CY_U3P_UIB_SOCKET_CONS_4;
apiRetStatus = CyU3PDmaChannelCreate (&glChHandleUVCControlIN,
CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
<cut>
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleUVCControlIN, 0);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Instead of CYU3P_NO_WAIT, can you please specify a finite timeout and see? This has been the issue in lot of similar cases.
Regards,
-Madhu Sudhan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have a similar issue, According to my debug, changing the size and count of DMA could ameliorate the situation. I don't know if the situation happens only when using libusb driver? Or it's the bug of FX3 when changing the size and count of DMA?