⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dma.c

📁 samsung s3c2443 dma transfer code
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************
  NAME: dma.c
  DESC: DMA memory2memory test
  HISTORY:
  2005.09.15:KIM, KI JUN: draft ver 0.0
  2006.06.02: Jeon chansik: modified
 *****************************************/
#include "System.h"
#include "Dma.h" 
#include "Dma2.h" 

void M2M_500KB_Transfer(void);
void M2M_1MB_Transfer(void);

static void __irq Dma0Done(void);
static void __irq Dma1Done(void);
static void __irq Dma2Done(void);
static void __irq Dma3Done(void);
static void __irq Dma4Done(void);
static void __irq Dma5Done(void);

void DMA_M2M(U32 ch,U32 s_addr, U32 d_addr, U32 tsz, U32 dsz, U32 tot_sz);		// handshake, whole
void DMA_M2M_loop(U32 ch,U32 s_addr, U32 d_addr, U32 tsz, U32 dsz, U32 tot_sz);

void DMA_M2M_HS_SNG(U32 ch,U32 s_addr, U32 d_addr, U32 tsz, U32 dsz, U32 tot_sz);	// handshake, single
void DMA_M2M_DM_WHL(U32 ch,U32 s_addr, U32 d_addr, U32 tsz, U32 dsz, U32 tot_sz);	// demand, whole
void DMA_M2M_DM_SNG(U32 ch,U32 s_addr, U32 d_addr, U32 tsz, U32 dsz, U32 tot_sz);	// demand, single
void M2M_Handshake_Whole(void);
void M2M_Handshake_Single(void);
void M2M_Demand_Whole(void);
void M2M_Demand_Single(void);

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
    volatile U32 DMAREQSEL; //0x24
}DMA;

static volatile int dmaDone;

void * dma_func[][2]=
{
	(void *)M2M_500KB_Transfer,		"M2M Handshake 500KB     ",
	(void *)M2M_1MB_Transfer,		"M2M Handshake 1MB        ",
	(void *)M2M_Handshake_Whole,	"M2M Handshake Whole     ",
	(void *)M2M_Handshake_Single,	"M2M Handshake Single     ",
	(void *)M2M_Demand_Whole,		"M2M Demand Whole         ",
	(void *)M2M_Demand_Single,		"M2M Demand Single         ",
	(void *)Extention_DMA_Test,		"Extention DMA Test          ",
	0,0
};

void Test_DMA(void)
{
	int i=0;

	while(1)
	{
		i=0;
		printf("\n\n");
		while(1)
		{   //display menu
			printf("%2d:%s",i,dma_func[i][1]);
			i++;
			if((int)(dma_func[i][0])==0)
			{
				printf("\n");
				break;
			}
			printf("\n");
		}

		printf("\nPress Enter key to exit : ");
		i = GetIntNum();
		if(i==-1) break;		// return.
		if(i>=0 && (i<((sizeof(dma_func)-1)/8)) )	// select and execute...
			( (void (*)(void)) (dma_func[i][0]) )();
	}

}

void M2M_500KB_Transfer(void)
{
	U32 ch;

	for(ch=0;ch<6;ch++)
	{
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, BYTE,   0x80000);	//Burst, Byte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, DBYTE, 0x80000);	//Burst, DByte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, FBYTE,  0x80000);	//Burst, FByte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,BYTE,   0x80000);	//Single, Byte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,DBYTE, 0x80000);	//Single, DByte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,FBYTE,  0x80000);	//Single, FByte, 512KB
		printf("\n");
	}
}

void M2M_1MB_Transfer(void)
{
	U32 ch;

	for(ch=0;ch<6;ch++)
	{
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x100000, BURST, BYTE,   0x100000);	//Burst, Byte, 1024KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x100000, BURST, DBYTE, 0x100000);	//Burst, DByte, 1024KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x100000, BURST, FBYTE,  0x100000);	//Burst, FByte, 1024KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x100000, SINGLE,BYTE,   0xffffc);	//Single, Byte, 1023KB
//		When 1MB is transferred, TC value is too big using for Single, Byte option

		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x100000, SINGLE,DBYTE, 0x100000);	//Single, DByte, 1024KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x100000, SINGLE,FBYTE,  0x100000);	//Single, FByte, 1024KB
		printf("\n");
	}
}

void M2M_Handshake_Whole(void)
{
	U32 ch;

	for(ch=0;ch<6;ch++)
	{
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, BYTE,   0x80000);	//Burst, Byte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, DBYTE, 0x80000);	//Burst, DByte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, FBYTE,  0x80000);	//Burst, FByte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,BYTE,   0x80000);	//Single, Byte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,DBYTE, 0x80000);	//Single, DByte, 512KB
		DMA_M2M(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,FBYTE,  0x80000);	//Single, FByte, 512KB
		printf("\n");
	}
}

void M2M_Handshake_Single(void)
{
	U32 ch;

	for(ch=0;ch<6;ch++)
	{
		DMA_M2M_HS_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, BYTE,   0x80000);	//Burst, Byte, 512KB
		DMA_M2M_HS_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, DBYTE, 0x80000);	//Burst, DByte, 512KB
		DMA_M2M_HS_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, FBYTE,  0x80000);	//Burst, FByte, 512KB
		DMA_M2M_HS_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,BYTE,   0x80000);	//Single, Byte, 512KB
		DMA_M2M_HS_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,DBYTE, 0x80000);	//Single, DByte, 512KB
		DMA_M2M_HS_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,FBYTE,  0x80000);	//Single, FByte, 512KB
	printf("\n");
	}
}

void M2M_Demand_Whole(void)
{
	U32 ch;

	for(ch=0;ch<6;ch++)
	{
		DMA_M2M_DM_WHL(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, BYTE,   0x80000);	//Burst, Byte, 512KB
		DMA_M2M_DM_WHL(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, DBYTE, 0x80000);	//Burst, DByte, 512KB
		DMA_M2M_DM_WHL(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, FBYTE,  0x80000);	//Burst, FByte, 512KB
		DMA_M2M_DM_WHL(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,BYTE,   0x80000);	//Single, Byte, 512KB
		DMA_M2M_DM_WHL(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,DBYTE, 0x80000);	//Single, DByte, 512KB
		DMA_M2M_DM_WHL(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,FBYTE,  0x80000);	//Single, FByte, 512KB
	printf("\n");
	}
}

void M2M_Demand_Single(void)
{
	U32 ch;

	for(ch=0;ch<6;ch++)
	{
		DMA_M2M_DM_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, BYTE,   0x80000);	//Burst, Byte, 512KB
		DMA_M2M_DM_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, DBYTE, 0x80000);	//Burst, DByte, 512KB
		DMA_M2M_DM_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, BURST, FBYTE,  0x80000);	//Burst, FByte, 512KB
		DMA_M2M_DM_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,BYTE,   0x80000);	//Single, Byte, 512KB
		DMA_M2M_DM_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,DBYTE, 0x80000);	//Single, DByte, 512KB
		DMA_M2M_DM_SNG(ch, _NONCACHE_STARTADDRESS, _NONCACHE_STARTADDRESS+0x80000, SINGLE,FBYTE,  0x80000);	//Single, FByte, 512KB
	printf("\n");
	}
}

void DMA_M2M(U32 ch,U32 s_addr, U32 d_addr, U32 tsz, U32 dsz, U32 tot_sz)
{
	U32 i;
	U32 tc = 0;
	volatile U32 memSum0=0,memSum1=0;
	DMA *pDMA = NULL;
	
	switch(ch)
	{
		case 0:
			pISR_DMA=(int)Dma0Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA0);  
			pDMA=(void *)0x4b000000;
			break;
		case 1:
			pISR_DMA=(int)Dma1Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA1);
			pDMA=(void *)0x4b000100;
			break;
		case 2:
			pISR_DMA=(int)Dma2Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA2);  
			pDMA=(void *)0x4b000200;
			break;
		case 3:
		    	pISR_DMA=(int)Dma3Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA3);
		   	pDMA=(void *)0x4b000300;
		    	break;
		case 4:
		    	pISR_DMA=(int)Dma4Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA4);
		   	pDMA=(void *)0x4b000400;
		    	break;
		case 5:
		    	pISR_DMA=(int)Dma5Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA5);
		   	pDMA=(void *)0x4b000500;
		    	break;
	}
	
	// tc : transfer count
	// tot_sz : Actual number of bytes to be tranferred
	// tsz = 0 @ Unit transfer,	tsz = 1 @ Burst transfer
	// dsz = 0 @ Byte,			dsz = 1 @ Half word
	// dsz = 2 @ Word
	switch(dsz)
	{
		case BYTE :
			tc=tot_sz/((tsz?4:1)*1);
			break;
		case DBYTE :
			tc=tot_sz/((tsz?4:1)*2);
			break;
		case FBYTE :
			tc=tot_sz/((tsz?4:1)*4);
			break;
		default :
			printf("DMA setting err, check code\n");
			break;
	}

	if(tc>1048575) {
		printf("\n[ERROR] Total Count is too big !%d\n",tc);
		printf("[ERROR] This function is abort !\n\n");
		return;
		}
	
	for(i=s_addr;i<(s_addr+tot_sz);i+=4)
	{
	    	*((U32 *)i)=i^0x55aa5aa5;
	    	memSum0+=*((U32 *)i);
	}

	dmaDone=0;
	
	pDMA->DISRC=s_addr;
	pDMA->DISRCC=(0<<1)|(0<<0); // AHB, INC
	pDMA->DIDST=d_addr;
	pDMA->DIDSTC=(0<<1)|(0<<0); // AHB, INC
	pDMA->DCON=(1<<31)|(1<<30)|(1<<29)|(tsz<<28)|(1<<27)|(0<<22)|(dsz<<20)|(tc);
			   //HS|AHB|InterruptEn|TransferSize|WholeServ|RelaodOff|DataSize|TransferCount
	pDMA->DMAREQSEL=0; //S/W request mode
	pDMA->DMASKTRIG=(1<<1)|1; //DMA on, SW_TRIG
//	printf("autoReload %d tc %d c_tc %d\n",((pDMA->DCON)>>22)&0x1,tc,pDMA->DSTAT&0xfffff);
	while(dmaDone==0);
	rINTSUBMSK=BIT_SUB_ALLMSK;
	rINTMSK=BIT_ALLMSK;

	for(i=d_addr;i<(d_addr+tot_sz);i+=4)
	{
	    	memSum1+=*((U32 *)i);
	}


	if(memSum0==memSum1)
		printf("[Ch: %d, Size: %d KB] DMA test (Handshake, Whole service) O.K.\n",ch,tot_sz/1024);
	else 
		printf("[Ch: %d, Size: %d KB] DMA test (Handshake, Whole service) ERROR!!!\n",ch,tot_sz/1024);

//	printf("DMASKTRIG 0x%03x\n",pDMA->DMASKTRIG&0x7);
//	printf("autoReload %d tc %d c_tc %d\n\n",((pDMA->DCON)>>22)&0x1,pDMA->DCON&0xfffff,pDMA->DSTAT&0xfffff);
}

void DMA_M2M_DM_WHL(U32 ch,U32 s_addr, U32 d_addr, U32 tsz, U32 dsz, U32 tot_sz)
{
	U32 i;
	U32 tc = 0;
	volatile U32 memSum0=0,memSum1=0;
	DMA *pDMA = 0;
	
	switch(ch)
	{
		case 0:
			pISR_DMA=(int)Dma0Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA0);  
			pDMA=(void *)0x4b000000;
			break;
		case 1:
			pISR_DMA=(int)Dma1Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA1);
			pDMA=(void *)0x4b000100;
			break;
		case 2:
			pISR_DMA=(int)Dma2Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA2);  
			pDMA=(void *)0x4b000200;
			break;
		case 3:
		    	pISR_DMA=(int)Dma3Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA3);
		   	pDMA=(void *)0x4b000300;
		    	break;
		case 4:
		    	pISR_DMA=(int)Dma4Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA4);
		   	pDMA=(void *)0x4b000400;
		    	break;
		case 5:
		    	pISR_DMA=(int)Dma5Done;
			rINTMSK&=~(BIT_DMA);
			rINTSUBMSK&=~(BIT_SUB_DMA5);
		   	pDMA=(void *)0x4b000500;
		    	break;
	}
	
	// tc : transfer count
	// tot_sz : Actual number of bytes to be tranferred
	// tsz = 0 @ Unit transfer,	tsz = 1 @ Burst transfer
	// dsz = 0 @ Byte,			dsz = 1 @ Half word
	// dsz = 2 @ Word
	switch(dsz)
	{
		case BYTE :
			tc=tot_sz/((tsz?4:1)*1);
			break;
		case DBYTE :
			tc=tot_sz/((tsz?4:1)*2);
			break;
		case FBYTE :
			tc=tot_sz/((tsz?4:1)*4);
			break;
		default :
			printf("DMA setting err, check code\n");
			break;
	}

	if(tc>1048575) {
		printf("\n[ERROR] Total Count is too big !%d\n",tc);
		printf("[ERROR] This function is abort !\n\n");
		return;
		}
	
	for(i=s_addr;i<(s_addr+tot_sz);i+=4)
	{
	    	*((U32 *)i)=i^0x55aa5aa5;
	    	memSum0+=*((U32 *)i);
	}

	dmaDone=0;
	
	pDMA->DISRC=s_addr;
	pDMA->DISRCC=(0<<1)|(0<<0); // AHB, INC
	pDMA->DIDST=d_addr;
	pDMA->DIDSTC=(0<<1)|(0<<0); // AHB, INC
	pDMA->DCON=(0<<31)|(1<<30)|(1<<29)|(tsz<<28)|(1<<27)|(0<<22)|(dsz<<20)|(tc);
			   //DM|AHB|InterruptEn|TransferSize|WholeServ|RelaodOff|DataSize|TransferCount
	pDMA->DMAREQSEL=0; //S/W request mode
	pDMA->DMASKTRIG=(1<<1)|1; //DMA on, SW_TRIG
//	printf("autoReload %d tc %d c_tc %d\n",((pDMA->DCON)>>22)&0x1,tc,pDMA->DSTAT&0xfffff);
	while(dmaDone==0);
	rINTSUBMSK=BIT_SUB_ALLMSK;
	rINTMSK=BIT_ALLMSK;

	for(i=d_addr;i<(d_addr+tot_sz);i+=4)
	{
	    	memSum1+=*((U32 *)i);
	}


	if(memSum0==memSum1)
		printf("[Ch: %d, Size: %d KB] DMA test (Demand, Whole service) O.K.\n",ch,tot_sz/1024);
	else 
		printf("[Ch: %d, Size: %d KB] DMA test (Demand, Whole service) ERROR!!!\n",ch,tot_sz/1024);

//	printf("DMASKTRIG 0x%03x\n",pDMA->DMASKTRIG&0x7);
//	printf("autoReload %d tc %d c_tc %d\n\n",((pDMA->DCON)>>22)&0x1,pDMA->DCON&0xfffff,pDMA->DSTAT&0xfffff);
}

void DMA_M2M_HS_SNG(U32 ch,U32 s_addr, U32 d_addr, U32 tsz, U32 dsz, U32 tot_sz)

⌨️ 快捷键说明

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