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

📄 dma.c

📁 samsung s3c2443 dma transfer code
💻 C
📖 第 1 页 / 共 2 页
字号:
{
	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)|(0<<27)|(0<<22)|(dsz<<20)|(tc);
			   //HS|AHB|InterruptEn|TransferSize|SingleServ|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) {
			if(pDMA->DSTAT&0xfffff) pDMA->DMASKTRIG |= 1;
		}

	pDMA->DMASKTRIG &=~(1<<1);
	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, Single service) O.K.\n",ch,tot_sz/1024);
	else 
		printf("[Ch: %d, Size: %d KB] DMA test (Handshake, Single 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_SNG(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=(0<<31)|(1<<30)|(1<<29)|(tsz<<28)|(0<<27)|(0<<22)|(dsz<<20)|(tc);
			   //DM|AHB|InterruptEn|TransferSize|SingleServ|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) {
			if(pDMA->DSTAT&0xfffff) pDMA->DMASKTRIG |= 1;
		}

	pDMA->DMASKTRIG &=~(1<<1);
	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, Single service) O.K.\n",ch,tot_sz/1024);
	else 
		printf("[Ch: %d, Size: %d KB] DMA test (Demand, Single 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);
}


static void __irq Dma0Done(void)
{
    rSUBSRCPND|=BIT_SUB_DMA0;
    ClearPending(BIT_DMA);
    dmaDone=1;
}

static void __irq Dma1Done(void)
{
    rSUBSRCPND|=BIT_SUB_DMA1;
    ClearPending(BIT_DMA);
    dmaDone=1;
}

static void __irq Dma2Done(void)
{
    rSUBSRCPND|=BIT_SUB_DMA2;
    ClearPending(BIT_DMA);
    dmaDone=1;
}

static void __irq Dma3Done(void)
{
    rSUBSRCPND|=BIT_SUB_DMA3;
    ClearPending(BIT_DMA);
    dmaDone=1;
}

static void __irq Dma4Done(void)
{
    rSUBSRCPND|=BIT_SUB_DMA4;
    ClearPending(BIT_DMA);
    dmaDone=1;
}

static void __irq Dma5Done(void)
{
    rSUBSRCPND|=BIT_SUB_DMA5;
    ClearPending(BIT_DMA);
    dmaDone=1;
}







/*********************************************************************************************************************/


#if 0
static void __irq Dma0Doneloop(void)
{
    rSUBSRCPND|=BIT_SUB_DMA0;
    ClearPending(BIT_DMA);
    dmaDone=1;
    rDMASKTRIG0=(1<<1)|1; //DMA on, SW_TRIG
}
#endif

void DMA_M2M_loop(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;
	}

	for(i=s_addr;i<(s_addr+tot_sz);i+=4)
	{
	    	*((U32 *)i)=i^0x55aa5aa5;
	    	memSum0+=i^0x55aa5aa5;
	}

	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

#if 0
	while(dmaDone==0);

	rINTSUBMSK=BIT_SUB_ALLMSK;
	rINTMSK=BIT_ALLMSK;

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

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

#if 0
[autoreload is off]
autoReload 1 tc 131072 c_tc 131072
[Ch: 3, Size: 512 KB] DMA test O.K.
DMASKTRIG 0x000
autoReload 1 tc 131072 c_tc 0

[autoreload is on]
autoReload 0 tc 131072 c_tc 131072
[Ch: 3, Size: 512 KB] DMA test O.K.
DMASKTRIG 0x002
autoReload 0 tc 131072 c_tc 0
#endif

⌨️ 快捷键说明

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