记录2--s3c2440 DMA的操作

发布者:RadiantWhisper最新更新时间:2020-06-09 来源: eefocus关键字:s3c2440  DMA  寄存器 手机看文章 扫描二维码
随时随地手机看文章

一.


typedef struct tagDMA

{

    volatile U32 DISRC;     //0x0     DMA初始源寄存器

    volatile U32 DISRCC;    //0x4     DMA初始源控制寄存器

    volatile U32 DIDST;     //0x8     DMA初始目的寄存器

    volatile U32 DIDSTC;    //0xc     DMA初始目的控制寄存器

    volatile U32 DCON;     //0x10    DMA控制寄存器

    volatile U32 DSTAT;     //0x14    DMA状态寄存器

    volatile U32 DCSRC;     //0x18    当前源寄存器

    volatile U32 DCDST;     //0x1c    当前目的寄存器

    volatile U32 DMASKTRIG; //0x20    DMA掩码触发寄存器

}DMA;


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 = (unsigned)Dma0Done;

        EnableIrq(BIT_DMA0); //open DMA0 INTERRUPT

    pDMA=(void *)0x4b000000;

    break;

    case 1:

    pISR_DMA1 = (unsigned)Dma1Done;

        EnableIrq(BIT_DMA1); //open DMA1  INTERRUPT

    pDMA=(void *)0x4b000040;

    break;

    case 2:

    pISR_DMA2 = (unsigned)Dma2Done;

        EnableIrq(BIT_DMA2); //open DMA2  INTERRUPT

    pDMA=(void *)0x4b000080;

break;

    case 3:

    pISR_DMA3 = (unsigned)Dma3Done;

        EnableIrq(BIT_DMA3); //open  DMA3  INTERRUPT

        pDMA=(void *)0x4b0000c0;

        break;

    }

                                                                                                                            

    Uart_Printf("DMA%d %8xh->%8xh,size=%xh(tc=%xh),dsz=%d,burst=%dn",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;   //向源地址写入任意数据 写入长度为length

    memSum0+=i^0x55aa5aa5;      //将写入数据累加,为校验读出数据的准确性

    }

    Uart_Printf("DMA%d startn",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=(1<<31)|(1<<30)|(1<<29)|(burst<<28)|(1<<27)|

            (0<<23)|(1<<22)|(dsz<<20)|(tc);

    //DMA控制寄存器  HS,AHB sync,enable 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();

    

    Uart_Printf("DMA transfer done.n");

    Uart_Printf("time = %u MSn", time*128/1000);   

 

    DisableIrq(BIT_DMA0);

    DisableIrq(BIT_DMA1);

    DisableIrq(BIT_DMA2);

    DisableIrq(BIT_DMA3);

    

    for(i=dstAddr;i    {

    memSum1+=*((U32 *)i)=i^0x55aa5aa5;

    }

    

    Uart_Printf("n memSum0=%x,memSum1=%xn",memSum0,memSum1);

    if(memSum0==memSum1)

    Uart_Printf("DMA test result--------------------------------------O.K.n");

    else 

    Uart_Printf("DMA test result--------------------------------------ERROR!!!n");

}


二.


测试DMA


void Test_DMA(void)

{

    //DMA Ch 0   _NONCACHE_STARTADDRESS = 0x30400000 

    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x80000,0,0); //byte,single

    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x40000,1,0); //halfword,single    

    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,2,0); //word,single

    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,0,1); //byte,burst    

    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x10000,1,1); //halfword,burst

    DMA_M2M(0,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst

 

    //DMA Ch 1

    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x80000,0,0); //byte,single

    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x40000,1,0); //halfword,single

    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,2,0); //word,single

    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,0,1); //byte,burst

    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x10000,1,1); //halfword,burst

    DMA_M2M(1,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst

 

    //DMA Ch 2

    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x80000,0,0); //byte,single

    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x40000,1,0); //halfword,single

    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,2,0); //word,single

    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,0,1); //byte,burst

    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x10000,1,1); //halfword,burst

    DMA_M2M(2,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst

 

    //DMA Ch 3

    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x80000,0,0); //byte,single

    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x40000,1,0); //halfword,single

    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,2,0); //word,single

    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x20000,0,1); //byte,burst

    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000,0x10000,1,1); //halfword,burst

    DMA_M2M(3,_NONCACHE_STARTADDRESS,_NONCACHE_STARTADDRESS+0x800000, 0x8000,2,1); //word,burst   

}

关键字:s3c2440  DMA  寄存器 引用地址:记录2--s3c2440 DMA的操作

上一篇:DMA基本概念及linux2440下DMA驱动程序编写与测试
下一篇:S3C2440 - DMA传输(以字符传输为例)

推荐阅读最新更新时间:2024-10-23 15:05

