概述
DMA是个很不错的东西,顾名思义:Direct Memory Access,它的最大优点在于实现数据的非CPU干预传输,大大降低CPU的负担,提高CPU的实时性。比如在串口发送中,你只需要将需要发送的一串数据交给DMA,DMA会负责把所有的数据都发送出去而不需要CPU干预(中断、或硬延时等待数据发送完毕等)。
DMA所操作的地址域在XDATA区,XDATA区部分地址映射到DATA、SRAM、SFR、XREG,还有FLASH,由此可知DMA可以做的事情非常多!DMA主要包括如下特征:
- 5个独立的DMA通道
- 3个可配置DMA优先级
- 32个可配置的触发事件
- 独立控制DMA的源地址和目的地址
- 单独、块、重复等传输模式
- 传输的数据长度可配置
- 可以半字、字节方式操作
其实我觉得用快递来理解DMA还是比较合适的。5个DMA通道,就是5辆快递车,数据就是货物,源地址就是寄件地址,目的地址就是收件地址,货物数量就是传输的数据量,触发DMA数据传输就是由客户来寄快递。下面就用这个方法来理解下CC2540的DMA机制吧。 首先,DMA需要配置,那就是需要知会寄件地址(源地址)、收件地址(目的地址),使用那辆运输车(哪个通道),寄送的快递是什么(是传UART数据还是AD数据),快递的数量(传送多少数据),一次送一件还是打包运输(single mode or block mode),单件快递重量(半字、字节方式),是否需要和快递公司合作长期配送该货物(重复传输模式)...这个就是DMA的配置过程。之后就是DMA的ARM过程了,客户需要寄送货物,快递公司分配车辆,装载货物。DMA事件触发,就是运输车发车运送,那么当所有货物都安全准时运送到目的地并签收就算是完成DMA的传输了。 当你正在配置DMA时,如果相应的DMA事件触发源发生了,那么DMA数据的传输不会被触发。此外,触发源可以是外设,也可以通过软件进行触发,即设置寄存器DMAREQ。
当你的DMA被ARM上一个通道后,若此时DMA已经在进行数据传输,若你想中断传输你可以通过设置寄存器DMAARM来disarm相应的DMA。
DMA的配置方式还是挺方便的,用户只要按照规定的格式将各项配置参数组织在内存的某个地址中,然后将这个地址传到DMA的配置寄存器就完成配置了。相关的寄存器有4个:
一个是DMA通道0配置寄存器,即用于配置DMA通道0的配置数据的首地址要写到DMA0CFGH:DMA0CFGL寄存器中;另外一个是DMA1通道寄存器DMA1CFGH:DMA1CFGL。DMA2~4的配置寄存器呢?这里CC2540将从DMA1配置的地址开始连续读取DMA1~DMA4的配置值,就是说程序对DMA1~4的配置值需要进行连续存放。举个例子:
halDMADesc_t dmaCh0;
halDMADesc_t dmaCh1234[4];
DMA的配置数据存放格式如下表:
这里要注意的一点是:当DMA配的的VLEN字段设置为001、010、011、100时,传输的数据量是动态配置的,但不能超过LEN字段所表示的数量。
就写这么多了,相信把上述的都理解了,结合代码再对照下寄存器,就很容易看懂了。