DSP(TMS320C6713)入门之旅四、edma的理解和使用
- 格式:doc
- 大小:821.00 KB
- 文档页数:20
摘要:增强型直接内存访问EDMA 是DSP 中一种高效的数据传输模块,能够不依赖CPU 进行数据的搬移,是在高速接口的使用中,十分重要的设备。
与之前的EDMA 模块相比,EDMA3在传输的同步方式、地址跳变、触发方式上都变得更为灵活。
在TI 的新型DSP 中,外设根据数据传输是否依赖EDMA3 而分成了2 种。
AIF 是一种高速接口模块,用于基带模块与射频模块间数据的传输。
该接口需要EDMA3 为其提供待传输的数据及搬移已接收的数据。
本文介绍了TI DSP 中的新一代EDMA3 模块的结构及参数配置,并结合多核心DSP TMS320C6474 中的高速AIF 接口,给出了一种EDMA3 的配置方式,为高速接口模块的使用,打下基础。
关键词:DSP;EDMA3;TMS320C6474;AIF0 引言TMS320C6474 是TI 推出的推出的一款高性能多核心DSP,基于65nm 工艺,在单一的裸片上集成了3 个1GHz 的C64x+内核,实现了3GHz 的原始DSP 性能。
显著降低了成本和功耗,并节省板级空间,使设计人员不必在电路板上集成多个数字信号处理器就能完成诸如同时执行多通道处理任务或同时执行多软件应用等高强度、高性能任务。
在TMS320C6474 DSP 中,C64x+核心、EDMA3 及片上外设是通过2 种交换网络互连的。
交换网络使主从器件间能够进行低延时的多路数据传输。
通过交换网络,CPU 能够向VCP2 发送数据而不影响RAC 与DDR2 内存控制器间的数据传输。
当对系统中的从设备进行访问时,交换网络能够对多个主设备进行仲裁。
片上外设可以分为两类:主设备及从设备。
主设备是指能够不使用EDMA3 就能在系统中进行读写操作的设备;从设备指必须使用EDMA3 才能进行数据传输的设备。
AIF 接口(Antenna Interface)是TMS320C6474 中的一种高速接口,是一种从设备,用于基带模块与射频模块间天线数据的传输,在使用OBSAI 协议时,单条链路速率最高可达4x 即3.072Gbps。
第22卷 第6期2007年12月液 晶 与 显 示Chinese Jour nal of L iquid Cry stals and Display sVol .22,No .6Dec .,2007文章编号:1007-2780(2007)06-0719-06EDM A 数据传输方式在基于DSP 的视频信号处理系统中的应用陈振华,邓少芝*,许宁生(中山大学理工学院光电材料与技术国家重点实验室;广东省显示材料与技术重点实验室,广东广州 510275)摘 要:视频信号传输是视频信号处理系统的关键技术,文章介绍利用EDM A 数据传输方式、在基于T I 公司的数字信号处理器(DSP )T M S320C6713芯片的视频信号处理系统中实现视频数据信号高速传输的一种方案。
介绍了方案中的DSP 外部储存器接口与FIF O 存储器的硬件接口设计,并着重描述了基于EDM A 数据传输方式的实现方法和软件设计流程。
利用EDM A 在CP U 后台高效地实现存储空间的数据搬移,并在EDM A 中断服务程序中对视频数据信号进行处理,DSP 的中央处理单元就能够专注于信号处理和系统功能控制,从而满足视频信号处理系统的高速实时性要求。
关 键 词:增强直接存储器访问;数字信号处理器;视频信号处理中图分类号:T N 27 文献标识码:A 收稿日期:2007-07-23;修订日期:2007-08-22 基金项目:国家科技部“973”计划项目(No .2003CB314701);国家-广东省联合科学基金项目(No .U0634002)*通讯联系人,E -mail :stsd sz @mail .sysu .edu .cn1 引 言随着平板显示技术成为主流显示技术,传统的视频设备需要提升其功能输出适合于平板显示器件的视频信号。
新型的平板显示器件,例如有机发光平板显示、场发射平板显示等器件需要适合于器件驱动方式的视频驱动信号[1],因此数字视频信号处理在上述新型显示技术研发活动中是一个受到关注的内容。
学习一个芯片的功能时,我的建议是先学会如何用C语言点亮一个LED灯,然后就是学习一下使用他的中断,因为在做芯片的时候,各个厂家有自己的一套自己的方法。
所以使用中断的就必须了解很多概念,比如如何打开中断,如何安装自己的中断子服务程序,等等!先介绍一下什么叫中断:你在下象棋,突然电话响了,你回屋接电话,然后回来继续下象棋,这个过程就叫做中断响应过程(中断过程)。
CPU执行正常任务———————下象棋保护现场———————————-你已经想好要―将军‖,先在脑海中记下来。
中断发生———————————-电话响-中断服务程序—————————-接电话恢复现场———————————-回来后恢复刚才想法中断返回———————————-你回来继续下象棋中断屏蔽———————————-Boss 正在训话,要求所有电话关机,你不能接电话了。
非屏蔽中断——————————-你内急,即使是Boss 在训话,你还是得到外面去嘘嘘。
可屏蔽中断——————————-你在―闭关修炼‖,可以不受外界干扰所以我们在使用中断之前先得告诉CPU,我们要使用那个中断,当中断发生的时候,你的执行程序的去向(也就是中断服务子程序),最后在返回我们被中断的函数。
这样就完成了我们的中断历程!看看6713执行中断的流程:一、使能了全局中断和子中断,那么CPU每执行一条指令之前就去查询一下有没有中断被置位,如果有产生的,那么CPU就要跳转!二、软件把CPU内部的寄存器A0~A15,B0~B15,等等这些寄存器的值推入堆栈保存,把当前PC寄存器的值放入IRP寄存器中以备中断返回能找到当前被打断的位置(保存现场,中断函数前面得加interrupt关键字)三、CPU的PC指针读出中断向量表的地址,也就是把(ISTP寄存器的值+子中断向量偏移量)装入PC寄存器,这样就执行跳转。
四、在中断向量表里一般有就用跳转指令,这样就可以跳转到我们用C语言编写的中断服务子程序中。
从TMS320C6000 EDMA的结构来理解和优化其应用(连载二)丁刚【期刊名称】《无线电工程》【年(卷),期】2002(32)8【摘要】增强DMA(EDMA)控制器是控制芯片除二级内存外的数据移动的高效传输引擎,存在于TMS320C621x、TMS320C671x和TMS320C641x等系列的数字信号处理器中,并会成为TI未来C6000 DSP的标准配置。
可编程的多个通道(C621x和C671x有十六个,而C641x则有六十四个)及一个快速DMA(ODMA)为数据传输提供了极大的灵活性。
然而灵活性也对编程提出了要求,必须巧妙地设计数据搬移,充分发挥EDMA的性能。
掌握底层EDMA体系结构并理解所有传输方法的原理并不太难。
文章介绍了EDMA有什么样的传输类型、传输是如何发送的以及共同使用多个传输时,相互之间是如何影响的。
掌握这些知识可有效设计传输过程,以便其充分利用EDMA的带宽。
【总页数】5页(P29-32,47)【作者】丁刚【作者单位】德州仪器(中国)有限公司上海办事处【正文语种】中文【中图分类】TP3【相关文献】1.应用粒子群-序列二次规划算法的结构可靠性优化 [J], 唐承;郭书祥;莫延彧;龚小平2.新城金矿二步采场结构参数优化及应用 [J], 苏环;张丹丹;侯俊3.从TMS320C6000EDMA的结构来理解和优化其应用(连载一) [J], 丁刚4.单片机原理及应用连载:第二讲 MCS—80C196的封装及内部结构 [J], 贺昱曜5.现代仪器分析在聚氨酯中的应用(连载七)核磁共振在聚氨酯结构研究中的应用(二) [J], 吴美玉因版权原因,仅展示原文概要,查看原文内容请购买。
DSP(TMS320C6713)入门之旅四、edma的理解和使用EDMA的全称是:Enhanced Direct Memory Access(增强型dma),增强型直接内存存取(EDMA)是数字信号处理器(DSP)中用于快速数据交换的重要技术,具有独立于CPU的后台批量数据传输的能力,能够满足实时图像处理中高速数据传输的要求。
以TI公司的TMS320C6713型DSP为例,介绍EDMA控制器的特点。
结合实例给出EDMA在数据实时传输中的具体控制和实现方法。
实验结果表明,通过灵活控制EDMA不仅能够提高数据的传输效率,而且能够充分发挥:DSP的高速性能。
也就是在我们一般的dma的基础上做了一下加工以完成特定的功能。
比如我们dma传送数据一般是连续的一片数据块,但是我们想间隔着传送就不行了。
还有就是增强型的dma可以实现二维的传送和一个事件可以发起两次传送,这样就可以很好的服务我们的数据传送要求!如图EDMA结构图:可以看到我们配置自己的edma之后,就等待传送事件的到来,当传送事件到来的时候edma的控制器就接受到一个触发信号,就进入传送过程。
传送的规则定义在edma的每一个通道的参数设置里面,我们可以通过控制传送的参数来达到我们要传送的数据的控制的目的!传送参数表如图:第一个双字就是控制edma传送的规则,比如:一维单元同步,一维帧同步,二维等等。
这些控制属性得在这个域里面对其进行说明。
第二个双字就是告诉edma要传送数据的源地址,第三个双字的帧的数目和单元的数目,第四个双字就是告诉edma要传送数据的目的地址。
第五个双字告诉edma下一次触发时地址的偏移量的量。
第六个双字就是当前的单元传送完成之后的单元数目的重载值和是否edma是否需要要链接到下一个edma(注意:这儿是通道链接)我们先来理解几个概念:事件链接:实质就是想一个事件触发之后引起两次edma的搬移,当然这两次搬移不是同一个edma通道,如果是同一个edma通道,相当于同样的数据搬移两次,这样不仅没有意义,还会占用内部总线带宽,印象片内数据的流动的速度。
DSP(TMS320C6713)入门之旅一、LED的点亮最近很多朋友开始学习DSP了(小双同志也加入这个团伙),本人基本上入门。
在此给他家分享一下DSP的入门经验。
其实DSP和我们本科所使用的单片机基本上架构一致,只是在它的内部集成了一系列的运算单元和逻辑移位单元,并且安排了指令流水,这样在运算性能上大大的提高,可以完成一系列的复杂计算。
当然DSP内部也集成了一系列外设,我这儿使用的是TMS320C6713 DSP,这块DSP主频可以达到450M,可以安排8级指令流水,在同一时刻可以同时执行8条指令,当然这要求的是CPU内部的运算单元不能冲突!好了,在此我就不多介绍了,免得把大家说得晕呼呼的!我们刚才是入门了解这些基本上没用,我们得一步一步的按着简单的东西一步一步的做实验。
所以我们今天开始一个最简单的实验—LED灯的点亮!我们一般学习是要买一块开发板,在此我不做推销,其实每一块开发板都基本上差不多,很多就是按照TI公司的Demo板,而设计的。
如果没有学习板,自己看书看了半年,还不如我拿到板子调试一个月的效果,因为很多东西是要在实际中才知道他的作用。
我们用一个板子一般要几样东西:一、原理图(知道每一根信号线的走向,比如我们的LED就连接到DSP的GPIO的13脚)二、芯片资料(芯片的总的芯片Datasheet和子模块的Datasheet,一般在芯片资料中总的芯片资料会告诉大家芯片的整体规划,比如内存分布,特殊寄存器的分布和具体的地址,而子模块资料会把这个模块的功能和使用介绍得更为详细)三、电路板和仿真器(这个是投入较大的一笔了)四、编译软件和计算机(希望在做实验之前大家用过编译器,不一定是CCS,因为所有基于windows上的编译软件都是一个样)我们来开始第一步,查看我们的电路板上的LED灯的位置和DSP的信号线的连接:从左边的几个原理图的截图我们可以清晰的看到LED灯接到了GPIO的13脚,中间用了一个缓冲器过度了一下,实际的控制信号还是来自DSP的GPIO13。
EDMA的全称是:Enhanced Direct Memory Access(增强型dma),增强型直接内存存取(EDMA)是数字信号处理器(DSP)中用于快速数据交换的重要技术,具有独立于CPU的后台批量数据传输的能力,能够满足实时图像处理中高速数据传输的要求。
以TI公司的TMS320C6713型DSP为例,介绍EDMA控制器的特点。
结合实例给出EDMA在数据实时传输中的具体控制和实现方法。
实验结果表明,通过灵活控制EDMA不仅能够提高数据的传输效率,而且能够充分发挥:DSP的高速性能。
也就是在我们一般的dma的基础上做了一下加工以完成特定的功能。
比如我们dma传送数据一般是连续的一片数据块,但是我们想间隔着传送就不行了。
还有就是增强型的dma可以实现二维的传送和一个事件可以发起两次传送,这样就可以很好的服务我们的数据传送要求!如图EDMA结构图:可以看到我们配置自己的edma之后,就等待传送事件的到来,当传送事件到来的时候edma的控制器就接受到一个触发信号,就进入传送过程。
传送的规则定义在edma的每一个通道的参数设置里面,我们可以通过控制传送的参数来达到我们要传送的数据的控制的目的!传送参数表如图:第一个双字就是控制edma传送的规则,比如:一维单元同步,一维帧同步,二维等等。
这些控制属性得在这个域里面对其进行说明。
第二个双字就是告诉edma要传送数据的源地址,第三个双字的帧的数目和单元的数目,第四个双字就是告诉edma要传送数据的目的地址。
第五个双字告诉edma下一次触发时地址的偏移量的量。
第六个双字就是当前的单元传送完成之后的单元数目的重载值和是否edma是否需要要链接到下一个edma(注意:这儿是通道链接)我们先来理解几个概念:事件链接:实质就是想一个事件触发之后引起两次edma的搬移,当然这两次搬移不是同一个edma通道,如果是同一个edma通道,相当于同样的数据搬移两次,这样不仅没有意义,还会占用内部总线带宽,印象片内数据的流动的速度。
《国外电子元器件》2006年第10期2006年10月●应用与设计1引言在许多基于DSP的系统设计中,程序代码总是保存在ROM、Flash或其他非易失存储器中,以保证掉电时代码仍存在,因此必须要解决引导装载的问题。
自举引导(Bootload)是指系统上电时,DSP将一段存储在外部非易失性存储器的代码搬移到内部的高速存储器单元中执行(如片内RAM)。
本文以TI公司的TMS320C6713(以下简称为C6713)浮点DSP和AMD公司的AM29LV040Flash存储器为例,通过JTAG口加载来设计一个完整的引导装载方案。
2TMS320C6713的引导配置外部信号BOOTMODE[4:3]决定了C6713的引导配置,在RESET信号的上升沿BOOTMODE[4:3]信号被获取。
C6713DSP只有2种引导方式:(1)ROM/Flash引导。
外部存储器的一部分通过EDMA控制器拷贝到DSP内部地址0处。
尽管引导程序在器件从外部复位释放后才开始执行,但在CPU被保持在内部复位时,这个拷贝就进行了。
Flash宽度也通过BOOTMODE[4:3]选择。
在Flash宽度小于32bit的情况下,DSP通过EMIF读取时,可以自基于EDMA的TMS320C6713片外Flash自举引导段鲁生1,李相平1,吴魏1,谢勇2(1.海军航空工程学院电子信息工程系,山东烟台264001;2.海军91172部队,海南三亚572000)摘要:在基于DSP的系统设计中,为了保证掉电时程序不丢失,总是将程序保存在非易失性存储器中,以便系统在上电复位时可将其引导到DSP内部的RAM中执行。
以TI公司的TMS320C6713浮点DSP和AMD公司的AM29LV040Flash存储器为例,通过JTAG加载来设计一个完整的自举引导方案。
着重描述了引导引脚以及相关寄存器的设置,分析了采用EDMA传输方式将代码从Flash复制到DSP的过程,并对引导程序给出基于汇编语言的代码实现。
EDMA的全称是:Enhanced Direct Memory Access(增强型dma),增强型直接内存存取(EDMA)是数字信号处理器(DSP)中用于快速数据交换的重要技术,具有独立于CPU的后台批量数据传输的能力,能够满足实时图像处理中高速数据传输的要求。
以TI公司的TMS320C6713型DSP为例,介绍EDMA控制器的特点。
结合实例给出EDMA在数据实时传输中的具体控制和实现方法。
实验结果表明,通过灵活控制EDMA不仅能够提高数据的传输效率,而且能够充分发挥:DSP的高速性能。
也就是在我们一般的dma的基础上做了一下加工以完成特定的功能。
比如我们dma传送数据一般是连续的一片数据块,但是我们想间隔着传送就不行了。
还有就是增强型的dma可以实现二维的传送和一个事件可以发起两次传送,这样就可以很好的服务我们的数据传送要求!如图EDMA结构图:可以看到我们配置自己的edma之后,就等待传送事件的到来,当传送事件到来的时候edma的控制器就接受到一个触发信号,就进入传送过程。
传送的规则定义在edma的每一个通道的参数设置里面,我们可以通过控制传送的参数来达到我们要传送的数据的控制的目的!传送参数表如图:第一个双字就是控制edma传送的规则,比如:一维单元同步,一维帧同步,二维等等。
这些控制属性得在这个域里面对其进行说明。
第二个双字就是告诉edma要传送数据的源地址,第三个双字的帧的数目和单元的数目,第四个双字就是告诉edma要传送数据的目的地址。
第五个双字告诉edma下一次触发时地址的偏移量的量。
第六个双字就是当前的单元传送完成之后的单元数目的重载值和是否edma是否需要要链接到下一个edma(注意:这儿是通道链接)我们先来理解几个概念:事件链接:实质就是想一个事件触发之后引起两次edma的搬移,当然这两次搬移不是同一个edma通道,如果是同一个edma通道,相当于同样的数据搬移两次,这样不仅没有意义,还会占用内部总线带宽,印象片内数据的流动的速度。
那么TI设计的是将一个事件先链接到第一个通道,然后将第一个通道的完成中断事件链接到第二个edma通道。
相当于当一个事件触发之后,就触发第一个edma通道搬移数据,当第一个通道完成之后就发出一个事件触发第二个通道搬移数据,最后可以产生一个中断通知CPU。
这样一般用视频的FIFO同步。
注:大家可能会用疑问,不是是要同时搬移两块吗,怎么不是同时的呢?大家可以想想DSP内部一般就只有一条数据总线供edma使用。
那么在同一时刻只用一个数占用总线,如果我们有两个设备驱动总线数据,那么数据就不对了。
所以edma 事件同步就是先让第一个通道搬移完成触发第二个通道搬移。
通道链接:实质就是由于edma搬移的数据块就只有那么大,那么当想搬移很多很多的时候怎么办呢?当然可以在完成中断中重新设置edma参数,这样当事件到来时,就可以重新开始搬移了。
其实也可以用edma的通道链接这个属性,当这个通道的参数设置的完成时,通过链接到自己或者别人这样就不用重新设置来达到事件到来时搬移数据的目的。
通道链接的时候一般下一个通道的事件触发器是同一个,这样就不会丢失事件。
这种属性一般应用于大量数据从一个固定地址到另一个固定地址!还要就是一个提高处理速度的乒乓结构的数据的搬移。
乒乓结构:在做一些设计的时候,一般要考虑两种因素:速度和面积。
速度当然是指我们要求的处理数据的速度,面积就是存储数据的要用的内存大小(成本问题)。
在这两者之间权衡我们的算法。
在这儿讲的乒乓结构就是用面积换取速度的一种做法!我们用两块内存和两个edma通道(相互链接,同一个事件触发),第一块取名为乒,第二块取名为乓。
当一个事件到来的时候触发我们的乒通道搬移数据到乒的内存块,等待一系列事件完之后,乒通道完成就连接到乓通道。
这时就是产生一个中断告诉cpu第一个块数据已经准备好在乒内存块了,让其进行数据算法处理。
与此同时乓通道也在搬移数据到乓内存块,完成之后通知cpu,链接到乒通道······这样形成一个循环。
就好像生活中打乒乓一样!如图:四种数据搬移方式:一维单元同步搬移(1D-to-1D):设置一个edma通道为一维数据单元同步搬移时,当一个事件到来触发时一次edma搬移数据的大小就是一个单元。
那么edma数据块搬移完成之后总体大小为:ESIZE*FRMCNT*ELERLD,当下一个事件到来时,下一个源地址和目的地址的偏移由opt中sum,dum控制。
例如:ESIZE=00b,SUM=01b,DUM=01b,FRMCNT=02h,ELERLD=04h,这样搬移的数据总量为2*4=8字节。
一维帧同步搬移(1D-to-1D):设置一个edma通道为一维数据帧同步搬移时,当一个事件到来触发时一次edma 搬移数据的大小就是一帧,也就是一帧中所有单元数据总和。
那么edma数据块搬移完成之后总体大小为:ESIZE*FRMCNT*ELERLD,当下一个事件到来时,下一个源地址和目的地址的偏移由opt中sum,dum控制。
例如:ESIZE=00b,SUM=01b,DUM=01b,FRMCNT=02h,ELERLD=04h,这样搬移的数据总量为2*4=8字节。
二维数组同步搬移(2D-to-2D):设置一个edma通道为一维数据帧同步搬移时,当一个事件到来触发时一次edma 搬移数据的大小就是一个数组,也就是一帧中所有单元数据总和。
那么edma数据块搬移完成之后总体大小为:ESIZE*FRMCNT*ELERLD,当下一个事件到来时,下一个源地址和目的地址的偏移由opt中sum,dum控制。
例如:ESIZE=00b,SUM=01b,DUM=01b,FRMCNT=02h,ELECNT=04h,这样搬移的数据总量为2*4=8字节。
二维数组同步搬移(2D-to-2D):设置一个edma通道为一维数据帧同步搬移时,当一个事件到来触发时一次edma 搬移数据的大小就是一个整个数据块,也就是一个edma通道中所有数据总和。
那么edma数据块搬移完成之后总体大小为:ESIZE*FRMCNT*ELERLD,当下一个事件到来时,下一个源地址和目的地址的偏移由opt中sum,dum控制。
例如:ESIZE=00b,SUM=01b,DUM=01b,FRMCNT=02h,ELECNT=04h,这样搬移的数据总量为2*4=8字节。
实例源代码,使用timer1作为事件触发源,通过1D-1D单元同步来实现乒乓结构:/** Copyright 2003 by Texas Instruments Incorporated.* All rights reserved. Property of Texas Instruments Incorporated.* Restricted rights to use, duplicate or disclose this code are* granted through contract.**//**———main_edma1.c———* This program uses the timers to trigger EDMA events. These events in turn * trigger linked EDMA parameter tables to fill a ping pong buffer structure.* Set a breakpoint on ‘processbuff’ function. Then open two memory windows. * Use ping as the address for one memory window and pong for the other. Then* run the application. You’ll note that the program bounces between the ping * and pong buffers filling each with a value that comes from the source.* (Note: This example runs with CACHE enable).*/#include <stdio.h>#include <csl.h>#include <csl_cache.h>#include <csl_edma.h>#include <csl_timer.h>#include <csl_irq.h>/*—————————————————————————-*//* Pick which EDMA transfer completion interrupt we want to use */#define TCCINTNUM 10/* define the constants */#define BUFF_SZ 256 /* ping-pong buffer sizes in # of ints */#define FCPU 150000000 /* CPU clock frequency */#define SRATE 8000 /* data sample rate (simulated w/timer */ #define TPRD (FCPU/(4*SRATE)) /* timer period */#define TRANSFER_CNT 20 /* Transfer count *//* Create the buffers. We want to align the buffers to be cache friendly *//* by aligning them on an L2 cache line boundary. */#pragma DATA_SECTION (ping, “.buffers”);#pragma DATA_SECTION (pong, “.buffers”);#pragma DATA_SECTION (outbuff, “.buffers”);#pragma DATA_ALIGN(ping,128);#pragma DATA_ALIGN(pong,128);#pragma DATA_ALIGN(outbuff,128);int ping[BUFF_SZ];int pong[BUFF_SZ];int outbuff[BUFF_SZ];/* These two variables serve as the data sources for this example. *//* Also want to align these on a cache line boundary since they *//* sources of EDMA transfers. */#pragma DATA_SECTION (ping_data, “.buffers”);#pragma DATA_SECTION (pong_data, “.buffers”);#pragma DATA_ALIGN(ping_data,128);#pragma DATA_ALIGN(pong_data,128);static int ping_data;static int pong_data;/* global variable used to track the ping-pong’ing */static int pingpong = 0;volatile int transferCount = 0;extern far void vectors();void setupInterrupts(void);void stopEdma(void); /* function used to stop EDMA *//*————————————————————————-*//* declare the CSL objects */TIMER_Handle hTimer; /* Handle for the timer device */ EDMA_Handle hEdma; /* Handle for the EDMA channel */ EDMA_Handle hEdmaPing; /* Handle for the ping EDMA reload parameters */EDMA_Handle hEdmaPong; /* Handle for the pong EDMA reload parameters */EDMA_Config cfgEdma; /* EDMA configuration structure *//* Create the EDMA configuration structure for ping transfers */EDMA_Config cfgEdmaPing = {EDMA_OPT_RMK( /* Making Options parameter register –EDMA_OPT */EDMA_OPT_PRI_LOW, /* Priority levels for EDMA events:-EDMA_OPT_PRI_LOW – Low priority EDMA transferEDMA_OPT_PRI_HIGH – High priority EDMA transfer*/EDMA_OPT_ESIZE_32BIT,/* Element size :-EDMA_OPT_ESIZE_32BIT – 32 bit wordEDMA_OPT_ESIZE_16BIT – 16 bit wordEDMA_OPT_ESIZE_8BIT - 8 bit word */EDMA_OPT_2DS_NO, /* Source dimension :-EDMA_OPT_2DS_NO – 1-dimensional sourceEDMA_OPT_2DS_YES – 2-dimensional source */EDMA_OPT_SUM_NONE, /* Source address update mode :-EDMA_OPT_SUM_NONE – Fixed address modeEDMA_OPT_SUM_INC – Increment address modeEDMA_OPT_SUM_DEC – Decrement address modeEDMA_OPT_SUM_IDX – Address modified by elementindex or frame Index */EDMA_OPT_2DD_NO, /* Destination dimension :-EDMA_OPT_2DD_NO – 1-dimensional sourceEDMA_OPT_2DD_YES – 2-dimensional source */EDMA_OPT_DUM_INC, /* Destination address updatemode :-EDMA_OPT_DUM_NONE – Fixed address modeEDMA_OPT_DUM_INC – Increment address modeEDMA_OPT_DUM_DEC – Decrement address modeEDMA_OPT_DUM_IDX – Address modified by elementindex or frame Index */EDMA_OPT_TCINT_YES, /* Transfer complete interrupt :-EDMA_OPT_TCINT_NO – Indication disabledEDMA_OPT_TCINT_YES – Indication enabled */EDMA_OPT_TCC_OF(TCCINTNUM),/* Transfer completecode */EDMA_OPT_LINK_YES, /* Linking of event parametersEDMA_OPT_LINK_NO - DisabledEDMA_OPT_LINK_YES - Enabled */EDMA_OPT_FS_NO /* Frame synchronizationEDMA_OPT_FS_NO – Channel is element/arraysynchronizedEDMA_OPT_FS_YES - Channel is frame synchronized*/ ),EDMA_SRC_OF(&ping_data),/* Source address register&ping_data – source address */EDMA_CNT_OF(BUFF_SZ), /* Transfer count parameterBUFF_SZ – buffer sizes in # of ints */EDMA_DST_OF(ping), /* Destination address parameterping – destination address */EDMA_IDX_OF(0×00000004),/* Index parameter */EDMA_RLD_OF(0×00000000) /* Count reload/linkparameter */};/* Create the EDMA configuration structure for pong transfers */EDMA_Config cfgEdmaPong = {EDMA_OPT_RMK( /* Making Options parameter register –EDMA_OPT */EDMA_OPT_PRI_LOW, /* Priority levels for EDMA events:-EDMA_OPT_PRI_LOW – Low priority EDMA transferEDMA_OPT_PRI_HIGH – High priority EDMA transfer */EDMA_OPT_ESIZE_32BIT,/* Element size :-EDMA_OPT_ESIZE_32BIT – 32 bit wordEDMA_OPT_ESIZE_16BIT – 16 bit wordEDMA_OPT_ESIZE_8BIT - 8 bit word */EDMA_OPT_2DS_NO, /* Source dimension :-EDMA_OPT_2DS_NO – 1-dimensional sourceEDMA_OPT_2DS_YES – 2-dimensional source */ EDMA_OPT_SUM_NONE, /* Source address update mode :-EDMA_OPT_SUM_NONE – Fixed address modeEDMA_OPT_SUM_INC – Increment address modeEDMA_OPT_SUM_DEC – Decrement address modeEDMA_OPT_SUM_IDX – Address modified by elementindex or frame Index */EDMA_OPT_2DD_NO, /* Destination dimension :-EDMA_OPT_2DD_NO – 1-dimensional sourceEDMA_OPT_2DD_YES – 2-dimensional source */EDMA_OPT_DUM_INC, /* Destination address updatemode :-EDMA_OPT_DUM_NONE – Fixed address modeEDMA_OPT_DUM_INC – Increment address modeEDMA_OPT_DUM_DEC – Decrement address modeEDMA_OPT_DUM_IDX – Address modified by elementindex or frame Index */EDMA_OPT_TCINT_YES, /* Transfer complete interrupt :-EDMA_OPT_TCINT_NO – Indication disabledEDMA_OPT_TCINT_YES – Indication enabled */ EDMA_OPT_TCC_OF(TCCINTNUM),/* Transfer completecode */EDMA_OPT_LINK_YES, /* Linking of event parametersEDMA_OPT_LINK_NO - DisabledEDMA_OPT_LINK_YES - Enabled */EDMA_OPT_FS_NO /* Frame synchronizationEDMA_OPT_FS_NO – Channel is element/arraysynchronizedEDMA_OPT_FS_YES - Channel is frame synchronized*/ ),EDMA_SRC_OF(&pong_data),/* Source address register&ping_data – source address */EDMA_CNT_OF(BUFF_SZ), /* Transfer count parameterBUFF_SZ – buffer sizes in # of ints */EDMA_DST_OF(pong), /* Destination address parameterping – destination address */EDMA_IDX_OF(0×00000004),/* Index parameter */EDMA_RLD_OF(0×00000000) /* Count reload/linkparameter */};/*—————————————————————————-*/void main(){/* initialize the CSL library */CSL_init();/* Configure L2 for 64K Cache and enable caching of external memory*/ CACHE_setL2Mode(CACHE_64KCACHE);CACHE_enableCaching(CACHE_CE00);/* initialize the input source data */ping_data=0×00000000;pong_data=0×80000000;/* Since these variables are the source of an EDMA transfer, we *//* need to flush them out of the cache since we just wrote to them. */ CACHE_wbInvL2(&ping_data, 4, CACHE_WAIT);CACHE_wbInvL2(&pong_data, 4, CACHE_WAIT);/* Let’s disable/clear related interrupts just in case they are pending *//* from a previous run of the program. */ setupInterrupts(); /* defined below *//* Although not required, let’s clear all of the EDMA parameter RAM. */ /* This makes it easier to view the RAM and see the changes as we */ /* configure it. */EDMA_clearPram(0×00000000);/* Let’s open up a timer device, we’ll use this to simulate input events */ /* at a given sample rate. */hTimer = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET);/* Lets open up the EDMA channel associated with timer #1. */hEdma = EDMA_open(EDMA_CHA_TINT1, EDMA_OPEN_RESET);/* We also need two EDMA reload parameter sets so let’s allocate them */ /* here. Notice the -1, this means allocate any availale table. */ hEdmaPing = EDMA_allocTable(-1);hEdmaPong = EDMA_allocTable(-1);/* Let’s copy the ping reload configuration structure to an *//* intermediate configuration structure. */cfgEdma = cfgEdmaPing;/* Let’s initialize the link fields of the configuration structures */ cfgEdmaPing.rld = EDMA_RLD_RMK(0,hEdmaPing);cfgEdmaPong.rld = EDMA_RLD_RMK(0,hEdmaPong);cfgEdma.rld = EDMA_RLD_RMK(0,hEdmaPong);/* Now let’s program up the EDMA channel with the configuration structure */EDMA_config(hEdma, &cfgEdma);/* Let’s also configure th e reload parameter tables in the EDMA PRAM */ /* with the values in the configuration structures. */EDMA_config(hEdmaPing, &cfgEdmaPing);EDMA_config(hEdmaPong, &cfgEdmaPong);/* Configure up the timer. */TIMER_configArgs(hTimer,TIMER_CTL_OF(0×00000200),TIMER_PRD_OF(TPRD), /* timer period */TIMER_CNT_OF(0));/* Enable the related interrupts */IRQ_enable(IRQ_EVT_EDMAINT);EDMA_intDisable(TCCINTNUM);EDMA_intClear(TCCINTNUM);EDMA_intEnable(TCCINTNUM);/* Enable the EDMA channel */EDMA_enableChannel(hEdma);/* Finally, enable the timer which will drive everything. */TIMER_start(hTimer);while(transferCount <= TRANSFER_CNT); /* waiting for interrupts */}/*—————————————————————————-*/void processbuff(int arg){int *inbuff;int x;printf(“\n %2d -”,transferCount);if (pingpong){/* If pingpong is 0, then we own the ping input buffer */inbuff = ping;printf(” Ping “);}else{/* If pingpong is 1, then we own the pong input buffer */inbuff = pong;printf(” Pong ” );}transferCount++;/* Now let’s process the input buffer, for simplicity, we’ll *//* just copy it to the output buffer. */for (x=0; x<BUFF_SZ; x++) {outbuff[x] = inbuff[x];}/* If this example is enhanced to actually do something with the *//* output buffer such as DMA it somewhere, you will want to flush *//* it out of the cache first. */CACHE_wbInvL2(outbuff, (BUFF_SZ << 2), CACHE_WAIT);/* Since we’re done processing the input buffer, clean it from cache, *//* this invalidates it from cache to ensure we read a fresh version *//* the next time. */CACHE_wbInvL2(inbuff, (BUFF_SZ << 2), CACHE_WAIT);}/*—————————————————————————-*//************************************************************************ \name: SetInterruptsEdmapurpose: Sets up interrupts to service EDMA transfersinputs: voidreturns: void\************************************************************************void setupInterrupts(void){IRQ_setVecs(vectors); /* point to the IRQ vector table */IRQ_nmiEnable();IRQ_globalEnable();IRQ_map(IRQ_EVT_EDMAINT, 8);IRQ_reset(IRQ_EVT_EDMAINT);} /* End of SetInterruptsEdma() *//************************************************************************ \name: Interrupt Service Routine c_int08purpose: ISR to service EDMAINT. vecs.asm must be modified to include c_int08 entry.inputs: n/areturns: n/a\************************************************************************ /interrupt voidc_int08(void){/* Clear the pending interrupt from the EDMA interrupt pending register */ EDMA_intClear(TCCINTNUM);/* Perform ping-pong */pingpong = (pingpong + 1) & 1;/*Exit from the program if certain no of transfres are done*/if (transferCount >= TRANSFER_CNT){TIMER_pause(hTimer);stopEdma();TIMER_close(hTimer);printf (“\nDone…..”);exit(0);}/* Based on if we ping’ed or pong’ed, we need to set the EDMA channel */ /* link address for the NEXT frame. */if (pingpong){/* Currently doing pong so setup next frame for ping *//* Modify the input data source, this just simulates *//* the input data changing. */ping_data++;/* Rememer to flush this variable out of the cache *//* since it’s the source of an EDMA transfer*/CACHE_wbInvL2(&ping_data, 4, CACHE_WAIT);/* Now filling pong so set link to ping */EDMA_link(hEdma,hEdmaPing);}else{/* Currently doing ping so setup next frame for pong *//* Modify the output data source, this just simulates *//* the input data changing. */pong_data++;/* Rememer to flush this variable out of the cache *//* since it’s the source of an EDMA transfer*/CACHE_wbInvL2(&pong_data, 4, CACHE_WAIT);/* Now filling ping so set link to pong */EDMA_link(hEdma,hEdmaPong);}processbuff(0);return;} /* end c_int08 *//************************************************************************name: stopEdmapurpose: Stops the EDMA service.inputs: voidreturns: void\************************************************************************ /void stopEdma(void) {/*Disable interrupts, close EDMA channel before exit of the program*/ IRQ_disable(IRQ_EVT_EDMAINT);EDMA_RSET(CCER,0×00000000);EDMA_disableChannel(hEdma);EDMA_intDisable(TCCINTNUM);EDMA_intClear(TCCINTNUM);EDMA_close(hEdma);EDMA_resetAll();EDMA_RSET(CIPR,0xFFFFFFFF);EDMA_RSET(ECR,0xFFFFFFFF);}。