S3C2440 DMA 驱动示例
将 DMA 抽象为一个字符设备,在初始化函数中调用 void *dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) 函数来分配两段物理地址连续的空间,一段作为源空间,一段作为目的空间。 然后将物理地址进行 ioremap 供驱动使用,最后调用 register_chrdev 来注册这个字符设备。 DMA 的 regs: #define DMA0_BASE_ADDR 0x4B000000 #define DMA1_BASE_ADDR 0x4B000040 #define DMA2_
[单片机]
S3C2440之简易播放器设计(利用DMA与IIS通信)
利用前一篇文章讲解的IIS知识,只是不是利用轮询,而是利用DMA控制器,让数据在内存和IIS的发送FIFO之间传送。这样在音乐播放过程中,进行暂停,静音,播放,音量增减都不会使音乐产生卡顿的感觉。 注意DMA的请求是由发送FIFO自动发起的。 可以设置DMAMSKTRIG的STOP位停止DMA,但是真正的停止需要参考ON_OFF位。ON_OFF位当为非自动重载,且CURR_TC为0,该位自动为OFF。STOP位置位,该位也置为OFF。所以需要注意,一次DMA传输结束,假设开启了DMA中断,那么再DMA中断需要再次打开DMA,因为CURR_TC=0使其停止了。 当CURR_TC=0,且DMA ACK=1的话,TC的数值又
[单片机]
S3C2440 DMA工作原理
这里具体DMA CONTROL寄存器(DCON)的配置说明,进而引出DMA的各种工作方式。 Atomic transfer:指的是DMA的单次原子操作,它可以是Unit模式(传输1个data size),也可以是burst模式(传输4个data size),具体对应DCON 。 Data Size:指的是单次原子操作的数据位宽,8、16、32,具体对应DCON 。 Request Source:DMA请求的来源有两种,软件&硬件模块,由DCON 控制;当为前者时,由软件对DMASKTRIG寄存器的位0置位触发一次DMA 操作。当为后者时,具体来源由DCON 控制,不同硬件模块的某时间触发一次DMA操作,具体要见不同的硬件模
[单片机]
<font color='red'>S3C2440</font> <font color='red'>DMA</font>工作原理
s3c2440学习系列6(dma 续)
DMA优点是其进行数据传输时不需要CPU的干涉,可以大大提高CPU的工作效率。 DMA大容量数据传输中非常重要,比如图像数据传输,SD卡数据传输,USB数据传输等等。 S3C2410有四个DMA,每个DMA支持工作方式基本相同,但支持的source Dest可能略有不同。 那么怎么使用DMA呢,S3C2410内部集成了DMA控制器,我们只需要简单的配置一下寄存器就可以实现DMA的传输了。 步骤与要点: 1.数据从哪里来,到哪里去? 使用DMA当然首先我们要知道数据的流向,DISRCx寄存器是DMA初始源寄存器存放了数据的源地址。DIDSTx是DMA的初始目的寄存器,应该存放数据的目的地址。 2.数据走得什么总线
[单片机]
S3C2440 - DMA传输(以字符传输为例)
一、使用DMA的优点及DMA支持的请求源 1、DMA优点是其进行数据传输时不需要CPU的干涉,可以大大提高CPU的工作效率。 2、DMA在大容量数据传输中非常重要,比如图像数据传输,SD卡数据传输,USB数据传输等。 3、S3C2440有四个DMA,每个DMA支持的工作方式基本相同,但支持的DMA请求源可能略有不同。如下为四个DMA通道分别支持的DMA请求源: Ch0: nXDREQ0, UART0, SDI, Timer, USB EP1 Ch1: nXDREQ1, UART1, I2SSDI, SPI0, USB EP2 Ch2: I2SSDO,
[单片机]
S3C2440 DMA驱动程序编写及测试(三十二)
DMA(Direct Memory Access) 即直接存储访问,DMA传输方式无需CPU直接控制传输,通过硬件为RAM、I/O设备开辟一条直接传输数据的通路,能使CPU的效率大为提高。 学了这么多驱动,不难退出DMA的编写套路: 1)注册DMA中断,分配缓冲区 2)注册字符设备,并提供文件操作集合fops - 2.1)file_operations里设置DMA硬件相关操作,来启动DMA 由于我们是用字符设备的测试方式测试的,而本例子只是用两个地址之间的拷贝来演示DMA的作用,所以采用字符设备方式编写 1、驱动编写之前,先来讲如何分配释放缓冲区、DMA相关寄存器、使用DMA中断 1.1 在linux中,分配释
[单片机]
<font color='red'>S3C2440</font> <font color='red'>DMA</font>驱动程序编写及测试(三十二)
s3c2440裸机-时钟编程-2-配置时钟寄存器
1.2440时钟时序 下图是2440时钟配置时序: 1.上电后,nRESET复位信号拉低,此时cpu还无法取指令工作。 2.nRESET复位信号结束后变为高电平,此时cpu开始工作。此时cpu主频FCLK=osc。 3.此时可以配置PLL,经过lock time后,FCLK倍频成新的时钟。 2.如何配置时钟 在参考手册的特性里介绍了S3C2440的工作频率,Fclk最高400MHz,Hclk最高136MHz,Pclk最高68MHz。那么 我们干脆配置FCLK:HCLK:PCLK= 400:100:50 (MHz). 1,先配置lock time 我们取芯片手册上的推荐值。
[单片机]
S3C2440 中断相关寄存器小探
肯定有的朋友和我一样,对2440里面的中断寄存器迷惑,屡不清脉络。结合网上资料和自己的琢磨,我大概搞清楚了。先上图,以飨读者。 1. 中断分为两大类 (1)外部中断 24个外部中断占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15(EINT8-EINT23)。这些中断对应的是片子上的引脚,用的时候,需要把引脚配置为中断模式,并且不要上拉。他们的触发方式由寄存器EXTINT0-EXTINT2设置(比如上升沿,下降沿等)。 EINTPEND:这个是中断挂起寄存器,清除时要写1。当一个外部中断(EINT4-EINT23)发生后,那么相应的位会被置1。 EINTMASK:这个是屏蔽中断用的,尽管 EINTP
[单片机]
<font color='red'>S3C2440</font> 中断相关<font color='red'>寄存器</font>小探
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved