This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EDMA3中断问题



我将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