test_dma.c

来自「arm9.rar」· C语言 代码 · 共 221 行

C
221
字号
/*****************************************
  NAME: dma.c
  DESC: DMA memory2memory test
  HISTORY:
  2001.03.31:purnnamu: draft ver 0.0
 *****************************************/

//#include <string.h>
#include "def.h"
//#include "option.h"
#include "2410addr.h"
//#include "2410lib.h"
//#include "2410slib.h" 
#include "board.h"
#include "utils.h"

#define	_NONCACHE_STARTADDRESS	0x31000000
#define	Uart_Printf				printf

#define ONESEC0 (62500)	             //16us resolution, max 1.04 sec
#define ONESEC1 (31250)	             //32us resolution, max 2.09 sec
#define ONESEC2 (15625)	             //64us resolution, max 4.19 sec
#define ONESEC3 (7812)	             //128us resolution, max 8.38 sec
#define ONESEC4 (PCLK/128/(0xff+1))  //@60Mhz, 128*4us resolution, max 32.53 sec

//========================*[ Timer ]==============================**
void Timer_Start(int divider)  //0:16us,1:32us 2:64us 3:128us
{
    rWTCON = ((GetMasterClock()/1000000-1)<<8)|(divider<<3);  //Watch-dog timer control register
    rWTDAT = 0xffff;  //Watch-dog timer data register
    rWTCNT = 0xffff;  //Watch-dog count register

      //Watch-dog timer enable & interrupt  disable
//    rWTCON = rWTCON |(1<<5) & !(1<<2);  //?
    rWTCON = rWTCON | (1<<5) | ~(1<<2);  //May 06, 2002 SOP
}

//=================================================================
int Timer_Stop(void)
{
    rWTCON = ((GetMasterClock()/1000000-1)<<8);
    return (0xffff - rWTCNT);
}

//=================================================================

static void __irq Dma0Done(void);
static void __irq Dma1Done(void);
static void __irq Dma2Done(void);
static void __irq Dma3Done(void);
void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst);

typedef struct tagDMA
{
    volatile U32 DISRC;	    //0x0
    volatile U32 DISRCC;    //0x4
    volatile U32 DIDST;	    //0x8
    volatile U32 DIDSTC;    //0xc
    volatile U32 DCON;	    //0x10
    volatile U32 DSTAT;	    //0x14
    volatile U32 DCSRC;	    //0x18
    volatile U32 DCDST;	    //0x1c
    volatile U32 DMASKTRIG; //0x20
}DMA;

static volatile int dmaDone;

void Test_DMA(void)
{
    //DMA Ch 0
    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x80000,0,0); //byte,single
    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x40000,1,0); //halfword,single
    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x20000,2,0); //word,single
    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x20000,0,1); //byte,burst
    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x10000,1,1); //halfword,burst
    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000, 0x8000,2,1); //word,burst

    //DMA Ch 1
    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x80000,0,0); //byte,single
    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x40000,1,0); //halfword,single
    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x20000,2,0); //word,single
    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x20000,0,1); //byte,burst
    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x10000,1,1); //halfword,burst
    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000, 0x8000,2,1); //word,burst

    //DMA Ch 2
    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x80000,0,0); //byte,single
    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x40000,1,0); //halfword,single
    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x20000,2,0); //word,single
    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x20000,0,1); //byte,burst
    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x10000,1,1); //halfword,burst
    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000, 0x8000,2,1); //word,burst

    //DMA Ch 3
    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x80000,0,0); //byte,single
    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x40000,1,0); //halfword,single
    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x20000,2,0); //word,single
    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x20000,0,1); //byte,burst
    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000,0x10000,1,1); //halfword,burst
    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x80000, 0x8000,2,1); //word,burst   
}

static char title[] = "DMA传输实验";
static char tip[]   = "通过存储器之间的数据拷贝实验S3C2410A内部DMA通道,按ESC键返回";

//Test_DMA_Item 在 prog_entry.c 里被引用
TEST_PROGRAM_ITEM Test_DMA_Item = {
				(TEST_PROGRAM)Test_DMA, 	//入口地址
				title, 					//显示名称
				tip, 					//帮助或提示信息,可为NULL
				1};						//使用printf,puts,putch等函数时在LCD上也显示输出字符(串)


void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst)
{
    int i,time;
    volatile U32 memSum0=0,memSum1=0;
    DMA *pDMA;
    int length;
    
    length=tc*(burst ? 4:1)*((dsz==0)+(dsz==1)*2+(dsz==2)*4);
    
    Uart_Printf("[DMA%d MEM2MEM Test]\n",ch);

    switch(ch)
    {
    case 0:
    	pISR_DMA0 =(int)Dma0Done;
    	rINTMSK &=~(BIT_DMA0);  
    	pDMA = (void *)0x4b000000;
    	break;
    case 1:
    	pISR_DMA1 = (int)Dma1Done;
    	rINTMSK &= ~(BIT_DMA1);  
    	pDMA = (void *)0x4b000040;
    	break;
    case 2:
	pISR_DMA2 = (int)Dma2Done;
    	rINTMSK &= ~(BIT_DMA2);  
    	pDMA = (void *)0x4b000080;
	break;
    case 3:
        pISR_DMA3 = (int)Dma3Done;
       	rINTMSK &= ~(BIT_DMA3);  
       	pDMA = (void *)0x4b0000c0;
        break;
    }
                                                                                                                            
    Uart_Printf("DMA%d %8xh->%8xh,size=%xh(tc=%xh),dsz=%d,burst=%d\n",ch,
    		srcAddr,dstAddr,length,tc,dsz,burst);

    Uart_Printf("Initialize the src.\n");
    
    for(i=srcAddr;i<(srcAddr+length);i+=4)
    {
    	*((U32 *)i)=i^0x55aa5aa5;
    	memSum0+=i^0x55aa5aa5;
    }

    Uart_Printf("DMA%d start\n",ch);
    
    dmaDone=0;
    
    pDMA->DISRC=srcAddr;
    pDMA->DISRCC=(0<<1)|(0<<0); // inc,AHB
    pDMA->DIDST=dstAddr;
    pDMA->DIDSTC=(0<<1)|(0<<0); // inc,AHB
    pDMA->DCON=tc|(1UL<<31)|(1<<30)|(1<<29)|(burst<<28)|(1<<27)|\
    	        (0<<23)|(1<<22)|(dsz<<20)|(tc);
    		//HS,AHB,TC interrupt,whole, SW request mode,relaod off
    pDMA->DMASKTRIG=(1<<1)|1; //DMA on, SW_TRIG

    Timer_Start(3);//128us resolution	      
    while(dmaDone==0);
    time=Timer_Stop();
    
	printf("DMA%d end\n", ch);
	
//	Uart_Printf("DMA transfer done. time=%f, %fMB/S\n",(float)time/ONESEC3,
//		length/((float)time/ONESEC3)/1000000.);
    rINTMSK |= (BIT_DMA0 | BIT_DMA1 | BIT_DMA2 | BIT_DMA3);
    
    for(i=dstAddr;i<dstAddr+length;i+=4)
    {
    	memSum1+=*((U32 *)i)=i^0x55aa5aa5;
    }
    
    Uart_Printf("memSum0=%x,memSum1=%x\n",memSum0,memSum1);
    if(memSum0==memSum1)
    	Uart_Printf("DMA test result--------O.K.\n");
    else 
    	Uart_Printf("DMA test result--------ERROR!!!\n");

}


static void __irq Dma0Done(void)
{
    ClearPending(BIT_DMA0);
    dmaDone=1;
}

static void __irq Dma1Done(void)
{
    ClearPending(BIT_DMA1);
    dmaDone=1;
}

static void __irq Dma2Done(void)
{
    ClearPending(BIT_DMA2);
    dmaDone=1;
}

static void __irq Dma3Done(void)
{
    ClearPending(BIT_DMA3);
    dmaDone=1;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?