我将CIC0的系统事件36映射到主机事件33,然后将主机事件33映射到CPU中断15,产生中断后输出"Hello EDMA3..."。
在主程序中,两次触发CC0的DMA2以完成一次数据传输,产生传输完成中断,此为第一次传输完成中断。
但是,再次触发CC0的DMA2后,无法完成中断触发,而通过轮询的方式,可以得知传输完成中断在第二次传输的时候也被触发了,只是没有进入中断函数执行。 也就是是说,两次传输,只有第一次进入中断函数了。
(调试很久了,还是没有解决掉,望解答。在此谢过!!!)
代码如下:
#include <stdio.h>
#include "csl_edma3.h"
#include "KeyStone_common.h"
#define CIC0_OUT33 33 // CIC0 out host event number
#define EDMA3CC0_GINT 22 // EDMA3CC0 GINT (input event for INTC)
/* Manually-Triggered Transfer Request */
void EDMA_manualTrigger(Uint32 ccNum , Uint32 channelNum){
if(channelNum < 32){
gpEDMA_CC_regs[ccNum]->TPCC_ESR = 1<<(channelNum);
}
else{
gpEDMA_CC_regs[ccNum]->TPCC_ESR = 1<<(channelNum-32);
}
}
/* PaRAM set initialize */
void EDMA_PaRAMsetSetup(
EDMA_CC_Channel_Num CC_channel, // enumeration for channel m in CCn
unsigned int srcAddr, // SRC
unsigned int dstAddr, // DST
unsigned short aCnt, // ACNT
unsigned short bCnt, // BCNT
unsigned short cCnt, // CCNT
short srcBidx, // SRCBIDX
short dstBidx, // DSTBIDX
short srcCidx, // SRCCIDX
short dstCidx, // DSTCIDX
unsigned short bCntRld, // BCNTRLD
unsigned short link // LINK
)
{
CSL_TpccRegs* EDMACCRegs;
unsigned int uiChannel;
EDMACCRegs= gpEDMA_CC_regs[CC_channel>>16];
uiChannel = CC_channel&0xFF;
EDMACCRegs->PARAMSET[uiChannel].OPT=
CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS,
CSL_EDMA3_TCCH_DIS,
CSL_EDMA3_ITCINT_DIS,
CSL_EDMA3_TCINT_EN,
uiChannel, // TCC
CSL_EDMA3_TCC_NORMAL,
CSL_EDMA3_FIFOWIDTH_NONE,
CSL_EDMA3_STATIC_DIS,
CSL_EDMA3_SYNC_A,
CSL_EDMA3_ADDRMODE_INCR,
CSL_EDMA3_ADDRMODE_INCR);
EDMACCRegs->PARAMSET[uiChannel].SRC= (Uint32)(srcAddr);
EDMACCRegs->PARAMSET[uiChannel].A_B_CNT=CSL_EDMA3_CNT_MAKE(aCnt&0xFFFF, bCnt&0xFFFF);
EDMACCRegs->PARAMSET[uiChannel].DST= (Uint32)(dstAddr);
EDMACCRegs->PARAMSET[uiChannel].SRC_DST_BIDX= CSL_EDMA3_BIDX_MAKE(srcBidx&0xFFFF,dstBidx&0xFFFF);
EDMACCRegs->PARAMSET[uiChannel].LINK_BCNTRLD= CSL_EDMA3_LINKBCNTRLD_MAKE(link&0xFFFF, bCntRld&0xFFFF);
EDMACCRegs->PARAMSET[uiChannel].SRC_DST_CIDX= CSL_EDMA3_CIDX_MAKE(srcCidx,dstCidx);
EDMACCRegs->PARAMSET[uiChannel].CCNT= cCnt;
}
/* CIC0 initizlize */
void CIC0Init(void){
/*disables all the host interrupts at once*/
gpCIC0_regs->GLOBAL_ENABLE_HINT_REG=0; // Global Enable Register
/*map the system event(EDMA3CC0 CCINT0) to CIC0_OUT33(host event)*/
gpCIC0_regs->CH_MAP[CSL_INTC0_CPU_2_EDMACC_GINT] = CIC0_OUT33; // Channel Map Registers
/*clearing the status of an interrupt*/
gpCIC0_regs->STATUS_CLR_INDEX_REG = CSL_INTC0_CPU_2_EDMACC_GINT; // System Interrupt Status Indexed Clear Register
/*enabling an interrupt*/
gpCIC0_regs->ENABLE_SET_INDEX_REG = CSL_INTC0_CPU_2_EDMACC_GINT; // System Interrupt Enable Indexed Set Register
/*enabling a host interrupt output. */
gpCIC0_regs->HINT_ENABLE_SET_INDEX_REG = CIC0_OUT33; // Host Interrupt Enable Indexed Set Register
/*enables all the host interrupts*/
gpCIC0_regs->GLOBAL_ENABLE_HINT_REG=1;
}
/* INTC initialize*/
void IntcInit(void){
CIC0Init(); // CIC0_OUT33 for core 0
/*initialize event selector*/
gpCGEM_regs->INTMUX1 = 0;
gpCGEM_regs->INTMUX2 = 0;
gpCGEM_regs->INTMUX3 = 0;
/*initialize event combiner*/
gpCGEM_regs->EVTMASK[0] = 0xFFFFFFFF;
gpCGEM_regs->EVTMASK[1] = 0xFFFFFFFF;
gpCGEM_regs->EVTMASK[2] = 0xFFFFFFFF;
gpCGEM_regs->EVTMASK[3] = 0xFFFFFFFF;
/* clear all event that input INTC */
gpCGEM_regs->EVTCLR[0]= 0xFFFFFFFF;
gpCGEM_regs->EVTCLR[1]= 0xFFFFFFFF;
gpCGEM_regs->EVTCLR[2]= 0xFFFFFFFF;
gpCGEM_regs->EVTCLR[3]= 0xFFFFFFFF;
/*combine CIC0_OUT33 event into EVT[0]*/
gpCGEM_regs->EVTMASK[0] = ~(1 << EDMA3CC0_GINT);
/*route EVT0 to INT15*/
gpCGEM_regs->INTMUX3 = CSL_GEM_EVT0<<CSL_CGEM_INTMUX3_INTSEL15_SHIFT;
/*enable CPU INT15*/
CPU_interrupt_enable(1<<15);
}
/* memory for test and its initialize */
Uint8 srcBuff1[512];
Uint8 srcBuff2[512];
Uint8 dstBuff1[512];
Uint8 dstBuff2[512];
/* Initialize data */
void dataInit(){
int loopIndex;
for (loopIndex = 0; loopIndex < 512; loopIndex++) {
srcBuff1[loopIndex] = loopIndex;
srcBuff2[loopIndex] = loopIndex;
dstBuff1[loopIndex] = 0;
dstBuff2[loopIndex] = 0;
}
}
/*
* Interrupt Service Sequence include INTC,CIC and EDMA3
* so that code need to be completed with Interrupt Service Sequence
* */
void interrupt EDMA3_ISR(void){
Uint32 eventFlag;
Uint32 iprFlag;
/*read masked event flag for INTC*/
eventFlag = gpCGEM_regs->MEVTFLAG[0];
/*clear event flag to wait for next event occur for INTC*/
gpCGEM_regs->EVTCLR[2] = eventFlag;
/*Disable the host interrupt for CIC0*/
gpCIC0_regs->ENABLE_HINT_REG[1] = (0<<(CIC0_OUT33-32));
/*Read the interrupt pending register (IPR/IPRH)*/
iprFlag = gpEDMA_CC_regs[0]->TPCC_IPR;
/*Service the interrupt */
printf("hello EDMA3...\n");
/*Re-enable the host interrupt*/
gpCIC0_regs->ENABLE_HINT_REG[1] = (1<<(CIC0_OUT33-32));
/*Writes to the interrupt pending clear register*/
gpEDMA_CC_regs[0]->TPCC_ICR= iprFlag;
if(gpEDMA_CC_regs[0]->TPCC_IPR!=0){
printf("hello EDMA3...(repeat!)\n");
}
}
void main(){
/*enable TSC, memory protection interrupts, EDC for internal RAM;
* clear cache; protect L1 as cache*/
KeyStone_common_CPU_init();
/*print device information. Enable memory protection interrupts, EDC for MSMC RAM*/
KeyStone_common_device_init();
//enable exception handling
KeyStone_Exception_cfg(TRUE);
CACHE_setL1PSize(CACHE_L1_32KCACHE);
CACHE_setL1DSize(CACHE_L1_32KCACHE);
CACHE_setL2Size(CACHE_512KCACHE);
// DSP core speed: 100*10/1=1000MHz
KeyStone_main_PLL_init(100, 10, 1);
// initialize interrupt
IntcInit();
dataInit();
EDMA_init(); // PARAM set 2 for channel 2 and PARAM set 3 for channel 3...etc
// set 2 for ping buffer
EDMA_PaRAMsetSetup(
EDMA_CC0_CH2, // enumeration for channel m in CCn
(Uint32)srcBuff1, // SRC
(Uint32)dstBuff1, // DST
256, // ACNT
2, // BCNT
1, // CCNT
256, // SRCBIDX
256, // DSTBIDX
256, // SRCCIDX
256, // DSTCIDX
2, // BCNTRLD
0x4060 // LINK (pong set)
);
// set 3 for pong buffer
EDMA_PaRAMsetSetup(
EDMA_CC0_CH3, // enumeration for channel m in CCn
(Uint32)srcBuff2, // SRC
(Uint32)dstBuff2, // DST
256, // ACNT
2, // BCNT
1, // CCNT
256, // SRCBIDX
256, // DSTBIDX
256, // SRCCIDX
256, // DSTCIDX
2, // BCNTRLD
0x4040 // LINK (ping set)
);
EDMA_interrupt_enable(0 , 2); // enable interrupt for channel 2
/* 1st transmit for channel 2*/
/*because 2nd dim size is 2 , that will result in event number be need is 2*/
EDMA_manualTrigger(0 , 2); // manually trigger event for transfer
EDMA_manualTrigger(0 , 2); // manually trigger event for transfer
while(((gpEDMA_CC_regs[0]->TPCC_IPR)&(1<<2))==0); // polls bit 2 in IPR
printf("OK Test...%x\n" , gpEDMA_CC_regs[0]->TPCC_IPR);
/* clear interrupt pending register */
gpEDMA_CC_regs[0]->TPCC_ICR = gpEDMA_CC_regs[0]->TPCC_IPR;
TSC_delay_us(2000);
/* 2nd transmit for channel 2*/
EDMA_manualTrigger(0 , 2); // manually trigger event for transfer
EDMA_manualTrigger(0 , 2); // manually trigger event for transfer
while(((gpEDMA_CC_regs[0]->TPCC_IPR)&(1<<3))==0);// polls bit 3 in IPR
printf("OK Test...%x\n\n" , gpEDMA_CC_regs[0]->TPCC_IPR);
/* clear interrupt pending register */
gpEDMA_CC_regs[0]->TPCC_ICR = gpEDMA_CC_regs[0]->TPCC_IPR;
}
输出为:
hello EDMA3...
OK Test...0
OK Test...8