64X DSP EDMA小结及实例详解及DAT_0PEN,COPY

来源:百度文库 编辑:神马文学网 时间:2024/04/19 21:42:22
C64X DSP EDMA小结
(1)EDMA概要
①EDMA数据传输有两种发起方式:
CPU发起的EMDA数据传输(非同步方式):需要传输时,CPU设置ESR寄存器的相应位为1,从而触发一个EDMA事件的产生,事件对应的通道参数被送往地址硬件并且完成相应的处理,这种非同步方式的实时数据传输无需设定EER寄存器;
事件触发方式EDMA数据传输(同步方式):ER寄存器保存外设发送过来的事件,一旦CPU设置EER寄存器的相应位为1后,ER中的事件才会提交给事 件编码器(Event Encoder),并且进一步引起相关的传输参数的发送给地址产生硬件;如果EER中对应于某事件的位没有置1,则ER寄存器中的事件将保留,一旦置1则 触发EDMA的传输,这种特性可以应用到EDMA Chain传输,需要EER和CCER结合使用;
(2)EDMA数据传输类型:
EDMA有两种类型的数据传输:1D和2D的(OPT.2DS和OPT.DDS标示源地址和目的地址的数据传输类型,即有4种组合方式);数据的维数表明了数据的组成方式:
①1D数据
数 据组成是“块->帧->元素”;一个块中的每帧数据是独立处理(即可以理解亦为2D数据,但是第二维永远是1),每次处理是 一个元素,因此一帧中的数据元素可以是在同一个内存地址、连续的地址或者是与同一帧中的前面的数据元素地址具有一定偏移(Offset,由ELEIDX通 道参数指定)的某地址;不同帧之间的内存地址偏移由FRMIDX通道参数指定(两帧的第一个元素之间的偏移或者后一帧的第一个元素的地址与前一帧的最后一 个元素地址的偏移,具体依赖于通道参数FS的设定);每帧的数据元素个数可以不同,由通道参数ELECNT指定,传完一帧数据后由ELERLD重新载入块 中的下一帧的数据元素个数ELECNT;块中的帧的个数由通道参数FRMCNT指定;
1D数据传输有两种同步方式:OPT.FS=0,元素同步方式;OPT.FS=1,帧同步方式;
元 素同步时,一次同步事件引起一帧中的一个元素的传输,每传输一次ELECNT递减1;当同步事件触发时,ELECNT=1表明是一帧的最后一个数据元素, 此时EDMA控制器除了完成最后这个元素的传输外,还需要重新载入ELECNT(通过ELERLD)并且FRMCNT递减1;ELEIDX表示元素之间的 偏移,FRMIDX表示一帧的最后一个元素和下一帧的第一个元素之间的偏移;如果OPT.LINK=1时,传输完成中断产生(FRMCNT=0)就重新从 PRAM中载入当前通道的其他参数;
帧同步时,一次同步事件引起一帧数据的传输,FRMIDX表示两帧的第一个元素之间的偏移;
② 2D数据
数据组成为“块->数组->元素”,同一数组中的元素是连续存放的,因此ELEIDX无意义;数组中的元素素引表示2D的第一维,块中的数组索引表示2D的第二维;FRMIDX的值依赖于OPT.FS的设定;
OPT.FS=0:表示一次同步事件传输一个数组,此时FRMIDX是数组首地址之间的偏移;每传完一个数组,FRMCNT递减1;当OPT.LINK=1并且FRMCNT递减至0时,从PRAM的中重新载入当前通道的其他参数;
OPT.FS=1:表示一次同步事件传输一个块;FRMIDX表示前一个数组的最后一个元素的地址与后一个数组的第一个元素的地址之间的偏移;如果OPT.LINK等于1,则当整块数据传完时,重新从PRAM中为当前通道载入新的参数;
(3)EDMA传输过程的源/目的地址的修改
在每次同步事件触发EDMA数据传输,并且传输完成后,需要对源/目的地址进行更新;地址的更新方式由SUM/DUM进行设定,并且和2DS、2DD以及FS是密切相关的;
(4)数据元素大小和对齐方式
源/目的地址是在元素大小的边界对齐的,因此要注意指向源/目的地址的指针的类型需要和OPT.ESIZE匹配;
(5)FRMCNT和ELEMCNT的更新
QUESTION:每次进行计数更新时,ELERLD的值哪里来的?
(6)EDMA Linking Transfer
当传输完成时(根据当前通道参数设定已经传完所有数据了,具体条件如下表所示),并且OPT.LINK=1,EDMA控制器会根据通道参数 LINK(非OPT.LINK,16bits)从PaRAM中的其他位置(以24个字节对齐,因为通道参数为6WORD)重新载入当前传输通道的参数;可 以链接到一个空的通道参数集(NULL Parameter)来停止EDMA传输,也可以自链接(用于循环缓冲处理或者重复的数据传输);Linking过程中不对相关寄存器作判定;
(7)EDMA中断
C64X DSP的EDMA控制器的所有64个通道只产生一种中断:EDMA_INT。如果需要让第n个EDMA通道(或者QDMA请求)可以在传输完成时可以产生中断通知CPU的话,应该如下设定:
OPT.TCINT=1:表示启用传输完成中断
OPT.TCC=n:在传输完成时,CIPR[TCC]=1,用于标记对应通道的传输完成,即便对应的CIER位没有启动,传输完成事件还是会在CIPR记录,即挂起的含义所在;
OPT.CIER[n]=1:表示立即允许挂起的第n个通道传输完成事件触发EDMA_INT中断发送给CPU;
其中,TCC用于表示的通道的位数不够时,可以扩展使用TCCM(即TCCM:TCC),CIPR和CIER均由两个寄存器组成:CIPRL+CIPRH以及CIERL+CIERH。
中 断服务例程ISR读取CIPR,确定哪一个通道完成了数据传输,进行相应的处理。ISR在进行处理之前需要清除CIPR中确定了通道的位(写入1到相关位 清除,写入0不起作用),目的是记录以后的传输完成事件的发生。在中断服务例程对某通道的传输完成中断进行服务后,因为期间有可能有其他通道传输完成了, 也已经设置了CIPR中的相应位,或者也有可能本来有好几个中断挂起了并且现在触发了,因此中断服务例程必须检查所有的CIPR并全部完成中断服务才行。 当CIPR[n]&CIER[n]=1时,则设置对应的IFR为1,防止在退出ISR时丢失中断并且使得可以多次调用ISR。中断服务例程的一个 任务是清除CIPR和CIER中的与通道对应的位。
C64X DSP除了传输完成中断外,还有交替性传输完成中断,即在传输过程中完成一个传输子过程(如传完一个数据元素、传完一个帧/数组数据;2D帧同步传输没有 交替性传输完成中断)给CPU发送一个中断,相应的设定由OPT.ATINT、OPT.ATCC设定,处理过程和传输完成中断雷同,区别只是在传输还没全 部完成的过程中进行中断处理而已。
这是使用BIOS和CSL LIB 作EDMA简单例子. 在CCS BIOS 中需要作 中断--EDMA--edmaHwi 的设置. Spru234 和 spra636a 都是有用的参考
解释见注释.
void main()
{
initEdma(); //Edma 初始化
initHwi(); //中断初始化
EDMA_setChannel(hEdma); //开始EDMA传送
while (1) {}
}
void initEdma(void)
{
EDMA_Config gEdmaConfig; //EDMA设置表
hEdma = EDMA_open(EDMA_CHA_ANY, EDMA_OPEN_RESET); //
gXmtTCC = EDMA_intAlloc(-1); //分配一个可用的TCC
.... //根据实际需要填写EDMA设置表
EDMA_config(hEdma, &gEdmaConfig); 设置EDMA通道
hEdmaReload = EDMA_allocTable(-1); //得到EDMA重载标实 EDMA_config(hEdmaReload, &gEdmaConfig); // 设置EDMA重载通道
EDMA_link(hEdma, hEdmaReload); //设置EDMA重载
EDMA_link(hEdmaReload, hEdmaReload); //设置EDMA重载
EDMA_intClear(gXmtTCC); // 清除可能的EDMA中断
EDMA_intEnable(gXmtTCC); // 打开EDMA中断
EDMA_intHook(gXmtTCC, edmaHwi); //通知系统edmaHwi是中断服务者
}
void edmaHwi(int tcc)   //中断服务
{
。。。。//准备数据
EDMA_setChannel(hEdma); //再次开始EDMA传送
}
DAT_open         Opens the DAT module
●函数    Uint32   DAT_open(
int chaNum,
int priority, 优先级
Uint32 flags
);
●参数        chaNum 指定分配那个DMA通道,必须是下面其中之一:
DAT_CHAANY
DAT_CHA0
DAT_CHA1
DAT_CHA2
DAT_CHA3
priority 指定DMA通道的优先级必须是下面其中之一
DAT_PRI_LOW
DAT_PRI_HIGH
flags   各种各样的打开标志
DAT_OPEN_2D
●返回值      success   如果失败返回0,如果成功返回非零值,失败的原因如下:
DAT模块已经打开,
需要的资源没有被分派。
●描述             这个函数打开DAT模块,而且必须在调用其它DAT API 函数之前被调用,ChaNum 参数指定了哪个DMA通道被DAT模块单独的打开,对于带有EDMA的设备,ChaNum 参数被忽略,原因是快速使用的DMA并不具有一个和它匹配的通道,对具有DMA的设备,ChaNum指定了将要使用哪个DMA通道, DAT_PRI_LOW设置DMA通道的CPU优先级 DAT_PRI_HIGH 设置DMA通道的DMA优先级,对具有EDMA的设备, ChaNum 被忽略,DAT_PRI_LOW设置 LOW priority ,DAT_PRI_HIGH 设置HIGH priority,一旦 DAT 模块被打开,任何被分配的资源,例如一个DMA通道,仍然被分配,你可以调用 DAT_close() 来释放这些资源,如果,准备通过DAT_copy2d 来进行2Dde传输, DAT_OPEN_2D 标志必须被指定,对具有DMA接口的设备指定这个标志, 将要导致一个全局重载计数寄存器和一个全局索引寄存器的分配这些全局寄存器在调用DAT_close()时将被释放,注意:对具有EDMA的设备,DAT 模块使用EDMA寄存器来提交传输请求,而且将使用通道中断挂起寄存器(CIPR),中断并不被使能 ,但是CIPR中的中断标志要用到, DAT模块使用完成码的1到4来计算一个在CIPR 寄存器中的掩码0x00000001E ,在具有EDMA的设备上使用DAT模块的用户必须避免使用完成码1到4。
使用任何有效的DMA通道来打开DAT模块的例子,
DAT_open(DAT_CHAANY,DAT_PRI_LOW,0);
用高优先级模式使用DMA通道2打开DAT模块,使用:
DAT_open(DAT_CHA2,DAT_PRI_HIGH,0);
使用2D拷贝打开DAT模块,使用:
DAT_open (DAT_CHAANY, DAT_PRI_HIGH, DAT_OPEN_2D);
DAT_copy                    Copies a linear block of data from Src to Dst using DMA or
EDMA hardware
Function                          Uint32 DAT_copy(
void *src,
void *dst,
Uint16 byteCnt
);
Arguments
void *src                 是一个源地址指针,
void *dst                  是目的地址指针,
Uint16 byteCnt     是一个无符号16位数,用来计算你要copy的byte数,这个值是以字节计算的。Return Value       xfrId Transfer ID
函数的返回值是一个传输通道的标号(xfrId Transfer ID),一般用作句柄
描述:
用CSL的DAT之前好像也得先设置好DMA或EDMA的参数,DAT可以自动选择DMA或EDMA的方式和通道,但是具体传输时还是要用到DMA和EDMA的参数,所以即使是用DAT来传输数据,也不能回避掉DMA/EDMA的设置。
The DAT module must be opened before calling this function. See
DAT_open().
The return value is a transfer identifier that may be used later on to wait for
completion. See DAT_wait().
Example                 #define DATA_SIZE 256
Uint32 BuffA[DATA_SIZE/sizeof(Uint32)];
Uint32 BuffB[DATA_SIZE/sizeof(Uint32)];

DAT_open(DAT_CHAANY,DAT_PRI_LOW,0);
DAT_copy(BuffA,BuffB,DATA_SIZE);