关于EDMA3,TI的文档有详细的介绍。园子里的文章 http://www.cnblogs.com/fpga/archive/2009/10/13/1582516.html,http://www.cnblogs.com/fpga/archive/2009/09/25/1574127.html 对其有详细的介绍,下面主要介绍一下如何注册和捕获EDMA事件完成中断。代码是裸奔的,没有用到CSL。
首先,要了解一下DSP的中断系统,可以参考文章:http://blog.csdn.net/ruby97/article/details/7538125 。
CPU系统级的中断事件一共有128个,涵盖了各种外设的系统级中断事件(每个事件的编号都是固定的)。详细见c6455的综述文档。然后查看《TMS320C64x+ DSP Megamodule Reference Guide》文档,里面对中断系统有详细描述。
这128个中断,被分成4种:
- Reset中断
- EXCEP(异常中断)
- NMI(不可屏蔽中断)
- INT[15:4]普通中断
我们正常情况下,都是只使用普通中断来处理事件。那么,128中断是如何被当做这四类中断处理的呢?
我们可以看到,中断控制器中有个叫做 Interrupt Selector的单元。这个单元会把128个中断进行一次筛选,送入DSP来处理。实际上是一个 128-->12的映射,实际上DSP系统级中断处理个数非常有限。
为了解决这个问题,可以将不同中断事件进行一个组合,再交给DSP处理。其中EVT[3:0]是一个组合事件,可以任意组合128个事件。
所以,整个DSP中断系统的架构可以用下面的图形来展示:
不同的事件,通过组合和筛选,最终被映射到16个系统级中断里来处理。
其次,让我们来看看如何编写 ISR(中断服务)。
与中断相关的必须设定的寄存器主要有
- ISTP 寄存器(设置中断向量表的首地址),必须为128字节对齐。
- EVTCLRn (中断事件清除寄存器)
- EVTMASKn(中断事件屏蔽寄存器)
- EVTFLAGn (中断事件标识寄存器)
- INTMUX (中断事件筛选寄存器)
此外还有,ICR(中断控制寄存器),EVTSETn(中断事件使能寄存器),INTXSTAT(中断异常状态寄存器),INTXCLR(中断异常清除寄存器)等等。
下面举例说明:
1:编写GPIO1的上升沿触发EDMA3进行EDMA数据传输完成中断服务例程
首先,设置ISTP,将中断向量表放到L2SRAM的某个地方(确保安全)。设置ICR,使能必要的中断。EVTCLRn设置,把所有事件都清除掉。EVTMASKn使能要用到的中断,INTMUXn筛选出需要的中断事件。
这里,我们把 GPIO1触发的EDMA3中断,安排在EDMA3_INT2中,对应128个CPU的系统级中断标号为:73 = 0x49,同时我们把EDMA3_INT2 中断安排在 INT5的位置(优先级比较高)
ICR = 0x0000FFF0;
ISTP = 0x00922000; // interruput vector table location EVTCLR0 = 0xFFFFFFFF;
EVTCLR1 = 0xFFFFFFFF;
EVTCLR2 = 0xFFFFFFFF;
EVTCLR3 = 0xFFFFFFFF; EVTMASK0 = 0xFFFFFFFF;
EVTMASK1 = 0xFFFFFFFF;
EVTMASK2 = 0xFFFFFFFF;
EVTMASK3 = 0xFFFFFFFF; INTMUX1 = 0x4700492A; // enable INT4 to RINT1, INT5 to EDMA3CC_INT2, INT7 to EDMA3CC_INT0,
INTMUX2 = 0x00004548; // enable INT8 to EDMA3CC_INT1 //enable INT9 to TINT1
INTMUX3 = 0x00000000; // IER |= 0x2; // ENABLE NMI
IER |= 0x7f0; // ENABLE INT4 INT7 INT8 INT9 INT10 CSR |= 0x1; // enable intertuput
接着,千万别玩了配置GPIO1的工作模式,设置为上升沿触发
GP_BINTEN |= 0x1 ; //enable gpio as souce of interruput
GP_DIR &= (0xffffffaf); //set GP[4] GP[6] output
GP_DIR |= (0xa2); //set GP[5] GP[7] GP[1] as input
GP_SET_RIS_TRIG |= 0xa2 ; //the rising edge of gpio1 and gpio5 gpio7 trige the interruput or event
然后,我们要配置EDMA3的GPIO对应的中断,查看6455综述文档,我们发现EDMA3相关的事件共有64个
其中GPIO1,对应为事件EVT:49(注意不要跟系统级中断事件混淆),EDMA初始化代码如下:
这里,我们从EMIFA_CE2_BASE_ADDR(源地址)搬移数据到目的地址(0x009fb880),使用二维数据传输,每次传输32bit,不使用Chain模式(我们只传输一次)。
在OPT参数中,我们打开了传输完成中断(TCINTEN = 1),LINK = NULL,并且设置 TCC(Transfer Complete Code) = 49(传输完成码)
这里非常容易混淆,TCC的值该如何设定? 文档中的表述说明,其实TCC的值可以随意设定(0-63)假设为:n,一旦该传输完成,EDMA3内部通道:n,产生一个事件(注意这是EDMA内部事件)
IPTRn对应的某个位置变成:1。表明触发了该事件!!!不同的EDMA通道,可以设定相同的TCC(但是我不建议这么做,除非你有一个理由!)
这样一来,我搞了好久才发现,EDMA3的触发事件(外设触发EDMA传输) 和 EDMA3 通道传输完成事件(TCC=n)并一毛钱的关系!!!
那么EDMA3 的内部事件如何捕获呢?
我们发现,EDMA3 传输完成事件,总共有64个,然而EDMA3在CPU系统级中断对应的只有 8个事件
64个事件,怎么当做8个事件来处理呢???这里就要看到EDMA3内部有个DRAE(DMA Region Access Enable Register),这几组寄存器来对EDMA3的64个事件进行筛选(MASK),映射到8个系统级中断中去。
总结一下:
对于要使用中断的通道而言,要确保对应的Parameter Set中的OPT位置上 TCINTEN = 1, TCC = n(n随意,是对应EDMA3内部完成事件标号),使能该事件 EESR = n,使能该事件中断 IESR = n,配置 DRAE = n
对于不使用传输完成中断的通道而言,OPT中设置 TCINTEN = 0即可
EDMA3CC_DRAE2 = 0x00000004;
EDMA3CC_DRAEH2 = 0x00000000; EDMA3CC_DCHMAP49 = 0x000000A0; // map channel 49(tied to gpio1 event) to PaRAM set 5
EDMA3CC_EESRH |= 0x00020000; // enable the event/channel 49
EDMA3CC_IESR |= 0x00000000; // enable the TCC=49 interrupt
EDMA3CC_IESRH |= 0x00020000;
EDMA3CC_DMAQNUM6 |= 0x00000020; //Event 49 is queued on Q2
pEDMA3CC_PaRAM = EDMA3CC_PaRAM5;
pEDMA3CC_PaRAM->OPT = 0x0013120C; //TCINTEN=1;TCC=49;SYNCDIM=1(AB);32-bit mode,static=1
pEDMA3CC_PaRAM->SRC = EMIFA_CE2_BASE_ADDR;//EMIFA_CE2_BASE_ADDR
pEDMA3CC_PaRAM->BCNT_ACNT = 0x05000004; //ACNT=32;BCNT=4576;
pEDMA3CC_PaRAM->DST = (volatile long*)(0x009fb880);//
pEDMA3CC_PaRAM->DSTBIDX_SRCBIDX = 0x00040004; //DSTBIDX=8;SRCBIDX=8;
pEDMA3CC_PaRAM->BCNTRLD_LINK = 0x0000FFFF; //LINK=NULL
pEDMA3CC_PaRAM->DSTCIDX_SRCCIDX = 0x0;
pEDMA3CC_PaRAM->RSVD_CCNT = 0x00000001; EDMA3CC_EMCR = 0xFFFFFFFF;
EDMA3CC_EMCRH = 0xFFFFFFFF;
EDMA3CC_ICR = 0xFFFFFFFF;
EDMA3CC_ICRH = 0xFFFFFFFF;
然后,配置中断向量表
.ref _EDMA3CC_INT2
INT5:
STW.D2 B0,*B15--
NOP
MVKL.S2 _EDMA3CC_INT2,B0
MVKH.S2 _EDMA3CC_INT2,B0
b.S2 B0
LDW.D2 *++B15,B0
NOP
nop
最后,编写对应的中断服务例程
void interrupt EDMA3CC_INT2()
{
EDMA3CC_EMCR = 0xFFFFFFFF;
EDMA3CC_EMCRH = 0xFFFFFFFF;
EDMA3CC_ICR = 0xFFFFFFFF;
EDMA3CC_ICRH = 0xFFFFFFFF;
// do something
}
TMS320C64X+ 中使用EDMA3中断的更多相关文章
-
操作系统开发系列—12.g.在内核中设置键盘中断
8259A虽然已经设置完成,但是我们还没有真正开始使用它呢. 所有的中断都会触发一个函数spurious_irq(),这个函数的定义如下: PUBLIC void spurious_irq(int i ...
-
向linux内核中添加外部中断驱动模块
本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...
-
uboot中添加FIQ中断及相关问题
本文主要说明了在uboot中添加FIQ中断时遇到的问题以及对应的解决办法. 首先交代一下项目的软硬件环境.硬件方面,使用s3c2440作为主控芯片,外接串口.网卡等设备.软件方面,主控芯片上电后运行u ...
-
[转] IE6中请求莫名中断
这两天碰到的问题,IE6下某个js生成的a节点,设置了href="javascript:;",点击时触一个ajax请求,但在IE6下就是无法执行succese里的内容,所以就用se ...
-
函数可重入问题reentrant functions(函数执行过程中可以被中断,允许多个副本)
最近经常听到这个名词,以前也听到过,不过接触更多的是“线程安全问题”,而且本人也一直理解的是两个名字的含义是一样的.今天仔细总结一下这个名词相关的概念. 引用博文:可重入函数和不可重入函数 (http ...
-
Asp.Net mvc筛选器中返回信息中断操作
在mvc中,使用response.end()或Response.Redirect("url"); 是无法阻止请求继续往下执行的.如果在action中,可以我们可以使用return ...
-
linux 中nvme 的中断申请及处理
/** * struct irq_desc - interrupt descriptor * @irq_data: per irq and chip data passed down to chip ...
-
2—ARM中的异常中断
ARM体系中的3种控制程序执行的方式 正常执行过程中,每执行1条ARM指令,PC的值加4个字节:每执行1条Thumb指令,PC的值加2个字节.整个过程按照顺序执行. 通过跳转指令,调到特定的地址开始执 ...
-
freeertos中关于PendSV中断服务函数的解析
__asm void xPortPendSVHandler( void ) { extern uxCriticalNesting; extern pxCurrentTCB; extern vTaskS ...
随机推荐
-
常用MySQL图形化管理工具
MySQL的管理维护工具非常多,除了系统自带的命令行管理工具之外,还有许多其他的图形化管理工具,这里我介绍几个经常使用的MySQL图形化管理工具,供大家参考. MySQL是一个非常流行的小型关系型数据 ...
-
c# 函数
1.输入三个数,求最大的数. 2.输入一个数,求1~n的和. 3.求n的阶乘. 4.输入一个小于等于100的数,判断是否是100,还是小于10,还是两位数.
-
在Linux(Ubuntu)下搭建ASP.NET Core环境并运行 继续跨平台
最新教程:http://www.cnblogs.com/linezero/p/aspnetcoreubuntu.html 无需安装mono,在Linux(Ubuntu)下搭建ASP.NET Core环 ...
-
leetcode 26
26. Remove Duplicates from Sorted Array Given a sorted array, remove the duplicates in place such th ...
-
PS-文字如何竖排版
单击文字输入工具“T”按钮,点住鼠标左键不要松手,会在“T”按钮的右边显示出其它形式的文字工具,拖动鼠标指向“直排文字”工具就可以了.
-
PCB的整个加工流程
1 MI:制作生产流程卡,指导产线如何去生产出所需要的pcb.2 内层:PCB,除了最便宜的单层板,简单的双层板,有时候需要使用4层 6层 8层,以实现复杂的连 接关系和高密度,再就是减少干扰或者降低 ...
-
Python的可变类型与不可变类型
Python基础知识,自己写一写比较不容易忘 Python的每个对象都分为可变和不可变,主要的核心类型中,数字.字符串.元组是不可变的,列表.字典是可变的. 对不可变类型的变量重新赋值,实际上是重新创 ...
-
Servlet - 基础
Servlet 标签 : Java与Web HTTP协议 HTTP(hypertext transport protocol),即超文本传输协议.这个协议详细规定了浏览器(Browser)和万维网服务 ...
-
MATLAB基础函数命令
1. 常用命令 dir:列出当前目录下的所有文件 clc:清除命令窗 clear all:清除环境(从内存中清除所有变量) who:将内存中的当前变量以简单形式列出 close all: 关闭所有的 ...
-
微信小程序Promise对象
Promise 对象 Promise 的含义 基本用法 Promise.prototype.then() Promise.prototype.catch() Promise.prototype.fin ...