1、程序分析
#include <stdio.h>
2440里面有4个DMA #define DMA0_BASE_ADDR 0x4B000000 #define DMA1_BASE_ADDR 0x4B000040 #define DMA2_BASE_ADDR 0x4B000080 #define DMA3_BASE_ADDR 0x4B0000C0 //DMA相关的寄存器值,存放在一个结构体体里 struct s3c_dma_regs { unsigned long disrc; unsigned long disrcc; unsigned long didst; unsigned long didstc; unsigned long dcon; unsigned long dstat; unsigned long dcsrc; unsigned long dcdst; unsigned long dmasktrig; }; //定义结构体指针 struct s3c_dma_regs *dma_regs; static int dma_src_rep; static int dma_len_rep;/* 数据传输: 源,目的,长度 */
对IIS来说,目的是FIFO【( First In First Out)简单说就是指先进先出】存储器,通过DMA把数据传入IIS的FIFO里面
void dma_init(unsigned int src, unsigned int len) { dma_src_rep = src; dma_len_rep = len; //结构体指针指向DMA2的基地址 dma_regs = (struct s3c_dma_regs *)DMA2_BASE_ADDR; /* 把源,目的,长度告诉DMA */ dma_regs->disrc = src; /* 源的物理地址 */ dma_regs->disrcc = (0<<1) | (0<<0); /* 源位于AHB总线, 源地址递增 */ dma_regs->didst = 0x55000010; /* 目的的物理地址 */ IISFIFO寄存器地址 dma_regs->didstc = (0<<2) | (1<<1) | (1<<0); /* 目的位于APB总线, 目的地址不变 */ dma_regs->dcon = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(0<<24)|(1<<23)|(1<<20)|(len/2); /* 使能中断,单个传输,硬件触发 */红色标识是选择DMA2的原因,因为由硬件产生DMA请求,由IISSDO产生DMA请求。bit19-0表示传输多少次,bit21-20表示每个单元传输多少字节,bit28表示每次传输多少个单元,三者相乘就是传输的总大小。(len/2)中除以2是因为bit28设为0(每次传输只传输一个单元),每个单元是两个字节。所以传输len就要传输len/2次。 } void dma_start(void) { /* 启动DMA */ dma_regs->dmasktrig = (1<<1); } void dma_stop(void) { /* 停止DMA */ dma_regs->dmasktrig &= ~(1<<1); } //DMA传输重复执行 void dma_repeat(void) { dma_init(dma_src_rep, dma_len_rep); } //DMA中断处理函数,当DMA传输完成后执行此函数 void DMA2IntHandle(void) { printf("DMA2 done\n\r"); dma_repeat(); }