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();
}