裸机系列——DMA工作

转至:http://blog.csdn.net/cybertan/archive/2009/10/19/4697516.aspx

DMA 优点是其进行数据传输时不需要 CPU 的干涉,可以大大提高 CPU 的工作效率。

DMA 大容量数据传输中非常重要,比如图像数据传输, SD 卡数据传输, USB 数据传输等等。

S3C2410 有四个 DMA ,每个 DMA 支持工作方式基本相同,但支持的 source Dest 可能略有不同。

那么怎么使用 DMA 呢, S3C2410 内部集成了 DMA 控制器,我们只需要简单的配置一下寄存器就可以实现 DMA 的传输了。

步骤与要点:

1.        数据从哪里来,到哪里去?

使用 DMA 当然首先我们要知道数据的流向, DISRCx 寄存器是 DMA 初始源寄存器存放了数据的源地址。 DIDSTx 是 DMA 的初始目的寄存器,应该存放数据的目的地址。

 

2.        数据走得什么总线?地址是否是固定的?

我们还要知道源与目的数据存储设备是在什么总线上( AHB 系统总线,一般是高速的比如内存, APB 外围总线低速的,比如 SD , UART );

以及数据传输结束以后起始地址还原到发送前的起始地址呢,还是在现在的末尾 +1 做为新的起始地址。

这些设置在 DISRCCx 与 DIDSTCx 两个寄存器里面配置。

 

3.        数据以什么方式传输?源与目的是什么设备?要不要自动重载?

需要确定数据的传输方式有请求还是握手(推荐使用 HANDSHAKE ) , 根据上面的总线确定与什么时钟同步( HCLK , PCLK ),是单元传输还是突发传输,是以字节传输还是字传输,是否重载。是单服务(只发送一次)还是多服务(不停循环发送),以及数据的传送大小。

选择源与目的设备,这里 DMA 控制器支持:

    Ch0:nXDREQ0,UART0,SDI,Timer,USB EP1

    Ch1: nXDREQ1,UART1,I2SSDI,SPI0,USB EP2

    Ch2:I2SSDO,I2SSDI,SDI,Timer, USB EP3

    Ch3:UART1,SDI,SPI1,Timer, USB EP4

最后还要确定中断是不是传输结束发生( CURR_TC 记数是不是 0 )。

这些都在 DCONx 中设置。

4.        怎么开始传输 DMA 和停止 DMA ,这些在 DMASKTRIG 中设置。

 

下面是 DMA 在 SD 卡中使用的一段示例:

 

SD 卡读的 DMA 设置:

pISR_DMA0=(unsigned)DMA_end; //DMA 中断服务函数入口地址,一次 DMA 传送结束发生 rINTMSK = ~(BIT_DMA0); // 开 DMA 中断

rDISRC0=(int)(Tx_buffer);  // 源地址在内存   就是从内存读数据到 SD 卡

rDISRCC0=(0<<1)+(0<<0);  // 内存的总线是  AHB,  地址是自动增加 inc

rDIDST0=(U32)(SDIDAT); //  目的地址 SD 卡

rDIDSTC0=(1<<1)+(1<<0);  //  在总线 APB,  地址是固定的因为 SD 的 FIFO 是固定大的   

rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;

//handshake 握手模式 ,  与  PCLK 同步 , 发送完产生中断 ,  单元传输 ,  单服务 , SDI

// 不自动重载 , 每次发送一个字 , 发送大小

rDMASKTRIG0=(0<<2)+(1<<1)+0;  // 不停止 , DMA0 channel  启动 , 不用 SW 触发

 

SD 卡写的相应代码

pISR_DMA0=(unsigned)DMA_end;

rINTMSK = ~(BIT_DMA0);

rDISRC0=(int)(Tx_buffer);                                 

rDISRCC0=(0<<1)+(0<<0);                            

rDIDST0=(U32)(SDIDAT);                              

rDIDSTC0=(1<<1)+(1<<0);                             

rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;                                                         

rDMASKTRIG0=(0<<2)+(1<<1)+0;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值