44b0有4个DMA通道。有两个称作ZDMA,是挂在系统总线上的,另两个是BDMA,是挂在系统总线和外围总线的桥接口上。本实验主要对两个ZDMA进行测试。本实验将分配两块内存,不经过CPU,直接使用DMA的方式进行数据拷贝。
下面是代码:
#include "DMA.h"
#include <string.h>
void Zdma0Int(int srcAddr,int dstAddr,int length,int dw);
void Zdma1Int(int srcAddr,int dstAddr,int length,int dw);
void __irq Zdma0Done(void);
void __irq Zdma1Done(void);
volatile int zdma0Done,zdma1Done;
void Test_Zdma0(void)
{
unsigned char *src, *dst;
int i;
unsigned int memSum;
rINTMSK|=BIT_GLOBAL;
pISR_ZDMA0=(int)Zdma0Done;
Uart_Printf("[ZDMA0 MEM2MEM Test]/n");
dst=(unsigned char *)malloc(0x80000);
src=(unsigned char *)malloc(0x80000);
rNCACHBE1=( ( (((unsigned)dst+0x100000)>>12) +1 )<<16 )|((unsigned)dst>>12);
Uart_Printf("dst=%x,src=%x/n",(int)dst,(int)src);
/* Copy by word */
memSum=0;
for(i=0;i<0x80000;i++)
*(src+i)=0x1;
Zdma0Int((int)src,(int)dst,0x80000,2); //word
for(i=0;i<0x80000;i++)
memSum+=*(dst+i);
Uart_Printf("memSum=%8x:",memSum);
if(memSum==0x80000)Uart_Printf("O.K./n");
else Uart_Printf("ERROR!!!/n");
/* Copy by half-word */
memSum=0;
for(i=0;i<0x80000;i++)
*(src+i)=2;
Zdma0Int((int)src,(int)dst,0x80000,1); //half-word
for(i=0;i<0x80000;i++)
memSum+=*(dst+i);
Uart_Printf("memSum=%8x:",memSum);
if(memSum==0x100000)Uart_Printf("O.K./n");
else Uart_Printf("ERROR!!!/n");
/* Copy by byte */
memSum=0;
for(i=0;i<0x80000;i++)
*(src+i)=3;
Zdma0Int((int)src,(int)dst,0x80000,0); //byte
for(i=0;i<0x80000;i++)
memSum+=*(dst+i);
Uart_Printf("memSum=%8x:",memSum);
if(memSum==0x180000)Uart_Printf("O.K./n");
else Uart_Printf("ERROR!!!/n");
free(src);
free(dst);
}
void Test_Zdma1(void)
{
unsigned char *src, *dst;
int i;
unsigned int memSum;
rINTMSK|=BIT_GLOBAL;
pISR_ZDMA1=(int)Zdma1Done;
Uart_Printf("[ZDMA1 MEM2MEM Test]/n");
dst=(unsigned char *)malloc(0x80000);
src=(unsigned char *)malloc(0x80000);
rNCACHBE1=( ( (((unsigned)dst+0x100000)>>12) +1 )<<16 )|((unsigned)dst>>12);
/* Copy by word */
memSum=0;
for(i=0;i<0x80000;i++)
*(src+i)=1;
Zdma1Int((int)src,(int)dst,0x80000,2); //word
for(i=0;i<0x80000;i++)
memSum+=*(dst+i);
Uart_Printf("memSum=%8x:",memSum);
if(memSum==0x80000)Uart_Printf("O.K./n");
else Uart_Printf("ERROR!!!/n");
/* Copy by half-word */
memSum=0;
for(i=0;i<0x80000;i++)
*(src+i)=2;
Zdma1Int((int)src,(int)dst,0x80000,1); //half-word
for(i=0;i<0x80000;i++)
memSum+=*(dst+i);
Uart_Printf("memSum=%8x:",memSum);
if(memSum==0x100000)Uart_Printf("O.K./n");
else Uart_Printf("ERROR!!!/n");
/* Copy by byte */
memSum=0;
for(i=0;i<0x80000;i++)
*(src+i)=3;
Zdma1Int((int)src,(int)dst,0x80000,0); //byte
for(i=0;i<0x80000;i++)
memSum+=*(dst+i);
Uart_Printf("memSum=%8x:",memSum);
if(memSum==0x180000)
Uart_Printf("O.K./n");
else
Uart_Printf("ERROR!!!/n");
free(src);
free(dst);
}
void Zdma0Int(int srcAddr,int dstAddr,int length,int dw)
//returns the checksum
{
int time;
zdma0Done=0;
rINTMSK=~(BIT_GLOBAL|BIT_ZDMA0);
rZDISRC0=srcAddr|(dw<<30)|(1<<28); // inc
rZDIDES0=dstAddr|( 2<<30)|(1<<28); // inc
rZDICNT0=length |( 2<<28)|(1<<26)|(3<<22)|(1<<20);
//whole,unit transfer,int@TC,enable DMA
rZDCON0=0x1; // start!!!
//Timer_Start(3);//128us resolution
while(zdma0Done==0);
//time=Timer_Stop();
time = 22;
Uart_Printf("ZDMA0 %8x->%8x,%x:time=%f/n",srcAddr,dstAddr,length,time*128E-6);
rINTMSK=BIT_GLOBAL;
}
void Zdma1Int(int srcAddr,int dstAddr,int length,int dw)
//returns the checksum
{
int time;
zdma1Done=0;
rINTMSK=~(BIT_GLOBAL|BIT_ZDMA1);
rZDISRC1=srcAddr|(dw<<30)|(1<<28); // inc
rZDIDES1=dstAddr|( 2<<30)|(1<<28); // inc
rZDICNT1=length |( 2<<28)|(1<<26)|(3<<22)|(1<<20);
//whole,unit transfer,int@TC,enable DMA
rZDCON1=0x1; // start!!!
//Timer_Start(3);//128us resolution
while(zdma1Done==0);
//time=Timer_Stop();
time = 22;
Uart_Printf("ZDMA1 %8x->%8x,%x:time=%f/n",srcAddr,dstAddr,length,time*128E-6);
rINTMSK=BIT_GLOBAL;
}
void __irq Zdma0Done(void)
{
rI_ISPC=BIT_ZDMA0; //clear pending
//rI_ISPC; //is needed only when cache=on & wrbuf=on & BSFRD=0
zdma0Done=1;
}
void __irq Zdma1Done(void)
{
rI_ISPC=BIT_ZDMA1; //clear pending
//rI_ISPC; //is needed only when cache=on & wrbuf=on & BSFRD=0
zdma1Done=1;
}
但是,实验结果却总是ERROR:
后来分析下,可能是由cache导致的。这个时候,正处于cache on的状态,所以很多读到的值可能和实际的值不一样。这也正好引出了我接下来要研究的东西:Cache。对于datasheet,CPU WRAPPER & BUS PRIORITIES这一章节确实也该好好看看了,呵呵。