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.

MCU-PLUS-SDK-AM263X: eDMA interrupts without interrupt vector in R5F

Part Number: MCU-PLUS-SDK-AM263X
Other Parts Discussed in Thread: AM2634, , SYSCONFIG

Hi,

I would like to activate the "transfer completion interrupt" of the eDMA on the Sitara AM2634 to trigger the PRU-CPUs and not any of the R5F CPUs.

For that purpose, I have used the "eDMA (intermediate) interrupt transfer" example available in the SDK "MCU-PLUS-SDK-AM263X". I identified that these code is used to trigger interrupt:

EDMA_ccPaRAMEntry_init(&edmaParam);
// code removed for clarity
    edmaParam.opt          |=
        (EDMA_OPT_TCINTEN_MASK | EDMA_OPT_ITCINTEN_MASK |
         ((((uint32_t)tcc) << EDMA_OPT_TCC_SHIFT) & EDMA_OPT_TCC_MASK)); // enable interrupt in the PaRAM
         
 /* Register interrupt */
intrObj.tccNum = tcc;
intrObj.cbFxn  = &EDMA_regionIsrFxn;
intrObj.appData = (void *) &gEdmaTestDoneSem;
status = EDMA_registerIntr(gEdmaHandle[0], &intrObj);
DebugP_assert(status == SystemP_SUCCESS);

With that code, I was able to trigger the events 32 to 48 in the PRU interrupt controller with the right XBAR configuration! Unfortunately, each time the interrupt is triggered, the function EDMA_regionIsrFxn() is executed on the R5F processor on which I run the example.

Therefore, I tried to investigate what is doing the function EDMA_registerIntr() and to avoid enabling the interrupt in the R5F and I tried this code:

// get base objects of eDMA
baseAddr = EDMA_getBaseAddr(gEdmaHandle[0]);
regionId = EDMA_getRegionId(gEdmaHandle[0]);
tcc = EDMA_RESOURCE_ALLOC_ANY;

EDMA_ccPaRAMEntry_init(&edmaParam);
// code removed for clarity
    edmaParam.opt          |=
        (EDMA_OPT_TCINTEN_MASK | EDMA_OPT_ITCINTEN_MASK |
         ((((uint32_t)tcc) << EDMA_OPT_TCC_SHIFT) & EDMA_OPT_TCC_MASK)); // enable interrupt in the PaRAM
         
 /* enable interrupt */
EDMA_enableEvtIntrRegion(baseAddr, regionId, tcc);

Unfortunately, just enabling the event interrupt region does not trigger the interrupts at SoC level. Is there something I missed in order to activate  "eDMA (intermediate) interrupt transfer" without executing an IRQ-Routine on the R5F CPU?

Thank you for your help.

Br, Nicolas

  • Hi Nicolas,

    I'm looking into this and will get back with you shortly.

    Regards,
    Frank

  • Hi Nicolas,

    "eDMA (intermediate) interrupt transfer" example available in the SDK "MCU-PLUS-SDK-AM263X"

    Is this the example you used as a starting point? 

    https://software-dl.ti.com/mcu-plus-sdk/esd/AM263X/08_04_00_17/exports/docs/api_guide_am263x/EXAMPLES_DRIVERS_EDMA_INTERRUPT_TRANSFER.html

    Regards,
    Frank

  • Hi Frank,

    thank you to have a look at my problem.

    This is indeed my starting point. The example works well but has the disadvantage (for my case), to trigger an interrupt in the R5F CPU 0-0.

    Br, Nicolas

  • with the right XBAR configuration!

    I see all EDMA interrupts are routed through the ICSS-M XBAR to the ICSS-M INTC:

    • Global transfer completion interrupt
    • Region transfer completion interrupts: EDMA_TPCC_INT0 - EDMA_TPCC_INT7
    • Error interrupts: EDMA_TPCC_ERRINT, EDMA_TPCC_MPINT, EDMA_TC0_ERRINT, EDMA_TC1_ERRINT

    The interrupts are available on ICSS-M INTC System Events 32-47 for CSS_MII_RT_REG:MII_RT_EVENT_EN=0.

    without executing an IRQ-Routine on the R5F CPU?

    In Sysconfig, set "Enable Interrupt" for the EDMA to FALSE, otherwise interrupts will be registered on R5F as below:

    edma_interrupt_transfer()
        Drivers_open()
            Drivers_edmaOpen()
                EDMA_open()
                    if (prms->intrEnable == TRUE)
                        HW_WR_REG32(config->attrs->intrAggEnableAddr, config->attrs->intrAggEnableMask);
                        
                        HwiP_Params_init(&hwiPrms);
                        hwiPrms.intNum   = config->attrs->compIntrNumber;           // 72, R5FSS0_CORE0_INTR_TPCC0_INTAGGR
                        hwiPrms.callback = &EDMA_transferCompletionMasterIsrFxn;    // SDK EDMA driver internal
                        hwiPrms.args     = object->handle;
                        status = HwiP_construct(&object->hwiObj, &hwiPrms);
    

    EDMA_registerIntr():

    • Places the interrupt object in a driver-maintained (doubly-)linked list of interrupt objects.
      The interrupt objects contain the TCC, pointer to callback data, and the callback function.
    • Calls EDMA_enableEvtIntrRegion() to enable the interrupt by writing to IESR/IERSH.

    When an EDMA interrupt occurs, the EDMA driver-internal callback function EDMA_transferCompletionMasterIsrFxn() is called to determine which EDMA channel has completed (as determined by the TCC) by browsing through the linked list. Once the TCC is determined, the appropriate application-registered callback function (here EDMA_regionIsrFxn()) is invoked. This is the call stack:

    HwiP_irq_handler()                              // SDK IRQ handler
        HwiP_irq_handler_c()                        // SDK IRQ handler
            EDMA_transferCompletionMasterIsrFxn()   // SDK EDMA driver internal
                EDMA_regionIsrFxn()                 // application-registered callback function
    

    just enabling the event interrupt region does not trigger the interrupts at SoC level

    How did you determine this? I don't see anything fundamentally wrong with what you've done. Did you inspect the EDMA registers IPR/IPRH to see if the EDMA is generating the interrupt? What about the ICSS INTC registers?

    Note if the R5 isn't servicing the EDMA, then the PRU will need to do so, please see EDMA_transferCompletionMasterIsrFxn() for details.

    Regards,
    Frank

  • Hi Frank,

    Thank you for your answer. I investigated further following your indication and that works now. Indeed my issue was that the PRU was not servicing the interrupt of the eDMA and therefore, no new interrupt was generated. I haven't noticed that because the time I was starting PRU, plenty of copies were generated in the meantime.

    Acknowledging/resetting the interrupt with eDMA registers ICR/ICRH has solved my issue. I was (wrongly) thinking that eDMA "transfer completion" interrupt was not requiring acknowledgment similarly to ePWM.

    Br, Nicolas