- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is it possible to change DMA configuration while running and restart DMA?
Below is a source that runs in 2-socket GPIF mode and runs fine.
and I want to stop GPIF and run it in loopback mode .
but it stop running.
The red source seems to be wrong.
Please give me guide line. Thank you.
dmaCfg.size = (usbSpeed == CY_U3P_SUPER_SPEED) ?(size * CY_FX_EP_BURST_LENGTH ) : (size);
dmaCfg.count = 4;
dmaCfg.validSckCount = 2;
dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaCfg.cb = NULL;
dmaCfg.notification = 0;
dmaCfg.prodSckId[0] = CY_U3P_PIB_SOCKET_0;
dmaCfg.prodSckId[1] = CY_U3P_PIB_SOCKET_1;
dmaCfg.consSckId[0] = CY_FX_EP_CONSUMER_SOCKET;
apiRetStatus = CyU3PDmaMultiChannelCreate (&glChHandleBulkSrc, CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE, &dmaCfg);
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleBulkSrc, CY_FX_BULKSRCSINK_DMA_TX_SIZE);
( Runnig Well)
(change to loop back mode)
dmaCfg.prodSckId[0] = CY_U3P_CPU_SOCKET_PROD;
dmaCfg.prodSckId[1] = CY_U3P_CPU_SOCKET_PROD;// duplicate ?
dmaCfg.consSckId[0] = CY_FX_EP_CONSUMER_SOCKET;
dmaCfg.cb = CyFxBulkSrcSinkDmaCallback;
dmaCfg.notification = CY_U3P_DMA_CB_CONS_EVENT;
CyU3PGpifDisable(CyTrue);
CyU3PDmaMultiChannelAbort(&glChHandleBulkSrc);
apiRetStatus = CyU3PDmaMultiChannelCreate (&glChHandleBulkSrc, CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE, &dmaCfg);
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleBulkSrc, CY_FX_BULKSRCSINK_DMA_TX_SIZE);
( running is stop)
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[Solved ] self^^
After preparing two types of start codes,
By calling the reboot_as() function, the startup code is branched by referring to the static global variable .
The reboot start address was found with the elf2img -v option.
void reboot_as(CyBool_t b_mode)
{
sw_loop_mode=b_mode;// static
CyU3PUsbAckSetup ();
CyU3PThreadSleep (2000);
CyU3PConnectState (CyFalse, CyTrue);
CyU3PThreadSleep (1000);
CyU3PUsbSetBooterSwitch (CyTrue);
CyU3PUsbJumpBackToBooter(0x4000e4e0);// from elf2img -verbose
while (1)CyU3PThreadSleep (100);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
CPU PROD has just one socket. Assigning CPU_PROD as prodSck[0] as well as prodSck[1] is invalid, which maybe causing the issue.
Also AUTO channels do not include CPU sockets. DMA channels from CPU is a MANUAL OUT channel, and DMA channel to a CPU is a MANUAL IN channel.
Please provide an explanation of your application and requirement, we can take try giving you a better alternative.
Best Regards,
AliAsgar
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for rapid answer.
Following your advice, I've change code like below;
Actually loopback code itself is running well also.
But I want to know how to change between 2 mode while running time.
mode(1) = 2 socket gpif mode
mode(2)= loop back mode
-----
CyU3PMemSet ((uint8_t *)&dmaCfg, 0, sizeof (dmaCfg));
dmaCfg.size = (size * CY_FX_EP_BURST_LENGTH);
dmaCfg.size *=2;
dmaCfg.count = 6;
dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaCfg.cb = CyFxBulkSrcSinkDmaCallback;
dmaCfg.notification = CY_U3P_DMA_CB_CONS_EVENT;
dmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
dmaCfg.consSckId =CY_FX_EP_CONSUMER_SOCKET;
dmaCfg.prodHeader = 0;
dmaCfg.prodFooter = 0;
dmaCfg.consHeader = 0;
dmaCfg.prodAvailCount = 0;
apiRetStatus = CyU3PDmaChannelCreate (&glChHandleBulkSrc_loop,
CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleBulkSrc_loop, CY_FX_BULKSRCSINK_DMA_TX_SIZE);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer failed, Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The DMA configuration for MANUAL OUT DMA channel seems fine. Could you let us know how the switching is triggered in the firmware?
Best Regards,
AliAsgar
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear AliAsgar;
Using Vendor Request ,the mode is changed.
The main purpose to change loop-back mode is for check max throughput.As you well know because the GPIF mode is limited under 3.x Gbps,I want to monitor non-GPIF mode in same FW.
And I've seen some progress in the meantime.
Switching to loop back mode works now.
But now, When I stop FW and restart ,it cannot be restored in gpif mode again and USB must be reset. How can I handle it?
The Function "Change_to_loopback()" must be wrong,I guess.
Thank you again for your time.
---
CyBool_t
CyFxBulkADApplnUSBSetupCB (
uint32_t setupdat0, /* SETUP Data 0 */
uint32_t setupdat1 /* SETUP Data 1 */
)
(...)
if (bType == CY_U3P_USB_VENDOR_RQT)
{
if (bRequest==0x10){
switch (wValue){
case (0x01): {change_sm(CyFxGpifConfig_01);break;}// change to some Statemachine (run well)
case (0x02): {change_sm(CyFxGpifConfig_02);break;}// change to another Statemachine (run well)
.
.
case (0x05): {change_to_loopback();break;}// change to loopback mode
}
(...)
}
void change_to_loopback(){
glIsApplnActive = CyFalse;
CyU3PGpifDisable(CyTrue);
CyU3PDmaMultiChannelDestroy(&glChHandleBulkSrc);
Set_loopback_mode();
CyU3PDmaChannelReset (&glChHandleBulkSrc_loop);
CyU3PUsbFlushEp(CY_FX_EP_CONSUMER);
CyU3PUsbResetEp (CY_FX_EP_CONSUMER);
glIsApplnActive = CyTrue;
}
void Set_loopback_mode()
{
uint16_t size = 0;
CyU3PEpConfig_t epCfg;
CyU3PDmaChannelConfig_t dmaCfg;
CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
CyU3PUSBSpeed_t usbSpeed = CyU3PUsbGetSpeed();
switch (usbSpeed)
{
case CY_U3P_FULL_SPEED:
size = 64;
break;
case CY_U3P_HIGH_SPEED:
size = 512;
break;
case CY_U3P_SUPER_SPEED:
size = 1024;
break;
default:
CyU3PDebugPrint (4, "Error! Invalid USB speed.\n");
CyFxAppErrorHandler (CY_U3P_ERROR_FAILURE);
break;
}
/* Create a DMA MANUAL_IN channel for the producer socket. */
CyU3PMemSet ((uint8_t *)&dmaCfg, 0, sizeof (dmaCfg));
dmaCfg.size = (size * CY_FX_EP_BURST_LENGTH);
dmaCfg.size *=2;
dmaCfg.count = 6;
dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaCfg.cb = CyFxBulkSrcSinkDmaCallback;
dmaCfg.notification = CY_U3P_DMA_CB_CONS_EVENT;
dmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
dmaCfg.consSckId =CY_FX_EP_CONSUMER_SOCKET;
dmaCfg.prodHeader = 0;
dmaCfg.prodFooter = 0;
dmaCfg.consHeader = 0;
dmaCfg.prodAvailCount = 0;
apiRetStatus = CyU3PDmaChannelCreate (&glChHandleBulkSrc_loop,
CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleBulkSrc_loop, CY_FX_BULKSRCSINK_DMA_TX_SIZE);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer failed, Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}
CyFxBulkSrcSinkFillInBuffers ();
glIsApplnActive = CyTrue;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[Solved ] self^^
After preparing two types of start codes,
By calling the reboot_as() function, the startup code is branched by referring to the static global variable .
The reboot start address was found with the elf2img -v option.
void reboot_as(CyBool_t b_mode)
{
sw_loop_mode=b_mode;// static
CyU3PUsbAckSetup ();
CyU3PThreadSleep (2000);
CyU3PConnectState (CyFalse, CyTrue);
CyU3PThreadSleep (1000);
CyU3PUsbSetBooterSwitch (CyTrue);
CyU3PUsbJumpBackToBooter(0x4000e4e0);// from elf2img -verbose
while (1)CyU3PThreadSleep (100);
}