DMA Channels Dynamic Reconnection

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

cross mob
DmKo_1322631
Level 2
Level 2
10 replies posted 5 replies posted 5 questions asked

Dear Cypress,

   

could you explain how to correctly perform dma channels reconnection on Cypress FX3?

I want to switch between to producers on event (external GPIO interrupt). For this I have one Consumer (USB BULK IN) and two Producers (CPU with CY_U3P_DMA_TYPE_MANUAL_OUT,and PIB with CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE) which should be switched. For this I have the following code:

   

//Customising CPU->USB EP_IN DMA Management
CyU3PMemSet ((uint8_t *)&dma5, 0, sizeof (dma5));
dma5.size =size;
dma5.count = 1;
dma5.dmaMode = CY_U3P_DMA_MODE_BYTE;
dma5.notification =CY_U3P_DMA_CB_CONS_EVENT;
dma5.cb = NULL;
dma5.prodHeader = 0;
dma5.prodFooter = 0;
dma5.consHeader = 0;
dma5.prodAvailCount = 0;
dma5.prodSckId = CY_U3P_CPU_SOCKET_PROD;
dma5.consSckId = CY_FX_EP_CONSUMER_SOCKET;

   

//Customising PIB->USB EP_IN DMA Management
CyU3PMemSet ((uint8_t *)&dma1, 0, sizeof (dma1));
dma1.size = (usbSpeed == CY_U3P_SUPER_SPEED) ?
(size * CY_FX_EP_BURST_LENGTH ) : (size);
dma1.size = (size * CY_FX_EP_BURST_LENGTH );
dma1.count = CY_FX_BULKSRCSINK_DMA_BUF_COUNT;
dma1.validSckCount = 2;
dma1.dmaMode = CY_U3P_DMA_MODE_BYTE;
dma1.notification = 0;
dma1.cb = 0;
dma1.prodHeader = 0;
dma1.prodFooter = 0;
dma1.consHeader = 0;
dma1.prodAvailCount = 0;
dma1.prodSckId[0] = CY_U3P_PIB_SOCKET_0;
dma1.prodSckId[1] = CY_U3P_PIB_SOCKET_1;
dma1.consSckId[0] = CY_FX_EP_CONSUMER_SOCKET;

   

For dma initialization I do next:

   

//To enable DMA5?
apiRetStatus = CyU3PDmaChannelCreate(&glChHandleCPUtoUsb2, CY_U3P_DMA_TYPE_MANUAL_OUT, &dma5);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}

   

// Set DMA Channel transfer size
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleCPUtoUsb2, 0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}

   

//To enable DMA1?
apiRetStatus = CyU3PDmaMultiChannelCreate(&glChHandleBulkSrc, CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE, &dma1);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}

   


apiRetStatus = CyU3PDmaMultiChannelSetXfer (&glChHandleBulkSrc, CY_FX_BULKSRCSINK_DMA_TX_SIZE,0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer failed, Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}

   

 

   

Separately it works. How to dynamically reconnect channels for example to switch off glChHandleBulkSrc and switch on glChHandleCPUtoUsb2? Should I use CyU3PDmaMultiChannelDestroy or any other function?

   

 

   

Thank you!

0 Likes
3 Replies
Anonymous
Not applicable

Hi,

   

Yes, you can use the DmaChannelDestroy API to destroy one channel and create another so that you can use same consumer in both the channels.

   

Or you can only have the glChHandleBulkSrc in your firmware and whenever you want to do the CPU to USB Consumer transfer, you cna simply call CyU3PDmaMultiChannelReset and then call the CyU3PDmaMultiChannelSetupSendBuffer API to transfer your own buffer (from the CPU) to the consumer socket. Please refer to the FX3 API guide for more details.

   

Regards,

   

- Madhu Sudhan

0 Likes
DmKo_1322631
Level 2
Level 2
10 replies posted 5 replies posted 5 questions asked

Hello Madhu, thank you for reply. Now I use CyU3PDmaMultiChannelSetupSendBuffer  to transfer my own buffer. Could to help how to correctly resume the previous continuous DMA transmission (GPIF(CY_U3P_PIB_SOCKET_0,1)->USB(Bulk in) after CPU transfer?

0 Likes
DmKo_1322631
Level 2
Level 2
10 replies posted 5 replies posted 5 questions asked

Dear Cypress, I sent you the firmware code, could you answer the question?

0 Likes