DMA(Direct Memory Acess, 直接内存访问),是计算机的一种内存访问技术,它允许在外设和内存之间直接传输数据,而不需要CPU介入处理。DMA具有速度快,节省CPU负担的特点。DMA的初始化需要CPU来完成,初始化完成之后,数据传输就由DMA控制器来完成。
在实现DMA传输时,是由DMA控制器直接掌管总线,因此,存在着一个总线控制权转移问题。即DMA传输前,CPU要把总线控制权交给DMA控制器,而在结束DMA传输后,DMA控制器应立即把总线控制权再交回给CPU。一个完整的DMA传输过程必须经过DMA请求、DMA响应、DMA传输、DMA结束4个步骤。
2440的DMA控制器支持4个DMA通道,各个通道的请求源如下所示:
2440的DMA基本时序如下图所示:
2440的DMA控制器有两种工作模式:
6410有4个DMA控制器,每个控制器有8个通道。210则支持两种类型的DMA访问,一种是内存到内存的DMA,使用的控制器是DMA,另一种是外设到内存的DMA,使用的控制器是DMA0和DMA1。对应的描述可从芯片手册的DMA相关章节找到。
下面使用DMA来完成将内存中的数据发送到串口,参考芯片手册的DMA编程指引部分,在11.7小节。
要完成使用DMA传输数据,至少需要完成以下几步:
而针对6410,还需要进行以下几步设置:
代码如下:
#define SDMA_SEL (*((volatile unsigned long *)0x7E00F110)) #define DMACIntTCClear (*((volatile unsigned long *)0x7DB00008)) #define DMACIntErrClr (*((volatile unsigned long *)0x7DB00010)) #define DMACConfiguration (*((volatile unsigned long *)0x7DB00030)) #define DMACSync (*((volatile unsigned long *)0x7DB00034)) #define DMACC0SrcAddr (*((volatile unsigned long *)0x7DB00100)) #define DMACC0DestAddr (*((volatile unsigned long *)0x7DB00104)) #define DMACC0Control0 (*((volatile unsigned long *)0x7DB0010c)) #define DMACC0Control1 (*((volatile unsigned long *)0x7DB00110)) #define DMACC0Configuration (*((volatile unsigned long *)0x7DB00114)) #define UTXH0 (volatile unsigned long *)0x7F005020 char src[100] = "\n\rHello World-> This is a test!\n\r"; void dma_init() { //DMA控制器选择(SDMA0) SDMA_SEL = 0; //DMA控制器使能 DMACConfiguration = 1; //初始化源地址 DMACC0SrcAddr = (unsigned int)src; //初始化目的地址 DMACC0DestAddr = (unsigned int)UTXH0; //对寄存器进行配置 /* 源地址自增 目的地址固定 目标主机选择AHB主机2 源主机选择AHB主机1 */ DMACC0Control0 = (1 << 25) | (1 << 26) | (1 << 31); DMACC0Control1 = 0x64; /* 流控制和传输类型:MTP 为 001 目标外设:DMA_UART0_1,源外设:DMA_MEM 通道有效: 1 */ DMACC0Configuration = (1<<6) | (1<<11) | (1<<14) | (1<<15); } void dma_start() { //开启channel0 DMA DMACC0Configuration = 1; } |