TMS320C64X+ 中使用EDMA3中断
關(guān)于EDMA3,TI的文檔有詳細(xì)的介紹。園子里的文章http://www.cnblogs.com/fpga/archive/2009/10/13/1582516.html,http://www.cnblogs.com/fpga/archive/2009/09/25/1574127.html 對其有詳細(xì)的介紹,下面主要介紹一下如何注冊和捕獲EDMA事件完成中斷。代碼是裸奔的,沒有用到CSL。
首先,要了解一下DSP的中斷系統(tǒng),可以參考文章:http://blog.csdn.net/ruby97/article/details/7538125 。
CPU系統(tǒng)級的中斷事件一共有128個,涵蓋了各種外設(shè)的系統(tǒng)級中斷事件(每個事件的編號都是固定的)。詳細(xì)見c6455的綜述文檔。然后查看《TMS320C64x+ DSP Megamodule Reference Guide》文檔,里面對中斷系統(tǒng)有詳細(xì)描述。
這128個中斷,被分成4種:
Reset中斷
EXCEP(異常中斷)
NMI(不可屏蔽中斷)
INT[15:4]普通中斷
我們正常情況下,都是只使用普通中斷來處理事件。那么,128中斷是如何被當(dāng)做這四類中斷處理的呢?
我們可以看到,中斷控制器中有個叫做 Interrupt Selector的單元。這個單元會把128個中斷進(jìn)行一次篩選,送入DSP來處理。實際上是一個 128-->12的映射,實際上DSP系統(tǒng)級中斷處理個數(shù)非常有限。
為了解決這個問題,可以將不同中斷事件進(jìn)行一個組合,再交給DSP處理。其中EVT[3:0]是一個組合事件,可以任意組合128個事件。
所以,整個DSP中斷系統(tǒng)的架構(gòu)可以用下面的圖形來展示:
不同的事件,通過組合和篩選,最終被映射到16個系統(tǒng)級中斷里來處理。
其次,讓我們來看看如何編寫 ISR(中斷服務(wù))。
與中斷相關(guān)的必須設(shè)定的寄存器主要有
ISTP 寄存器(設(shè)置中斷向量表的首地址),必須為128字節(jié)對齊。
EVTCLRn (中斷事件清除寄存器)
EVTMASKn(中斷事件屏蔽寄存器)
EVTFLAGn (中斷事件標(biāo)識寄存器)
INTMUX (中斷事件篩選寄存器)
此外還有,ICR(中斷控制寄存器),EVTSETn(中斷事件使能寄存器),INTXSTAT(中斷異常狀態(tài)寄存器),INTXCLR(中斷異常清除寄存器)等等。
下面舉例說明:
1:編寫GPIO1的上升沿觸發(fā)EDMA3進(jìn)行EDMA數(shù)據(jù)傳輸完成中斷服務(wù)例程
首先,設(shè)置ISTP,將中斷向量表放到L2SRAM的某個地方(確保安全)。設(shè)置ICR,使能必要的中斷。EVTCLRn設(shè)置,把所有事件都清除掉。EVTMASKn使能要用到的中斷,INTMUXn篩選出需要的中斷事件。
這里,我們把 GPIO1觸發(fā)的EDMA3中斷,安排在EDMA3_INT2中,對應(yīng)128個CPU的系統(tǒng)級中斷標(biāo)號為:73 = 0x49,同時我們把EDMA3_INT2 中斷安排在 INT5的位置(優(yōu)先級比較高)
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的工作模式,設(shè)置為上升沿觸發(fā)
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對應(yīng)的中斷,查看6455綜述文檔,我們發(fā)現(xiàn)EDMA3相關(guān)的事件共有64個
其中GPIO1,對應(yīng)為事件EVT:49(注意不要跟系統(tǒng)級中斷事件混淆),EDMA初始化代碼如下:
這里,我們從EMIFA_CE2_BASE_ADDR(源地址)搬移數(shù)據(jù)到目的地址(0x009fb880),使用二維數(shù)據(jù)傳輸,每次傳輸32bit,不使用Chain模式(我們只傳輸一次)。
在OPT參數(shù)中,我們打開了傳輸完成中斷(TCINTEN = 1),LINK = NULL,并且設(shè)置 TCC(Transfer Complete Code) = 49(傳輸完成碼)
這里非常容易混淆,TCC的值該如何設(shè)定? 文檔中的表述說明,其實TCC的值可以隨意設(shè)定(0-63)假設(shè)為:n,一旦該傳輸完成,EDMA3內(nèi)部通道:n,產(chǎn)生一個事件(注意這是EDMA內(nèi)部事件)
IPTRn對應(yīng)的某個位置變成:1。表明觸發(fā)了該事件!!!不同的EDMA通道,可以設(shè)定相同的TCC(但是我不建議這么做,除非你有一個理由!)
這樣一來,我搞了好久才發(fā)現(xiàn),EDMA3的觸發(fā)事件(外設(shè)觸發(fā)EDMA傳輸) 和 EDMA3 通道傳輸完成事件(TCC=n)并一毛錢的關(guān)系!!!
那么EDMA3 的內(nèi)部事件如何捕獲呢?
我們發(fā)現(xiàn),EDMA3 傳輸完成事件,總共有64個,然而EDMA3在CPU系統(tǒng)級中斷對應(yīng)的只有 8個事件
64個事件,怎么當(dāng)做8個事件來處理呢???這里就要看到EDMA3內(nèi)部有個DRAE(DMA Region Access Enable Register),這幾組寄存器來對EDMA3的64個事件進(jìn)行篩選(MASK),映射到8個系統(tǒng)級中斷中去。
總結(jié)一下:
對于要使用中斷的通道而言,要確保對應(yīng)的Parameter Set中的OPT位置上 TCINTEN = 1, TCC = n(n隨意,是對應(yīng)EDMA3內(nèi)部完成事件標(biāo)號),使能該事件 EESR = n,使能該事件中斷 IESR = n,配置 DRAE = n
對于不使用傳輸完成中斷的通道而言,OPT中設(shè)置 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 4
MVKL.S2 _EDMA3CC_INT2,B0
MVKH.S2 _EDMA3CC_INT2,B0
b.S2 B0
LDW.D2 *++B15,B0
NOP 4
nop
最后,編寫對應(yīng)的中斷服務(wù)例程
void interrupt EDMA3CC_INT2()
{
EDMA3CC_EMCR = 0xFFFFFFFF;
EDMA3CC_EMCRH = 0xFFFFFFFF;
EDMA3CC_ICR = 0xFFFFFFFF;
EDMA3CC_ICRH = 0xFFFFFFFF;
// do something
}
總結(jié)
以上是生活随笔為你收集整理的TMS320C64X+ 中使用EDMA3中断的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 道德准则
- 下一篇: 信用卡结清证明怎么打?这些条件要满足