dsp EDMA学习与疑问

来源:互联网 发布:烟风煤粉管道设计软件 编辑:程序博客网 时间:2024/06/10 05:43

EDMA是一种数据传输模式,用EDMA建立无需CPU干预的外部设备与内存之间的直接数据传输通道,节省CPU工作时间。

EDMA控制器主要包含传输控制器和通道控制器两部分。传输控制器包含了将要传输的数据,而通道控制器是通过一个触发事件或者它接收到一个传输请求TR,从而实现进入传输入口的。注意它的传输主要是事件触发的特点。

EDMA有三种触发方法:

1、最主要的通过外部事件来触发一次TR;

2、通过某个指定的传输完成后触发另一个的连锁触发方式;

3、CPU触发,通过往事件设置寄存器ESR中写数,一般调试用。

EDMA有1D和2D两种传输模式。1D的数据组成为块-》帧-》元素,2D的数据组成为块-》数组-》元素。

每个外设都有寄存器,EDMA的寄存器如下:

ESEL:设置EDMA事件与通道的映射关系(有些dsp型号是固定映射的);

PQSR:表示状态,表示传输寄存器在每个优先级水平上是否为空;

CIPR:表示通道中断待定状态;

CIER:使能或屏蔽通道中断;

CCER:使能或屏蔽通道连锁;

ER:表示状态,表示捕获的事件;

EER:使能或屏蔽ER中的每一个事件;

ECR:清除已触发的事件;

ESR:触发传输请求。

另外有个很重要的通道参数RAM,通常称PaRAM,包括OPT通道选项参数、SRC源地址参数、DST目的地址参数、CNT、IDX、RLD等等参数。这个寄存器在程序中是显式配置的,不像前面那些,应该都写成CSL函数了。


程序的流程我通过一个实例来解释了。这个实例将实现,当FIFO满了,触发EDMA把FIFO数据经EMIF-》EDMA读入内存。

硬件上,注意FIFO和dsp EMIF接口的连接,尤其让FIFO的满信号和dsp外部中断引脚相连,这样满信号就能作为外部GPIO触发中断。

软件编程分为以下几部分:

1、初始化部分:

(1)CSL的初始化;

(2)中断寄存器的初始化,例如设置中断向量、先禁止所有中断源等等;

(3)EMIF的初始化,即函数EMIF_config(&myConfig),其中要对myConfig结构体根据EMIF知识点进行配置。

2、设置EDMA中断:

void IRQ_map(Uint32 eventID,int intNumber);//将中断事件和中断号绑定

对于EDMA中断号为8,那么应该写成(中断号依型号而定):

IRQ_map(EDMAINT,8);

3、配置并打开EDMA通道:

(1)配置前应该清空寄存器并禁止中断:

EDMA_clearPram(0x00000000);

EMDA_intDisable(7);//GPIO外部触发事件,所以事件号可以为7,对应GPIO事件7/外部中断7

(2)打开通道返回句柄:EDMA_Handle EDMA_open(int chaNum,Uint32 flags);

第一个参数是通道设置的事件号,第二个参数统一为EDMA_OPEN_RESET,一系列的初始化工作。

因为这里是GPIO外部触发事件,事件号为7,因此写成:

hEdma7 = EDMA_open(EDMA_CHA_EXTINT7,EDMA_OPEN_RESET);

(3)配置EDMA,通过结构体。

注意这个配置函数需要句柄和结构体两个参数:void EDMA_config(EDMA_Handle hEdma,EDMA_Config *config);

那么就需要对该结构体进行配置,共有OPT、SRC、DST、CNT、IDX、RLD六个寄存器,格式同EMIF的配置格式。

(4)使能EDMA传输结束中断,允许一次传输结束后产生中断。

EDMA_intEnable(7);

(5)使能EDMA事件号的传输通道及使能EDMA传输。

EDMA_enableChannel(hEdma7);

IRQ_enable(EDMAINT);

4、可以编写中断服务程序,表示中断发生的时候干什么。

EDMA_IntHandler EDMA_intHook(int tccNum,EDMA_IntHandler funcAddr);

例如本例可以写为:EDMA_intHook(7,myLed){}

注意这个程序实现的是中断处理函数,即EDMA传输完成后做什么事情,而传输的过程经过事件触发自动完成,不用显示的读写。


注意EDMA整个程序流程的顺序是很讲究的,对中断的设置流程来讲,都是先初始化-》禁止大中断-》禁止小中断-》设置映射等等-》开启小中断-》开启大中断的顺序。以后也要注意中断的写法。


目前对于EDMA还是有很多疑问,比如:
1、在实际配置EDMA时候只显式配置了PaRAM,而其他的没有看到。虽然很明显的一些CSL函数肯定是对某个寄存器某位进行设置,但不确定真的是这样吗?

2、上一节的EMIF程序没有用到EDMA,是不是说明它的读写就是经过CPU的,需要取地址取数据?

等等。


扩展:当需要多组EDMA传输的时候,需要定义多组PaRAM,每组的最后参数linkaddress指向另一个PaRAM,就像一个链表的结构。整个程序多用数组的形式和for循环,参考文档《EDMA使用详解》。


补充:在另一个地方看到软件触发EDMA的函数:EDMA_setChannel(...)




0 0
原创粉丝点击