- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
In USBToGPIF example, I want to add an extra memory between USB and GPIF instead of increase the existed memory.
In this example, there is a CY_U3P_DMA_TYPE_AUTO( prod=CY_U3P_UIB_SOCKET_PROD_1 , cons=CY_U3P_PIB_SOCKET_0). I added a DMA before that and change this DMA as well. Now, I have 2 DMA back to back like:
first DMA: CY_U3P_DMA_TYPE_AUTO, prod = CY_U3P_UIB_SOCKET_PROD_1 , cons = CY_U3P_CPU_SOCKET_CONS, notification = CY_U3P_DMA_CB_PROD_EVENT, cb = DmaCallback
second DMA: CY_U3P_DMA_TYPE_AUTO, prod = CY_U3P_CPU_SOCKET_PROD, cons = CY_U3P_PIB_SOCKET_0,
notification = 0, cb = 0
I copy the data from the fist to second DMA in DmaCallback., But when I add this extra DMA to my design, it doesn't work. and I lose the EP in CC.
What is the right way to add an extra memory between USB and GPIF?
Thanks
Solved! Go to Solution.
- Labels:
-
USB Superspeed Peripherals
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
DMA channels cannot be configured as AUTO channels, if one of the sockets is CPU.
Please make the channel as a MANUAL_IN channel, when CPU is consumer socket and make the channel as MANUAL_OUT, when CPU is the producer socket.
Best Regards,
AliAsgar
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
1. What exactly do you mean by "I want to add an extra memory between USB and GPIF instead of increase the existed memory"?
2. Could you share your firmware with us?
Best Regards,
AliAsgar
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I need to store input data coming from USB in a separate memory, but I don't want to increase the size of existing memory. for this reason I added a DMA channel in series with the previous DMA. But it doesn't work. What is the best way to save data in another memory?
In USBToGPIF example, there is an auto DMA channel between prod = CY_U3P_UIB_SOCKET_PROD_1 and cons = CY_U3P_PIB_SOCKET_0. I wanted to add another DMA.
I did those changes in the attached FW, now there are glDmaChHandle0 and glDmaChHandle1, but it seems that it is not the correct way.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
DMA channels cannot be configured as AUTO channels, if one of the sockets is CPU.
Please make the channel as a MANUAL_IN channel, when CPU is consumer socket and make the channel as MANUAL_OUT, when CPU is the producer socket.
Best Regards,
AliAsgar
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for your reply.
I changed my code based on your comments. This example works fine.
But It doesn't work for a multi channel DMA.
I have another example, with a CY_U3P_DMA_TYPE_AUTO_ONE_TO_MANY channel, that I need to add extra DMA to it as well.
I added a MANUAL_IN channel before that and changed the second DMA to CY_U3P_DMA_TYPE_MANUAL_ONE_TO_MANY. but I got error in CyU3PDmaMultiChannelCreate.(the second DMA)
first DMA:
CyU3PMemSet ((uint8_t *)&dmaCfg0, 0, sizeof (dmaCfg0));
dmaCfg0.size = CY_FX_DMA_BUF_SIZE;
dmaCfg0.count = CY_FX_DMA_BUF_COUNT;
dmaCfg0.prodSckId = CY_FX_EP_PRODUCER_SOCKET0;
dmaCfg0.consSckId = CY_U3P_CPU_SOCKET_CONS;
dmaCfg0.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaCfg0.notification = CY_U3P_DMA_CB_PROD_EVENT;
dmaCfg0.cb = DmaCallback;
dmaCfg0.prodHeader = 0;
dmaCfg0.prodFooter = 0;
dmaCfg0.consHeader = 0;
dmaCfg0.prodAvailCount = 0;
apiRetStatus = CyU3PDmaChannelCreate (&glDmaChHandle0, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaCfg0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyFxAppErrorHandler(apiRetStatus);
}
apiRetStatus = CyU3PDmaChannelSetXfer (&glDmaChHandle0, CY_FX_GPIFTOUSB_DMA_TX_SIZE);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyFxAppErrorHandler(apiRetStatus);
}
Second DMA:
/* Create a DMA AUTO channel for the USB to GPIF transfer. */
CyU3PMemSet ((uint8_t *)&dmaCfg, 0, sizeof (dmaCfg));
dmaCfg.size = CY_FX_DMA_BUF_SIZE;
dmaCfg.count = CY_FX_DMA_BUF_COUNT;
dmaCfg.validSckCount= 4;
// TODO: Producer/Consumer
dmaCfg.prodSckId[0] = CY_U3P_CPU_SOCKET_PROD;
// TODO: Producer/Consumer
dmaCfg.consSckId[0] = CY_FX_GPIF_CONSUMER_SOCKET0;//CY_U3P_PIB_SOCKET_0;
dmaCfg.consSckId[1] = CY_FX_GPIF_CONSUMER_SOCKET1;//CY_U3P_PIB_SOCKET_1;
dmaCfg.consSckId[2] = CY_FX_GPIF_CONSUMER_SOCKET2;//CY_U3P_PIB_SOCKET_2;
dmaCfg.consSckId[3] = CY_FX_GPIF_CONSUMER_SOCKET3;//CY_U3P_PIB_SOCKET_3;
dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaCfg.notification = 0;
dmaCfg.cb = 0;
dmaCfg.prodHeader = 0;
dmaCfg.prodFooter = 0;
dmaCfg.consHeader = 0;
dmaCfg.prodAvailCount = 0;
// TODO: Producer/Consumer
apiRetStatus = CyU3PDmaMultiChannelCreate (&glDmaChHandle,CY_U3P_DMA_TYPE_MANUAL_ONE_TO_MANY , &dmaCfg);//CY_U3P_DMA_TYPE_AUTO_ONE_TO_MANY
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyFxAppErrorHandler(apiRetStatus);
}
apiRetStatus = CyU3PDmaMultiChannelSetXfer (&glDmaChHandle, CY_FX_GPIFTOUSB_DMA_TX_SIZE, 0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyFxAppErrorHandler(apiRetStatus);
}
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
As I mentioned, this solution doesn't work for a multi channel DMA(ONE_TO_MANY ) in my side.
Is there any workaround for that?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
A MANUAL channel is different from MANUAL_IN and MANUAL_OUT channel. The difference is that in MANUAL_IN and MANUAL_OUT channels, one of the sockets (either the consumer or the producer is the CPU). But in the case of a MANUAL channel, the sockets used in creating the channels are never CPU. But CPU (firmware) plays a role in obtaining and committing buffers based on the DMA callback events.
MANUAL_ONE_TO_MANY channels is a MANUAL channel and therefore should not have CPU as one of it sockets.
We recommend you to create one channel, with
dmaCfg.prodSckID = CY_FX_EP_PRODUCER_SOCKET0
dmaCfg.consSckId[0] = CY_FX_GPIF_CONSUMER_SOCKET0;//CY_U3P_PIB_SOCKET_0;
dmaCfg.consSckId[1] = CY_FX_GPIF_CONSUMER_SOCKET1;//CY_U3P_PIB_SOCKET_1;
dmaCfg.consSckId[2] = CY_FX_GPIF_CONSUMER_SOCKET2;//CY_U3P_PIB_SOCKET_2;
dmaCfg.consSckId[3] = CY_FX_GPIF_CONSUMER_SOCKET3;//CY_U3P_PIB_SOCKET_3;
Best Regards,
AliAsgar
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I already have that single multichannel DMA (dmaCfg) and it works.
I am looking for a way to add an extra DMA before that.
So no way for that if I use multichannel DMA, right?
Do you have any suggestion?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
For a multichannel DMA, ONE_TO_MANY in this case, one MANUAL_IN channel and multiple MANUAL_OUT channels can be created.
The getbuffer and commitbuffer APIs must be handled appropriately in the firmware.
Best Regards,
AliAsgar