- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I use cyusb3065 and 0v5640 to tranmit image data by DMA. I config stream dma as CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE dma, and commit data buffer in its dma callback. And I want to send leader before payload and send trailer after payload. I creat another CY_U3P_DMA_TYPE_MANUAL_OUT dma channel to send leader and trailer. I sent trailer and leader when stream dma callback get a short packet.But when I debug my code, I can see Leader and trailer dma get buffer and commit buffer successful, but I can't catch leader and trailer in bushound.What's my problem?
And I confuse how dma channel connet with end point? For example, I commit a buffer in stream dma callback, why dma can send the buffer to stream end point?How dma channel match the end point?
my code:
Stream DMA init:
{
/* Create a DMA Manual OUT channel for streaming data */
/* Video streaming Channel is not active till a stream request is received */
stDmaCfg.size = 32768;
stDmaCfg.count = 2;
stDmaCfg.validSckCount = 2;
stDmaCfg.prodSckId[0] = CY_U3P_PIB_SOCKET_0;
stDmaCfg.prodSckId[1] = CY_U3P_PIB_SOCKET_1;
stDmaCfg.consSckId[0] = CY_U3P_UIB_SOCKET_CONS_3;
stDmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
stDmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT | CY_U3P_DMA_CB_SEND_CPLT;
stDmaCfg.cb = CyCx3UvcAppDmaCallback;
stDmaCfg.prodHeader = 0;
stDmaCfg.prodFooter = 0;
stDmaCfg.consHeader = 0;
stDmaCfg.prodAvailCount = 0;
ui32Status = CyU3PDmaMultiChannelCreate (&g_stParameterSetVariable.stDMAHandleStreamIn,
CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE , &stDmaCfg);
if (ui32Status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rAppInit:DmaMultiChannelCreate1 Err = 0x%x", ui32Status);
}
CyU3PThreadSleep(100);
ui32Status = CyU3PDmaMultiChannelReset(&g_stParameterSetVariable.stDMAHandleStreamIn);
if (ui32Status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4,"\n\rAppInit:MultiChannelReset1 Err = 0x%x", ui32Status);
}
}
Stream DMA Callback:CyCx3UvcAppDmaCallback
{
...
if(type ==CY_U3P_DMA_CB_SEND_CPLT )
{
status = CyU3PDmaMultiChannelSetXfer (&g_stParameterSetVariable.stDMAHandleStreamIn, 0, 0);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rAplnStrt:SetXfer Err = 0x%x", status);
}
CyU3PGpifSMSwitch(CX3_INVALID_GPIF_STATE, CX3_START_SCK0, CX3_INVALID_GPIF_STATE, ALPHA_CX3_START_SCK0, CX3_GPIF_SWITCH_TIMEOUT);
CyU3PMipicsiWakeup();
if (status != CY_U3P_SUCCESS)
{
CyU3PDeviceReset(CyFalse);
CyU3PDebugPrint (4, "\n\rAplnStrt:SetXfer Err = 0x%x", status);
}
CyCx3_ImageSensor_Wakeup();
}
if (type == CY_U3P_DMA_CB_PROD_EVENT)
{
/* This is a produce event notification to the CPU. This notification is
* received upon reception of every buffer. The buffer will not be sent
* out unless it is explicitly committed. The call shall fail if there
* is a bus reset / usb disconnect or if there is any application error. */
status = CyU3PDmaMultiChannelGetBuffer(chHandle, &dmaBuffer, CYU3P_NO_WAIT);
while (status == CY_U3P_SUCCESS)
{
ui32DataCount = ui32DataCount + dmaBuffer.count;
/* Add Headers*/
if (dmaBuffer.count < CX3_UVC_DATA_BUF_SIZE)
{
EOF = CyTrue;
}
status = CyU3PDmaMultiChannelCommitBuffer (chHandle, dmaBuffer.count, 0);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint(4, "\r\nCommit Error:0x%x\r\n", status);
CyU3PEventSet(&glCx3Event, CX3_DMA_RESET_EVENT, CYU3P_EVENT_OR);
break;
}
status = CyU3PDmaMultiChannelGetBuffer(chHandle, &dmaBuffer, CYU3P_NO_WAIT);
}
}
else if (type == CY_U3P_DMA_CB_CONS_EVENT)
{
if(EOF == CyTrue)
{
EOF = CyFalse;
status = CyU3PMipicsiSleep();
status = CyCx3_ImageSensor_Sleep();
CyU3PBusyWait (1000);
//Fill Trailer
__SetTrailerBuffer(&stTrailer);
//Send Trailer
SendDMAMessage(&stTrailer, sizeof(IMAGE_TRAILER));
//Fill Leader
__SetLeaderBuffer(&stLeader);
//Send Leader
SendDMAMessage(&stLeader, sizeof(IMAGE_LEADER));
}
...
}
Leader Trailer DMA init
{
stEP1OutDmaCfg.size = 1024;
stEP1OutDmaCfg.count = 3;
stEP1OutDmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
stEP1OutDmaCfg.consSckId = CY_U3P_UIB_SOCKET_CONS_4;
stEP1OutDmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
stEP1OutDmaCfg.notification = 0;
stEP1OutDmaCfg.cb = 0;
stEP1OutDmaCfg.prodHeader = 0;
stEP1OutDmaCfg.prodFooter = 0;
stEP1OutDmaCfg.consHeader = 0;
stEP1OutDmaCfg.prodAvailCount = 0;
ui32Status = CyU3PDmaChannelCreate (&g_stParameterSetVariable.stLeaderTrailer,
CY_U3P_DMA_TYPE_MANUAL_OUT, &stEP1OutDmaCfg);
if (ui32Status != DH_STATUS_SUCCESS)
{
CyU3PDebugPrint (4, "LeaderTrailerDma Error: 0x%x\n\r", ui32Status);
g_testparam = ui32Status;
return ui32Status;
}
else
{
CyU3PDebugPrint(4, "\r\n LeaderTrailerDma success\r\n");
}
// 设置DMA通道传输大小
ui32Status = CyU3PDmaChannelSetXfer (&g_stParameterSetVariable.stLeaderTrailer, 0);
if (ui32Status != DH_STATUS_SUCCESS)
{
return ui32Status;
}
}
Send Leader and Trailer function:
void SendDMAMessage(uint8_t* buffer, uint8_t len)
{
unsigned int ui32Status = 0;
CyU3PDmaBuffer_t buf_p;
CyU3PDmaBuffer_t stOutBuffer;
ui32Status = CyU3PDmaChannelGetBuffer(&g_stParameterSetVariable.stLeaderTrailer, &stOutBuffer, 0);
if (ui32Status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\r\nGetBuffer Fail = %d\n", ui32Status);
}
else
{
CyU3PDebugPrint (4, "\r\nGetBuffer success\r\n");
}
CyU3PMemCopy(stOutBuffer.buffer, buffer, len);
for (i = 0; i < len; i++)
{
CyU3PDebugPrint(4, "0x%x\r\n", stOutBuffer.buffer);
}
ui32Status = CyU3PDmaChannelCommitBuffer(&g_stParameterSetVariable.stLeaderTrailer, len, 0);
if(ui32Status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\r\nSendBuffer Fail = %d\n", ui32Status);
}
else
{
CyU3PDebugPrint (4, "\r\nSendBuffer success\r\n");
}
ui32Status = CyU3PDmaChannelDiscardBuffer (&g_stParameterSetVariable.stLeaderTrailer);
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
CY_U3P_UIB_SOCKET_CONS_X corresponds to IN-Endpoint number X and CY_U3P_UIB_SOCKET_PROD_X corresponds to OUT-Endpoint number X.
You are committing the video data to IN-Endpoint 3 and committing leader and trailer to IN-Endpoint 4.
Regards,
Hemanth
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
CY_U3P_UIB_SOCKET_CONS_X corresponds to IN-Endpoint number X and CY_U3P_UIB_SOCKET_PROD_X corresponds to OUT-Endpoint number X.
You are committing the video data to IN-Endpoint 3 and committing leader and trailer to IN-Endpoint 4.
Regards,
Hemanth
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Can the same dma producer or consumer socket register for different DMA channel ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
No, it is not possible. To send trailer and leader at the end of the frame, to the same endpoint to which video data is sent, you will have to use CyU3PDmaMultiChannelSetupSendBuffer() as discussed in CX3 GPIFII modify (response dated Dec 6, 2019)
Regards,
Hemanth