📄 dma_test.c
字号:
u32 uLoopCnt = 0;
volatile u32 uMemSum =0, uMemSum0=0, uMemSum1=0, uMemSum2=0, uMemSum3=0;
u32 uDstAddrOffset = 0;
INTC_Disable(NUM_DMA0);
INTC_Disable(NUM_DMA1);
INTC_Disable(NUM_SDMA0);
INTC_Disable(NUM_SDMA1);
DMAC_InitCh(DMA0, DMA_ALL, &oDmac0);
INTC_SetVectAddr(NUM_DMA0, Dma0DoneW);
DMAC_InitCh(DMA1, DMA_ALL, &oDmac1);
INTC_SetVectAddr(NUM_DMA1, Dma1DoneW);
DMAC_InitCh(SDMA0, DMA_ALL, &oDmac2);
INTC_SetVectAddr(NUM_SDMA0, Sdma0DoneW );
DMAC_InitCh(SDMA1, DMA_ALL, &oDmac3);
INTC_SetVectAddr(NUM_SDMA1, Sdma1DoneW );
g_DmaDone0 = 0;
g_DmaDone1 = 0;
g_DmaDone2 = 0;
g_DmaDone3 = 0;
// Memory Filling
for(uLoopCnt=uTxBuffAddr;uLoopCnt<uTxBuffAddr+g_TSize;uLoopCnt+=4)
{
*((unsigned int *)uLoopCnt)=uLoopCnt;
uMemSum += uLoopCnt;
}
//-------- DMAC0 -----------
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
DMACH_Setup((DMA_CH)DMA_A, 0x0, uTxBuffAddr, 0, uRxBuffAddr0, 0, (DATA_SIZE)WORD, DMAC0TxSize, DEMAND, MEM, MEM, (BURST_MODE)BURST8, &oDmac0);
DMACH_Start(&oDmac0); // Enable DMA
INTC_Enable(NUM_DMA0);
DelayfrTimer(milli, 1000);
//-------- DMAC1 -----------
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
DMACH_Setup((DMA_CH)DMA_A, 0x0, uTxBuffAddr, 0, uRxBuffAddr1, 0, (DATA_SIZE)WORD, DMAC1TxSize, DEMAND, MEM, MEM, (BURST_MODE)BURST8, &oDmac1);
DMACH_Start(&oDmac1); // Enable DMA
INTC_Enable(NUM_DMA1);
//-------- DMAC2 -----------
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
DMACH_Setup((DMA_CH)DMA_A, 0x0, uTxBuffAddr, 0, uRxBuffAddr2, 0, (DATA_SIZE)WORD, SDMAC0TxSize, DEMAND, MEM, MEM, (BURST_MODE)BURST8, &oDmac2);
DMACH_Start(&oDmac2); // Enable DMA
INTC_Enable(NUM_SDMA0);
//-------- DMAC3 -----------
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
DMACH_Setup((DMA_CH)DMA_A, 0x0, uTxBuffAddr, 0, uRxBuffAddr3, 0, (DATA_SIZE)WORD, SDMAC1TxSize, DEMAND, MEM, MEM, (BURST_MODE)BURST8, &oDmac3);
DMACH_Start(&oDmac3); // Enable DMA
INTC_Enable(NUM_SDMA1);
Disp("Waiting Transfer Count Interrupt\n");
// while(g_DmaDone0<(g_TSize/DMAC0TxSize)||g_DmaDone1<(g_TSize/DMAC1TxSize)|g_DmaDone2<(g_TSize/SDMAC0TxSize)|g_DmaDone3<(g_TSize/SDMAC1TxSize));
while(g_DmaDone1<(g_TSize/DMAC1TxSize)|g_DmaDone2<(g_TSize/SDMAC0TxSize)|g_DmaDone3<(g_TSize/SDMAC1TxSize));
Disp("DMAC0 Test ==========================\n");
uDstAddrOffset = 0;
for(uLoopCnt=uRxBuffAddr0;uLoopCnt<(uRxBuffAddr0+g_TSize);uLoopCnt+=4) //Compare source data with destination data
{
if(*((unsigned int *)uLoopCnt) != (uTxBuffAddr+uDstAddrOffset))
{
Disp("Error!!! Src value=%x, Addr %x=%x\n",uTxBuffAddr+uDstAddrOffset,uLoopCnt,*((unsigned int *)uLoopCnt));
}
uMemSum0+=*((unsigned int *)uLoopCnt);
uDstAddrOffset += 4;
}
Disp("DMAC1 Test ==========================\n");
uDstAddrOffset = 0;
for(uLoopCnt=uRxBuffAddr1;uLoopCnt<(uRxBuffAddr1+g_TSize);uLoopCnt+=4) //Compare source data with destination data
{
if(*((unsigned int *)uLoopCnt) != (uTxBuffAddr+uDstAddrOffset))
{
Disp("Error!!! Src value=%x, Addr %x=%x\n",uTxBuffAddr+uDstAddrOffset,uLoopCnt,*((unsigned int *)uLoopCnt));
}
uMemSum1 += *((unsigned int *)uLoopCnt);
uDstAddrOffset += 4;
}
Disp("SDMAC0 Test ==========================\n");
uDstAddrOffset = 0;
for(uLoopCnt=uRxBuffAddr2;uLoopCnt<(uRxBuffAddr2+g_TSize);uLoopCnt+=4) //Compare source data with destination data
{
if(*((unsigned int *)uLoopCnt) != (uTxBuffAddr+uDstAddrOffset))
{
Disp("Error!!! Src value=%x, Addr %x=%x\n",uTxBuffAddr+uDstAddrOffset,uLoopCnt,*((unsigned int *)uLoopCnt));
}
uMemSum2+=*((unsigned int *)uLoopCnt);
uDstAddrOffset += 4;
}
Disp("SDMAC1 Test ==========================\n");
uDstAddrOffset = 0;
for(uLoopCnt=uRxBuffAddr3;uLoopCnt<(uRxBuffAddr3+g_TSize);uLoopCnt+=4) //Compare source data with destination data
{
if(*((unsigned int *)uLoopCnt) != (uTxBuffAddr+uDstAddrOffset))
{
Disp("Error!!! Src value=%x, Addr %x=%x\n",uTxBuffAddr+uDstAddrOffset,uLoopCnt,*((unsigned int *)uLoopCnt));
}
uMemSum3+=*((unsigned int *)uLoopCnt);
uDstAddrOffset += 4;
}
Disp("memSum=%x,memSum0=%x\n",uMemSum,uMemSum0);
Disp("memSum=%x,memSum1=%x\n",uMemSum,uMemSum1);
Disp("memSum=%x,memSum2=%x\n",uMemSum,uMemSum2);
Disp("memSum=%x,memSum3=%x\n",uMemSum,uMemSum3);
if(uMemSum==uMemSum0)
Disp("DMAC0 test result......................O.K.\n");
else
Disp("DMAC0 test result......................ERROR.\n");
if(uMemSum==uMemSum1)
Disp("DMAC1 test result......................O.K.\n");
else
Disp("DMAC1 test result......................ERROR.\n");
if(uMemSum==uMemSum2)
Disp("SDMAC0 test result......................O.K.\n");
else
Disp("SDMAC0 test result......................ERROR.\n");
if(uMemSum==uMemSum3)
Disp("SDMAC1 test result......................O.K.\n");
else
Disp("SDMAC1 test result......................ERROR.\n");
}
//////////
// Function Name : DMAT_External
// Function Description : External DMA Test
// Input : None
// Output : None
// Version : v0.1
static void DMAT_External(void)
{
u32 i;
u8 ucExitKey=0;
g_DmaDone=0;
GPIO_SetFunctionEach(eGPIO_F,eGPIO_13,1);
GPIO_SetDataEach(eGPIO_F, eGPIO_13 , 1); //GPF[13] -> High
// GPIO_SetFunctionEach(eGPIO_B, eGPIO_0, 3); // set XuRXD[2]/XexdREQ/XirRXD/ADDR_CF[0]/GPB[0] as XexdREQ
// GPIO_SetFunctionEach(eGPIO_B, eGPIO_1, 3); // set XuTXD[2]/XexdACK/XirTXD/ADDR_CF[1]/GPB[1] as XexdACK
GPIO_SetFunctionEach(eGPIO_B, eGPIO_2, 4); // set XuRXD[3]/IrDARXD/XexdREQ/ADDR_CF[2]/GPB[2] as XexdREQ
GPIO_SetFunctionEach(eGPIO_B, eGPIO_3, 4); // set XuTXD[3]/IrDATXD/XexdACK/ADDR_CF[3]/GPB[3] as XexdACK
Disp("Selected DMAC 1 ..... \n");
SYSC_SelectDMA(eSEL_EXTERNAL, 1);
DMAC_InitCh(DMA1, DMA_ALL, &oDmac1);
INTC_SetVectAddr(NUM_DMA1, Dma1Done);
INTC_Enable(NUM_DMA1);
DMACH_ClearErrIntPending(&oDmac1);
DMACH_ClearIntPending(&oDmac1);
#if 0
Disp("\nSelect Transfer Size [1~0x200_0000] : ");
uDataCnts=GetIntNum();
Disp("\n");
#else
uDataCnts=100;
#endif
// 0. Clear the rx/tx buf.
for (i = 0; i<(uDataCnts*WORD+16); i++)
{
*(u8 *)(uRxBuffAddr+i) = 0;
*(u8 *)(uTxBuffAddr+i) = 0;
}
// 1. Set up the tx buf.
for (i = 0; i<uDataCnts*WORD; i++)
*(u8 *)(uTxBuffAddr+i) = (u8)(i+2)%0xff;
// uRxBuffAddr = 0x7f006010;
uRxBuffAddr = 0x54000000;
// Disp("uRxBuffAddr:0x%x\n", uRxBuffAddr);
DMACH_Setup((DMA_CH)DMA_A, 0x0, 0x51000000, 0, uRxBuffAddr, 0, (DATA_SIZE)WORD, uDataCnts, DEMAND, DMA1_EXTERNAL, MEM, (BURST_MODE)BURST8, &oDmac1);
// Enable DMA
DMACH_Start(&oDmac1);
#if 0
Disp("DMA doesn't send request not yet. Now sending...\n");
Getc();
DMACH_SoftBurstReq(&oDmac1, DMA1_EXTERNAL); // SoftWare Burst Request to DMA1_PWM source
Disp("DMA request was sent.\n");
#endif
Disp("Waiting the response of External DMA Request..... ");
while(g_DmaDone==0) // Int.
{
ucExitKey = Getc();
if(ucExitKey == 'r')
{
Disp("Ext. DMA Request Low\n");
GPIO_SetDataEach(eGPIO_F, eGPIO_13 , 0); //GPB[0] -> Low
}
else if(ucExitKey == 'e')
{
Disp("Ext. DMA Request High\n");
GPIO_SetDataEach(eGPIO_F, eGPIO_13 , 1); //GPB[0] -> High
}
else if(ucExitKey == 'x')
{
break;
}
}
Disp("OK!! \n");
if (CompareDMA(uTxBuffAddr, uRxBuffAddr, (DATA_SIZE)WORD, uDataCnts))
Disp(" >> Test Tx&Rx -> Ok << \n");
else
{
Disp(" >>*** Tx-data & Rx-data mismatch ***<< \n");
}
INTC_Disable(NUM_DMA1);
DMAC_Close(DMA1, DMA_ALL, &oDmac1);
}
void TestGPIO(void)
{
s32 iGPIOSel = 0;
s32 iGPIOPortSel = 0;
GPIO_eId eGPIOId = eGPIO_D;
Disp("\nSelect GPIO : 0:GPD, 1:GPE");
iGPIOSel=GetIntNum();
Disp("\n");
Disp("\nSelect GPIO Port: 0:Port0, 1:Port1, 2:Port2, 3:Port3, 4:Port4");
iGPIOPortSel=GetIntNum();
Disp("\n");
eGPIOId = (GPIO_eId)((u32)eGPIO_D + iGPIOSel*2);
GPIO_SetFunctionEach(eGPIOId,(GPIO_eBitPos)iGPIOPortSel,1); // GPD[0] -> output
GPIO_SetDataEach(eGPIOId, (GPIO_eBitPos)iGPIOPortSel, 0); //GPD[0] -> Low
GPIO_SetDataEach(eGPIOId, (GPIO_eBitPos)iGPIOPortSel , 1); //GPD[0] -> High
GPIO_SetDataEach(eGPIOId, (GPIO_eBitPos)iGPIOPortSel , 0); //GPD[0] -> Low
}
///////////////////////////////////////////////////////////////////////////////////
//////////////////// DMA Full Test ///////////////////////////
///////////////////////////////////////////////////////////////////////////////////
#define MAX_DMA_CNT 0x7D000*5 // (20MB)
//#define MAX_DMA_CNT 0x200
//////////
// Function Name : DMAT_FullFunction
// Function Description : DMA full function test
// Input : None
// Version : v0.1
void DMAT_FullFunction(void)
{
u32 i, j, k,uNumClock, uNumOndMode;
u32 *puTxDataBuffer, *puRxDataBuffer;
u32 uIntSrcNo = NUM_DMA0;
DMA_UNIT eDmaUnit = DMA0;
DMA_CH eDmaCh = DMA_A;
BURST_MODE eBurstMode = BURST4;
u32 uDataCnts = 0;
//{Sync Mode, APLL, MPLL, HCLKx2 divide, HCLK divide, Flash CLK divide, SMCLK divide}
u32 aCaseOfClock[][7] = { //Sync Mode
#if 0
{eSYNC_MODE, eAPLL400M, eAPLL200M, 2, 2, 2, 2},
{eSYNC_MODE, eAPLL400M, eAPLL200M, 2, 2, 3, 2},
{eSYNC_MODE, eAPLL400M, eAPLL200M, 2, 2, 4, 2},
{eSYNC_MODE, eAPLL400M, eAPLL200M, 4, 2, 2, 2},
{eSYNC_MODE, eAPLL400M, eAPLL200M, 4, 2, 3, 2},
{eSYNC_MODE, eAPLL400M, eAPLL200M, 4, 2, 4, 2},
{eSYNC_MODE, eAPLL532M, eAPLL266M, 2, 2, 2, 2},
{eSYNC_MODE, eAPLL532M, eAPLL266M, 2, 2, 3, 2},
{eSYNC_MODE, eAPLL532M, eAPLL266M, 2, 2, 4, 2},
{eSYNC_MODE, eAPLL532M, eAPLL266M, 4, 2, 2, 2},
{eSYNC_MODE, eAPLL532M, eAPLL266M, 4, 2, 3, 2},
{eSYNC_MODE, eAPLL532M, eAPLL266M, 4, 2, 4, 2},
#endif
//Async Mode
{eASYNC_MODE, eAPLL400M, eAPLL400M, 2, 2, 2, 2},
{eASYNC_MODE, eAPLL400M, eAPLL400M, 2, 2, 3, 2},
{eASYNC_MODE, eAPLL400M, eAPLL400M, 2, 2, 4, 2},
{eASYNC_MODE, eAPLL400M, eAPLL400M, 4, 2, 2, 2},
{eASYNC_MODE, eAPLL400M, eAPLL400M, 4, 2, 3, 2},
{eASYNC_MODE, eAPLL400M, eAPLL400M, 4, 2, 4, 2},
{eASYNC_MODE, eAPLL532M, eAPLL400M, 2, 2, 2, 2},
{eASYNC_MODE, eAPLL532M, eAPLL400M, 2, 2, 3, 2},
{eASYNC_MODE, eAPLL532M, eAPLL400M, 2, 2, 4, 2},
{eASYNC_MODE, eAPLL532M, eAPLL400M, 4, 2, 2, 2},
{eASYNC_MODE, eAPLL532M, eAPLL400M, 4, 2, 3, 2},
{eASYNC_MODE, eAPLL532M, eAPLL400M, 4, 2, 4, 2},
{eASYNC_MODE, eAPLL532M, eAPLL532M, 2, 2, 2, 2},
{eASYNC_MODE, eAPLL532M, eAPLL532M, 2, 2, 3, 2},
{eASYNC_MODE, eAPLL532M, eAPLL532M, 2, 2, 4, 2},
{eASYNC_MODE, eAPLL532M, eAPLL532M, 4, 2, 2, 2},
{eASYNC_MODE, eAPLL532M, eAPLL532M, 4, 2, 3, 2},
{eASYNC_MODE, eAPLL532M, eAPLL532M, 4, 2, 4, 2} };
// {Controller, Interrupt Src, Channel, Burst, Data Cnt}
u32 aCaseOfDMAMode[][5] = { {DMA0, NUM_DMA0, DMA_A, BURST4, MAX_DMA_CNT}, // 0x200(512) * WORD = 2K
{DMA0, NUM_DMA0, DMA_B, BURST8, MAX_DMA_CNT}, // 0x200(512) * WORD = 2K
{DMA0, NUM_DMA0, DMA_C, BURST16, MAX_DMA_CNT}, // 0x200(5120) * WORD = 20K
{DMA0, NUM_DMA0, DMA_D, BURST32, MAX_DMA_CNT}, // 0x200(5120) * WORD = 20K
{DMA0, NUM_DMA0, DMA_E, BURST64, MAX_DMA_CNT}, // 0xC800(51200) * WORD = 200K
{DMA0, NUM_DMA0, DMA_F, BURST128, MAX_DMA_CNT}, // 0xC800(51200) * WORD = 200K
{DMA0, NUM_DMA0, DMA_G, BURST256, MAX_DMA_CNT}, // 0x7D000(512000) * WORD = 2M
{DMA0, NUM_DMA0, DMA_H, BURST256, MAX_DMA_CNT}, // 0x7D000(512000) * WORD = 2M
{DMA1, NUM_DMA1, DMA_A, BURST4, MAX_DMA_CNT}, // 0x200(512) * WORD = 2K
{DMA1, NUM_DMA1, DMA_B, BURST8, MAX_DMA_CNT}, // 0x200(512) * WORD = 2K
{DMA1, NUM_DMA1, DMA_C, BURST16, MAX_DMA_CNT}, // 0x200(5120) * WORD = 20K
{DMA1, NUM_DMA1, DMA_D, BURST32, MAX_DMA_CNT}, // 0x200(5120) * WORD = 20K
{DMA1, NUM_DMA1, DMA_E, BURST64, MAX_DMA_CNT}, // 0xC800(51200) * WORD = 200K
{DMA1, NUM_DMA1, DMA_F, BURST128, MAX_DMA_CNT}, // 0xC800(51200) * WORD = 200K
{DMA1, NUM_DMA1, DMA_G, BURST256, MAX_DMA_CNT}, // 0x7D000(512000) * WORD = 2M
{DMA1, NUM_DMA1, DMA_H, BURST256, MAX_DMA_CNT}, // 0x7D000(512000) * WORD = 2M
};
uNumClock = sizeof(aCaseOfClock)/sizeof(aCaseOfClock[0]);
uNumOndMode = sizeof(aCaseOfDMAMode)/sizeof(aCaseOfDMAMode[0]);
puTxDataBuffer = (u32 *)malloc(MAX_DMA_CNT*WORD);
puRxDataBuffer = (u32 *)malloc(MAX_DMA_CNT*WORD);
// 1. Set up the tx buf.
for (k = 0; k<MAX_DMA_CNT*WORD; k++)
*((u8 *)puTxDataBuffer+k) = (u8)(k+2)%0xff;
for(i=0 ; i<uNumClock ; i++)
{
if(aCaseOfClock[i][0] == eSYNC_MODE)
{
SYSC_ChangeMode(eSYNC_MODE);
SYSC_ChangeSYSCLK_1((APLL_eOUT)aCaseOfClock[i][1], (APLL_eOUT)aCaseOfClock[i][2], 0, 1, 3);
SYSC_SetDIV0(0, 1, aCaseOfClock[i][4]-1, aCaseOfClock[i][3]-1, 3, aCaseOfClock[i][5]-1, 1,0, 1, 0);
SYSC_GetClkInform();
OpenConsole();
UART_Printf("\n\n");
UART_Printf("====================================================================\n");
UART_Printf("Sync Mode : Synchronous\n");
UART_Printf("ARMCLK : HCLK : FlashCLK : SMCLK = %d : %d : %d : %d MHz\n",
g_ARMCLK/1000000, g_HCLK/1000000,
g_ARMCLK/(1000000*aCaseOfClock[i][3]*aCaseOfClock[i][5]),
g_ARMCLK/(1000000*aCaseOfClock[i][3]*aCaseOfClock[i][5]*aCaseOfClock[i][6]) );
}
else // Async Mode
{
SYSC_ChangeMode(eASYNC_MODE);
SYSC_ChangeSYSCLK_1((APLL_eOUT)aCaseOfClock[i][1], (APLL_eOUT)aCaseOfClock[i][2], 0, 1, 3);
SYSC_SetDIV0(0, 1, aCaseOfClock[i][4]-1, aCaseOfClock[i][3]-1, 3, aCaseOfClock[i][5]-1, 1,0, 1, 0);
SYSC_GetClkInform();
OpenConsole();
UART_Printf("\n\n");
UART_Printf("====================================================================\n");
UART_Printf("Sync Mode : Asynchronous\n");
UART_Printf("ARMCLK : HCLK : FlashCLK : SMCLK = %d : %d : %d : %d MHz (MPLL : %d MHz)\n",
g_ARMCLK/1000000, g_HCLK/1000000,
g_MPLL/(1000000*aCaseOfClock[i][3]*aCaseOfClock[i][5]),
g_MPLL/(1000000*aCaseOfClock[i][3]*aCaseOfClock[i][5]*aCaseOfClock[i][6]), g_MPLL );
}
UART_Printf("\n");
for(j=0 ; j<uNumOndMode ; j++)
{
uIntSrcNo = aCaseOfDMAMode[j][1];
eDmaUnit = (DMA_UNIT)aCaseOfDMAMode[j][0];
eDmaCh = (DMA_CH)aCaseOfDMAMode[j][2];
eBurstMode = (BURST_MODE)aCaseOfDMAMode[j][3];
uDataCnts = aCaseOfDMAMode[j][4];
// 0. Clear the rx/tx buf.
for (k = 0; k<(uDataCnts*WORD); k++)
{
*((u8 *)puRxDataBuffer+k) = 0;
}
UART_Printf("------------------------------ %d --------------------------------------\n", j);
DMAC_InitCh(eDmaUnit, eDmaCh, &oDmac0);
INTC_SetVectAddr(uIntSrcNo, Dma0Done);
INTC_Enable(uIntSrcNo);
DMACH_Setup((DMA_CH)eDmaCh, 0x0, (u32)puTxDataBuffer, 0, (u32)puRxDataBuffer, 0, (DATA_SIZE)WORD, uDataCnts, DEMAND, MEM, MEM, (BURST_MODE)eBurstMode, &oDmac0);
// Enable DMA
DMACH_Start(&oDmac0);
while(g_DmaDone==0); // Int.
if (CompareDMA((u32)puTxDataBuffer, (u32)puRxDataBuffer, (DATA_SIZE)WORD, uDataCnts))
{
Disp(" >> Test Tx&Rx -> Ok << \n");
}
else
{
Disp(" >>*** Tx-data & Rx-data mismatch ***<< \n");
}
INTC_Disable(uIntSrcNo);
DMAC_Close(eDmaUnit, eDmaCh, &oDmac0);
}
UART_Printf("====================================================================\n");
}
}
///////////////////////////////////////////////////////////////////////////////////
//////////////////// DMA Main Test ///////////////////////////
///////////////////////////////////////////////////////////////////////////////////
const testFuncMenu dma_menu[] =
{
0, "Exit",
Mem_dump, "Memory dump ",
DMAT_MemtoMem, "Test DMA From Mem To Mem",
DMAT_MemtoMemLLI, "Test DMA LLI From Mem To Mem",
DMAT_SoftReq, "Test DMA Software Request",
DMAT_WorstCase, "Test 4 DMAs concurrently",
DMAT_External, "Test External DMA through Modem I/F",
// DMAT_ExternalDMAReq, "Test External DMA Request",
DMAT_FullFunction, "Test DMA Full Function",
// TestGPIO, "Test GPIO ",
0,0
};
void Test_DMA(void)
{
u32 i;
s32 uSel;
printf("[DMA_Test]\n\n");
while(1)
{
for (i=0; (u32)(dma_menu[i].desc)!=0; i++)
printf("%2d: %s\n", i, dma_menu[i].desc);
printf("\nSelect the function to test : ");
uSel =GetIntNum();
printf("\n");
if(uSel == -1)
break;
if (uSel==0)
break;
if (uSel>=0 && uSel<(sizeof(dma_menu)/8-1))
(dma_menu[uSel].func) ();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -