44b0实验-DMA实验

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这一章节确实也该好好看看了,呵呵。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值