Is it possible to change DMA configuration while running and restart DMA?

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

cross mob
rainmen747
Level 2
Level 2
50 sign-ins 5 replies posted 25 sign-ins

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)

0 Likes
1 Solution
rainmen747
Level 2
Level 2
50 sign-ins 5 replies posted 25 sign-ins

[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);
}

View solution in original post

0 Likes
5 Replies
AliAsgar
Moderator
Moderator
Moderator
1000 replies posted 250 solutions authored 750 replies posted

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

0 Likes

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);
}

0 Likes
AliAsgar
Moderator
Moderator
Moderator
1000 replies posted 250 solutions authored 750 replies posted

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

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;

}

0 Likes
rainmen747
Level 2
Level 2
50 sign-ins 5 replies posted 25 sign-ins

[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);
}

0 Likes