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 Interrupt

Hi,

I generated EDMA interrupt using INTC & CPINTC .The code works successfully if I call the transfer function of EDMA once for that channel but if I call the same EDMA transfer function again,interrupt does not occur.

What can be the reason ?

Regards,

Bharti

  • Hi Bharti.

    Please paste the code.

    Thank you.

  • Hi Bahrti,

    There are three levels where you have to clear the interrupt in your ISR: INTC, CPINTC and EDMA.

    You can accomplish this via the Interrupt vector clear register, the CPINTC status clear index register and EDMA Interrupt Pending Register.

    It's also a good idea to disable the host interrupt in CPINTC while you're in the ISR, that way a new event from the EDMA would not immideately trigger a new interrupt.

    My EDMA ISR looks something like this:

    1. clear the interrupt vector in INTC

    2. disable host interrupt in CPINTC

    3. Clear the CPINTC input event (dubbed system event CSL)

    3. get EDMA pending interrupts

    4. clear EDMA interrupts

    5. handle EDMA interrupts

    6. repeat steps 3-5 until there are no more pending EDMA interrupts

    7. enable host interrupt in CPINTC

    Hope this helps and ask again if you're uncertain about something!

  • Hi,

    I tried this out, but encountered a problem when I disable my system interrupt (22) & host interrupt (1) using 

    CSL_CPINTC_disableSysInterrupt(hnd0,22);
     
     CSL_CPINTC_disableHostInterrupt (hnd0,  1);

    & after this, I check for pending interrupts & pending host interrupt
     
    pendingStatus = CSL_CPINTC_isInterruptPending (hnd0);
    pendingStatus_host = CSL_CPINTC_isHostInterruptPending(hnd0,1);
    
    
    I get both the values true which should not be the case.
    What can be the reason?
    
    
    Regards,
    Bharti
  • Hi Bharti,

    Instead of disabling the input event to CPINTC you should clear it with:

    CSL_CPINTC_clearSysInterrupt(hnd0, 22);

    After you clear the input event to CPINTC both isInterruptPending and isHostInterruptPending should return false (unless another event has been retriggered).

    In CCS you can get a handy view of all the registers in CPINTC by watching the base address of the module and cast it to the CSL register overlay type, e.g: (CSL_CPINTCRegs*)0x02600000 It's a bit slow but I found it to be very helpful during development. 

  • Hi,

    I tried the same,but still it's returning TRUE. Could you give some more suggestions on the same.

    Regards,

    Bharti

  • Well, isInterruptPending only tells you whether there is at least one system interrupt pending in CPINTC, not which interrupts. Check out the RAW_STATUS_REG and ENA_STATUS_REG while in interrupt context. That should give you a clear idea of what is going on.

    I'm not actually sure why you want to check for pendingInterrupts, if your ISR has been triggered something has obviously happened =) Are you perhaps combining several events to one ISR?

    Maybe you could provide an example of your ISR code?

    Bsr /Henrik

  • Hi Bharti,

    The following procedure should be followed for any ISR which handles interrupts routed through the CPINTCs:

    /* For interrupts routed through the chip-level INTC */
    void CPINTC_ISR (Uint32 eventId)
    {

    /* Disable CPINTC0 Host interrupt (CPINTC output) */
    CSL_CPINTC_disableHostInterrupt(cphnd, cp_host_event);

    /* Clear the CPINTC0 Interrupt */
    CSL_CPINTC_clearSysInterrupt(cphnd, cp_event);

    /* Clear the CorePac Interrupt */
    CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTCLEAR,NULL);

    /* Do the required servicing here */
    ……
    ……

    /* Enable CPINTC0 Host interrupt (CPINTC output) */
    CSL_CPINTC_enableHostInterrupt(cphnd, cp_host_event);

    }

    The steps for INTC host interrupt disable and enable at the start and end of the ISR are not added in the current version of the INTC users guide. The above updated procedure will be added in the next revision of the INTC users guide.

    Please, let me know if following the above procedure solves your issue.

  • void main(void)
    {

    edma_interrupt_example ();
    EDMA3_transfer_channel_0();

    intFlag = 0;
    edma_interrupt_example ();
    EDMA3_transfer_channel_0();
    return;
    }


    void edma_interrupt_example (void)
    {


    /* Initialize data buffers */
    for (loopIndex = 0; loopIndex < 512; loopIndex++) {
    srcBuff[loopIndex] = loopIndex;
    dstBuff[loopIndex] = 0;
    }


    /* Intc module initialization */
    intcContext.eventhandlerRecord = EventHandler;
    intcContext.numEvtEntries = 10;
    CSL_intcInit(&intcContext);

    /* Enable NMIs */
    CSL_intcGlobalNmiEnable();

    /* Enable global interrupts */
    CSL_intcGlobalEnable(&state);

    /* Module initialization */
    status = CSL_edma3Init(&context);
    if (status != CSL_SOK) {
    printf ("Edma module initialization failed\n");
    return;
    }
    /* Edma module open */
    hModule = CSL_edma3Open(&edmaObj,instNum,NULL,&status);
    if ( (hModule == NULL) || (status != CSL_SOK)) {
    printf ("Edma module open failed\n");
    return;
    }


    /************* CPINTC Configuration *************/

    /* Open the handle to the CPINT Instance 0 */
    hnd0 = CSL_CPINTC_open(0);
    if (hnd0 == 0)
    {
    printf ("Error: Unable to open CPINTC-0\n");

    }

    /* Disable all host interrupts. */
    CSL_CPINTC_disableAllHostInterrupt (hnd0);


    /* Configure no nesting support in the CPINTC Module. */
    CSL_CPINTC_setNestingMode (hnd0, CPINTC_NO_NESTING);


    /* map System Interrupt 22 to host channel 1 */
    CSL_CPINTC_mapSystemIntrToChannel (hnd0, 22,1);

    /* enable system interrupt 22 */
    CSL_CPINTC_enableSysInterrupt (hnd0, 22);


    /* enable host interrupts. */
    CSL_CPINTC_enableHostInterrupt (hnd0, 1);


    /* Enable all host interrupts also. */
    CSL_CPINTC_enableAllHostInterrupt(hnd0);

    /* Opening a intc handle for edma event */
    vectId = CSL_INTC_VECTID_6;
    hIntcEdma = CSL_intcOpen (&intcObjEdma, 57, \
    &vectId , NULL);
    /* Association of an EDMA event handler with the INTC routine */
    EventRecord.handler = &eventEdmaHandler;
    EventRecord.arg = (void*)(hModule);
    CSL_intcPlugEventHandler(hIntcEdma,&EventRecord);


    /* Enabling event edma */
    CSL_intcHwControl(hIntcEdma,CSL_INTC_CMD_EVTENABLE,NULL);

    /* Hook up the EDMA event with an completion code function handler */
    EdmaEventHook(0, tcc0Fxn);

    }

    void EDMA3_transfer_channel_0()
    {
    /* Channel open */
    chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL;
    chAttr.chaNum = EDMA3_DL_DATA_TRANSFER_CH_0;
    hChannel = CSL_edma3ChannelOpen (&chObj, instNum, &chAttr, &status);
    if ((hChannel == NULL) || (status != CSL_SOK))
    {
    printf ("Error: Unable to open EDMA Channel %d\n", chAttr.chaNum);
    return ;
    }


    if ((status = CSL_edma3HwChannelControl (hChannel, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL)) != CSL_SOK)
    {
    printf ("Error: EDMA Enabling Acc channel\n");
    return ;
    }

    CSL_edma3MapDMAChannelToParamBlock (hModule, 0, 0);

    hParamBasic = CSL_edma3GetParamHandle (hChannel,0, &status);
    if ( hParamBasic == NULL)
    {
    printf ("Error: EDMA Failed to get parameter entry for the event\n");
    return ;
    }

    /* Edma parameter entry Setup */
    myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
    CSL_EDMA3_TCCH_DIS, \
    CSL_EDMA3_ITCINT_DIS, \
    CSL_EDMA3_TCINT_EN,\
    0,CSL_EDMA3_TCC_NORMAL,\
    CSL_EDMA3_FIFOWIDTH_NONE, \
    CSL_EDMA3_STATIC_DIS, \
    CSL_EDMA3_SYNC_A, \
    CSL_EDMA3_ADDRMODE_INCR, \
    CSL_EDMA3_ADDRMODE_INCR);
    myParamSetup.srcAddr = src1;//(Uint32)srcBuff;//(Uint32)srcAddr;
    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(512,1);
    myParamSetup.dstAddr = dst1; // (Uint32)dstBuff;//(Uint32)dstAddr;
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(1,1);
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL,
    0);
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
    myParamSetup.cCnt = 1;
    status = CSL_edma3ParamSetup(hParamBasic,&myParamSetup);
    if (status != CSL_SOK) {
    printf ("Edma param setup failed\n");
    return;
    }

    CSL_CPINTC_mapSystemIntrToChannel (hnd0, 22,1);


    /* Enabling event edma */
    CSL_intcHwControl(hIntcEdma,CSL_INTC_CMD_EVTENABLE,NULL);


    /* Enable interrupts */
    regionIntr.region = CSL_EDMA3_REGION_GLOBAL ;
    regionIntr.intr = 0x1 ;
    regionIntr.intrh = 0x0 ;
    status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);
    if (status != CSL_SOK) {
    printf ("Edma interrupt enable command failed\n");
    return;
    }

    /* Manually trigger the channel */
    status = CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);
    if (status != CSL_SOK) {
    printf ("Edma channel set command failed\n");
    return;
    }

    status = CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_CLEAR,NULL);
    if (status != CSL_SOK) {
    printf ("Edma channel set command failed\n");
    return;
    }

    if ((status = CSL_edma3HwChannelControl (hChannel, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL)) != CSL_SOK)
    {
    printf ("Error: EDMA Enabling Acc channel\n");
    return ;
    }

    }

    // eventEdmaHandler clears & disables EDMA3 events

    /* ISR*/
    void tcc0Fxn(void)
    {

    intFlag = 1;
           CSL_edma3ChannelClose ( hChannel);
    /* disabling event edma */
    CSL_intcHwControl(hIntcEdma, CSL_INTC_CMD_EVTDISABLE,NULL);

    CSL_CPINTC_disableHostInterrupt(hnd0,1);
    CSL_CPINTC_disableAllHostInterrupt(hnd0);

    CSL_CPINTC_disableSysInterrupt(hnd0,22);

    CSL_CPINTC_clearSysInterrupt(hnd0, 22);

    CSL_intcHwControl(hIntcEdma, CSL_INTC_CMD_EVTCLEAR,NULL);
    CSL_intcGlobalDisable(&state);

    pendingStatus = CSL_CPINTC_isInterruptPending (hnd0);
    pendingStatus_host = CSL_CPINTC_isHostInterruptPending(hnd0,1);  
     
    //both these above values come out to be true..

    CSL_intcClose(hIntcEdma);
    CSL_edma3Close(hModule);
    }
  • Hi there Bharti,

    I am currently trying to configure the DMA controller to transfer with interrupts on a 6678. This code fragment looks like it could be a very useful example for me to work from. Could you re-attach the fragment with the variable declarations etc included please.

    Thanks in advance,

    Pete