📄 dma.c
字号:
/*
* GDMA memory to memory test submodule
*/
void GdmaMem2Mem(unsigned gdma_channel)
{
// GDMA related register all clear to reset state
GdmaReset(gdma_channel);
rGDMA.CON |= GDMA_RUN|GDMA_INT_ENABLE|GDMA_MEM2MEM;
GDMARegWrite(gdma_channel);
}
void GdmaTxWidth(int width)
{
switch(width) {
case 0:rGDMA.CON=(rGDMA.CON&~GDMA_NO_USE)|GDMA_TX_BYTE; break;
case 1:rGDMA.CON=(rGDMA.CON&~GDMA_NO_USE)|GDMA_TX_HALFWORD; break;
case 2:rGDMA.CON=(rGDMA.CON&~GDMA_NO_USE)|GDMA_TX_WORD; break;
default: rGDMA.CON|=GDMA_NO_USE;
}
}
/* Setup memory to memory gdma transfer */
void SetUpmem2mem(void)
{
Print("\r>>Input Destination Address[0x1200000]> 0x");
rGDMA.DST = get_num() ;
if (rGDMA.DST==0) rGDMA.DST=(U32)DmaTestDest; //default destination addr
Print("\r>>Input source Address[0x1100000]> 0x");
rGDMA.SRC = get_num() ;
if (rGDMA.SRC==0) rGDMA.SRC=(U32)DmaTestSrc; //default source addr
Print("\r>>Input Memory Test Size[0x10000]> 0x") ;
rGDMA.CNT = get_num() ;
if (rGDMA.CNT==0) rGDMA.CNT=(U32)DmaTestSize;
}
/*
* Initialize GDMA control register
*/
void GdmaReset(unsigned gdma_channel)
{
if(gdma_channel) {
GDMASRC1 = 0;
GDMADST1 = 0;
GDMACNT1 = 0;
GDMACON1 = 0;
}
else {
GDMASRC0 = 0;
GDMADST0 = 0;
GDMACNT0 = 0;
GDMACON0 = 0;
}
}
/*
* GDMA Run enable /disable control
*/
void GdmaRunEnable(unsigned gdma_channel)
{
if(gdma_channel)
GDMA1_RUN_ENABLE = 1 ;
else
GDMA0_RUN_ENABLE = 1 ;
}
/*
* GDMA Interrupt enable & disable and clear transfer done flag
*/
void GdmaIntEnable(unsigned gdma_channel)
{
if(gdma_channel) {
Enable_Int(nGDMA1_INT);
Gdma1DoneFlag = 0;
}
else {
Enable_Int(nGDMA0_INT);
Gdma0DoneFlag = 0;
}
Enable_Int(nGLOBAL_INT);
}
void GdmaIntDisable(unsigned gdma_channel)
{
if(gdma_channel) {
Disable_Int(nGDMA1_INT);
Gdma1DoneFlag = 0;
}
else {
Disable_Int(nGDMA0_INT);
Gdma0DoneFlag = 0;
}
}
/******************************************************************/
/* GDMA0, GDMA1 Interrupt Service Routines */
/******************************************************************/
void GDMA0isr(void)
{
//Clear_PendingBit(nGDMA0_INT) ;
//UARTPollInit(CONSOLE); // Change UART mode to polling
#if DEBUG
switch((GDMACON0&GDMA_NO_USE)>>12) {
case 0: Print("\rGDMA0:BYTE TRANSFER IS DONE! "); break;
case 1: Print("\rGDMA0:HALFWORD TRANSFER IS DONE! "); break;
case 2: Print("\rGDMA0:WORD TRANSFER IS DONE! "); break;
default: Print("\rGDMA0:NO USE TRANSFER IS MODE! "); break;
}
switch((GDMACON0&GDMA_MODE)>>2) {
case 0: Print("\rTRANSFER MODE IS SOFTWARE."); break;
case 1: Print("\rTRANSFER MODE IS EXTDREQ."); break;
case 2: Print("\rTRANSFER MODE IS UART0."); break;
case 3: Print("\rTRANSFER MODE IS UART1.");
}
GdmaReset(GDMA0);
#endif
Gdma0DoneFlag = 1;
}
void GDMA1isr(void)
{
//Clear_PendingBit(nGDMA1_INT) ;
#if DEBUG
switch((GDMACON1&GDMA_NO_USE) >>12) {
case 0: Print("\rGDMA1:BYTE TRANSFER IS DONE!"); break;
case 1: Print("\rGDMA1:HALFWORD TRANSFER IS DONE!"); break;
case 2: Print("\rGDMA1:WORD TRANSFER IS DONE!"); break;
default: Print("\rGDMA1:NO USE TRANSFER IS MODE!"); break;
}
switch((GDMACON1&GDMA_MODE)>>2) {
case 0: Print("\rTRANSFER MODE IS SOFTWARE."); break;
case 1: Print("\rTRANSFER MODE IS EXTDREQ."); break;
case 2: Print("\rTRANSFER MODE IS UART0."); break;
case 3: Print("\rTRANSFER MODE IS UART1.");
}
GdmaReset(GDMA1);
#endif
Gdma1DoneFlag = 1;
}
/******************************************************************/
/* GDMA0, GDMA1 Test Utility Functions */
/******************************************************************/
void DisplayGdma(unsigned gdma_channel)
{
U32 gdmacnt;
if(gdma_channel) gdmacnt = GDMACNT1;
else gdmacnt = GDMACNT0;
IOPDATA = ~(gdmacnt%4);
}
/*
* GDMA Configuration viewer
*/
void GDMAConfigView(void)
{
unsigned channel;
channel = GetGdmaChannel();
GDMARegRead(channel);
Print("\r\r===============================================\r");
Print(">>> GDMA%d CONTROL REGISTER CONTENTS <<<\r",channel);
Print("===============================================\r\r");
if(rGDMA.CON&GDMA_RUN)
Print("* GDMA%d Run enabled.\r",channel);
else
Print("* GDMA%d Run disabled.\r",channel);
if(rGDMA.CON&GDMA_BUSY)
Print("* GDMA%d is IDLE state.\r",channel);
else
Print("* GDMA%d is ACTIVE state.\r",channel);
switch(rGDMA.CON&GDMA_MODE) {
case 0x0004: Print("* GDMA%d:External DMA Request mode.\r",channel); break;
case 0x0008: Print("* GDMA%d:UART0 Mode.\r",channel); break;
case 0x000C: Print("* GDMA%d:UART1 Mode.\r",channel); break;
default : Print("* GDMA%d:Memory to Memory mode.\r",channel); break;
}
if(rGDMA.CON&GDMA_DST_DEC)
Print("* GDMA%d: Decrease detination address.\r",channel);
else
Print("* GDMA%d: Increase detination address.\r",channel);
if(rGDMA.CON&GDMA_SRC_DEC)
Print("* GDMA%d: Decrease source address.\r",channel);
else
Print("* GDMA%d: Increase source address.\r",channel);
if(rGDMA.CON&GDMA_DST_FIX)
Print("* GDMA%d: Do not change destination address.\r",channel);
else
Print("* GDMA%d: Increase/Decrease destination address.\r",channel);
if(rGDMA.CON&GDMA_SRC_FIX)
Print("* GDMA%d: Do not change source address.\r",channel);
else
Print("* GDMA%d: Increase/Decrease source address.\r",channel);
if(rGDMA.CON&GDMA_INT_ENABLE)
Print("* GDMA%d: Generate stop interrupt when GDMA stop.\r",channel);
else
Print("* GDMA%d: Do not generate stop interrupt when GDMA stop.\r",channel);
if(rGDMA.CON&GDMA_RESET)
Print("* GDMA%d: RESET Gdma control register.\r",channel);
else
Print("* GDMA%d: Normal operation.\r",channel);
if(rGDMA.CON&GDMA_MEM2UART)
Print("* GDMA%d: UART0/UART1 to Memory.\r",channel);
else
Print("* GDMA%d: Memory to UART0/UART1.\r",channel);
if(rGDMA.CON&GDMA_BLOCK)
Print("* GDMA%d: Block Mode.\r",channel);
else
Print("* GDMA%d: Single Mode.\r",channel);
switch(rGDMA.CON&GDMA_TX_WIDTH) {
case 0x0000: Print("* GDMA%d:Transfer width is BYTE.\r",channel); break;
case 0x1000: Print("* GDMA%d:Transfer width is HALFWORD.\r",channel); break;
case 0x2000: Print("* GDMA%d:Transfer width is WORD.\r",channel); break;
default : Print("* GDMA%d:No Use.\r",channel); break;
}
if(rGDMA.CON&GDMA_CONTINUOUS)
Print("* GDMA%d: Continuous mode.\r",channel);
else
Print("* GDMA%d: Normal operation.\r",channel);
if(rGDMA.CON&GDMA_DEMAND)
Print("* GDMA%d: Demand mode.\r",channel);
else
Print("* GDMA%d: Normal operation.\r",channel);
Print("===============================================\r");
Print(" GDMA REGISTER VIEW \r");
Print("===============================================\r");
Print(">>> GDMACON%d = 0x%08x\r",channel,rGDMA.CON);
Print(">>> GDMASRC%d = 0x%08x\r",channel,rGDMA.SRC);
Print(">>> GDMADST%d = 0x%08x\r",channel,rGDMA.DST);
Print(">>> GDMACNT%d = 0x%08x\r",channel,rGDMA.CNT);
Print("===============================================\r\r");
}
// DMA Copy using Interrupt
void dcopy(uint32 dmadst, uint32 dmasrc,int Size, int Width)
{
uint32 DMA_CON_SET ;
Disable_Int(nGDMA0_INT); /* Disable GDMA 0 interupt */
SysSetInterrupt(nGDMA0_INT, GDMA0isr); /* Vector setup */
Gdma0DoneFlag = 0; /* GDMA transmit done flag */
GDMASRC0 = dmasrc;
GDMADST0 = dmadst;
GDMACNT0 = Size;
DMA_CON_SET = GDMA_MEM2MEM ;
switch(Width) {
case 0 : DMA_CON_SET |= GDMA_WIDTH_BTYE; break;
case 1 : DMA_CON_SET |= GDMA_WIDTH_HWORD; break;
case 2 :
default: DMA_CON_SET |= GDMA_WIDTH_WORD; break;
}
Enable_Int(nGDMA0_INT); /* Enable GDMA 0 interrupt */
GDMACON0 = DMA_CON_SET | GDMA_RUN; /* Start run GDMA0 */
// By Interrupt Mode
while(!Gdma0DoneFlag) ;
}
// DMA Copy without Interrupt
void dcopy1(U32 dmadst, U32 dmasrc,int Size, int Width)
{
long DMA_CON_SET ;
GDMASRC1 = dmasrc;
GDMADST1 = dmadst;
GDMACNT1 = Size;
DMA_CON_SET = GDMA_MEM2MEM ;
switch(Width) {
case 0 : DMA_CON_SET |= GDMA_WIDTH_BTYE; break;
case 1 : DMA_CON_SET |= GDMA_WIDTH_HWORD; break;
case 2 :
default: DMA_CON_SET |= GDMA_WIDTH_WORD; break;
}
GDMACON1 = DMA_CON_SET | GDMA_RUN;
while(!Gdma1DoneFlag) ;
}
// DMA auto test
int DmaAutoTest(U32 src,U32 dst,int tsize,int lsize)
{
int i ;
// For use non-cacheable area
src |= 0x4000000 ;
src |= 0x4000000 ;
// Word Test
MemTestInit((U32 *)src, tsize);
Print("\n ++ DMA Channel 0 Test (Long) .... ");
for (i=0 ; i < lsize ; i++)
{
dcopy(src, dst, tsize,TxWORD) ;
if ( !wcomp((U32 *)src, (U32 *)dst, tsize) )
{
Print(" Fail !!") ;
return MemTestFail ;
}
PrintMemTestStatus(i%4) ;
}
Print("Ok") ;
// Half Word Test
Print("\r ++ DMA Channel 0 Test (Short) ... ") ;
for (i=0 ; i < lsize ; i++)
{
dcopy(src, dst, tsize,TxHWORD) ;
if ( !scomp((U16 *)src, (U16 *)dst, tsize) )
{
Print(" Fail !!") ;
return MemTestFail ;
}
PrintMemTestStatus(i%4) ;
}
Print("Ok") ;
// Byte Test
Print("\r ++ DMA Channel 0 Test (Byte) .... ") ;
for (i=0 ; i < lsize ; i++)
{
dcopy(src, dst, tsize,TxBYTE) ;
if ( !bcomp((U8 *)src, (U8 *)dst, tsize) )
{
Print(" Fail !!") ;
return MemTestFail ;
}
PrintMemTestStatus(i%4) ;
}
Print("Ok") ;
// Word Test
Print("\n ++ DMA Channel 1 Test (Long) .... ");
for (i=0 ; i < lsize ; i++)
{
dcopy1(src, dst, tsize,TxWORD) ;
if ( !wcomp((U32 *)src, (U32 *)dst, tsize) )
{
Print(" Fail !!") ;
return MemTestFail ;
}
PrintMemTestStatus(i%4) ;
}
Print("Ok") ;
// Half Word Test
Print("\r ++ DMA Channel 1 Test (Short) ... ") ;
for (i=0 ; i < lsize ; i++)
{
dcopy1(src, dst, tsize,TxHWORD) ;
if ( !scomp((U16 *)src, (U16 *)dst, tsize) )
{
Print(" Fail !!") ;
return MemTestFail ;
}
PrintMemTestStatus(i%4) ;
}
Print("Ok") ;
// Byte Test
Print("\r ++ DMA Channel 1 Test (Byte) .... ") ;
for (i=0 ; i < lsize ; i++)
{
dcopy1(src, dst, tsize,TxBYTE) ;
if ( !bcomp((U8 *)src, (U8 *)dst, tsize) )
{
Print(" Fail !!") ;
return MemTestFail ;
}
PrintMemTestStatus(i%4) ;
}
Print("Ok") ;
return MemTestOk ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -