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.

TMS320C6670: Interrupt routing path

Part Number: TMS320C6670
Other Parts Discussed in Thread: SYSBIOS

Hello!

My question should be very newbie, but I am resorting to forum after failing to solve that myself.

I am trying to develop EDMA app. Using CSL API I have configured the transfer on Channel Controller 0. The transfer should trigger completion interrupt on global region. To check, that transfer actually completes, I put polling loop right after transfer submission

CSL_Edma3CmdIntr regionIntr;

edma_intr_enable( hModule );
fpga_tx_edma_submit( &tx1 );

regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
regionIntr.intr   = 0;
regionIntr.intrh  = 0;

/* Poll on interrupt pend bit 1 */
do
{
    CSL_edma3GetHwStatus( lte->dma->hModule, CSL_EDMA3_QUERY_INTRPEND, &regionIntr );
} while (!(regionIntr.intr));
Log_print1( Diags_USER1, "controller(): regionIntr.intr: %x", regionIntr.intr );

This piece of code prints 0x40 which matches expected TCC=6. However, ISR is not invoked and I want to trace down why.

 First of all, in C6670 data sheet SPRUGH7, Table Table 7-39 CIC0 Event Inputs — C66x CorePac Secondary Interrupts I have found EDMA3CC0 EDMACC_GINT is Event# 36. Next, as this event is listed as secondary, I refer Figure 7-29 Interrupt Topology in the same data sheet and see that "117 Core-only Secondary Events" route through CIC0.

Next, in TMS320C66x DSP CorePac User Guide SPRUGW0B, Table 9-2 System Event Mapping, EDMA global interrupt is not hard mapped and needs to be programmed. Also I refer A.1 Debug Checklist in Keystone EDMA3 UG SPRUGS5B. Item 1) The interrupt generation is enabled in the OPT is OK, I have

cfg.option = CSL_EDMA3_OPT_MAKE
        (
            CSL_EDMA3_ITCCH_DIS,        // itcchEn,
            CSL_EDMA3_TCCH_DIS,         // tcchEn,
            CSL_EDMA3_ITCINT_DIS,       // itcintEn,
            CSL_EDMA3_TCINT_EN,         // tcintEn,
            6,                          // tcc,
            CSL_EDMA3_TCC_NORMAL,       // tccMode,
...
CSL_edma3ParamSetup( hdl, &cfg );

The second is 2) The interrupts are enabled in the EDMA3 Channel Controller, via the Interrupt Enable Registers (IER/IERH). For that I have

regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
regionIntr.intr   = 0xC0;
regionIntr.intrh  = 0x0000;
CSL_edma3HwControl( hModule, CSL_EDMA3_CMD_INTR_ENABLE, &regionIntr );

Then, likely 3) The corresponding interrupts are enabled in the device interrupt controller is the root of my problem.

In my sysbios config I have

EventCombiner.eventGroupHwiNum[0] = 7;
EventCombiner.eventGroupHwiNum[1] = 8;
EventCombiner.eventGroupHwiNum[2] = 9;
EventCombiner.eventGroupHwiNum[3] = 10;


// Plug function and argument for event 31 then enable it.
EventCombiner.events[36].fxn    = '&edma_isr';
EventCombiner.events[36].arg    = 36;
EventCombiner.events[36].unmask = true;

So I believe event 36 which is EDMA global interrupt is connected with ISR. Event combiner puts event 36 on its output 1, which in turn, is tied with HWI 8. The latter is enabled too.

So once again, I thing that EDMA interrupt first enters CIC0, aka CpIntcC. So I put

hnd = CSL_CPINTC_open(0);    // Opens CPINTC Instance 0
CSL_CPINTC_mapSystemIntrToChannel( hnd, CSL_INTC0_CPU_2_EDMACC_GINT, CSL_INTC0_CPU_2_EDMACC_GINT );
CSL_CPINTC_enableSysInterrupt(hnd, CSL_INTC0_CPU_2_EDMACC_GINT);

CSL_INTC0_CPU_2_EDMACC_GINT is 36 and I think I mapped system event 36 to channel 36, which is host interrupt 36. I expect, that Event combiner pick this event and trigger HWI, but that does not happen. Please help me to understand interrupt flow in this particular case.

Thanks in advance.

  • I've forwarded this to the software experts. Their feedback should be posted here.

    BR
    Tsvetolin Shulev
  • Hi,

    EDMA OPT field looks OK. For interrupt code:

    CSL_INTC0_CPU_2_EDMACC_GINT is 36 and I think I mapped system event 36 to channel 36. ====> No, if you look at Table 7-38, this is no CIC0_OUT36.

    Can you check this wiki processors.wiki.ti.com/.../Configuring_Interrupts_on_Keystone_Devices if this resolve your problem? It has example to use either CSL or SYSBIOS.

    In our Processor SDK RTOS, we aslo have an example:pdk_c667x_2_0_5\packages\ti\boot\examples\pcie\pcieboot_interrupt\src, for 6670, it mapped secondary interrupt PCIEXpress_Legacy_INTA (50) to channel 3. INTC0_OUT3 is connected to VectID 4. For your case, PCIEXpress_Legacy_INTA needs to be replaced with EDMA3CC0 EDMACC_GINT (36). The code is written in CSL, the callflow is the same for SYSBIOS.

    Regards, Eric
  • Hi,

    Thank you for your response. Good thing you see mistake in my code, so I could find it later too :-)

    First of all, I've managed to get interrupt working a little different way. I peeped that in CpIntc help. It looks like

    CpIntc.sysInts[36].fxn      = '&edma_isr';
    CpIntc.sysInts[36].arg      = 36;
    CpIntc.sysInts[36].hostInt  = 2;
    CpIntc.sysInts[36].enable   = true;
    
    var eventId = CpIntc.getEventIdMeta(2);
    params               = new Hwi.Params;
    params.arg           = 2;
    params.instance.name = 'edma';
    params.eventId       = eventId;
    params.enableInt     = 1;
    Program.global.hwi11 = Hwi.create(11, CpIntc.dispatch, params);

    The difference with previous attempt was that I was trying to attach my ISR to

    EventCombiner.events[36].fxn    = '&edma_isr';

    i.e. to event combiner of the CorePack INTC, while system event under interest was input to CIC. Though it worked for me, I don't feel myself capable enough to reproduce fro the scratch on my own. I have jumped to C6670 from C41x, that is huge leap, and its hard for me sometimes to catch up.

    So once again, I'd like to ask for clarification.

    As I understand, one HWI may serve for either one event, or their combination. And it seems to me that depending on the former or latter scheme, the place where ISR is attached is different. If we used just single event to trigger HWI, then we put

    var PCIeMSI_hwi_N_Params            =   new Hwi.Params();
    PCIeMSI_hwi_N_Params.instance.name  =   "hwi_pcie_N";
    PCIeMSI_hwi_N_Params.enableInt      =   false;
    PCIeMSI_hwi_N_Params.eventId        =   17;
    PCIeMSI_hwi_N_Params.arg            =   0;
    PCIeMSI_hwi_N_Params.maskSetting    =   xdc.module("ti.sysbios.interfaces.IHwi").MaskingOption_SELF;
    Program.global.hwi_pcie_N           =   Hwi.create(12, "&pcie_isr", PCIeMSI_hwi_N_Params);

    i.e. ISR is bound directly to HWI. Also event 17 is CorePack primary event. So I think if we look at Fig. 9-9 in data manual,

    interrupt selector chooses its lower input directly from input events bus. Hope this is correct and we can move further.

    Suppose, I wish single HWI to serve multiple combined events. Then instead of true ISR, like pcie_isr in the example above, I have to plug kind of dispatcher. Then if we put

    EventCombiner.eventGroupHwiNum[0] = 7;
    EventCombiner.eventGroupHwiNum[1] = 8;

    it will implicitly switch interrupt selector from above figure to its upper input, which in turn is connected to event combiner output. This way events from the input bus EVT[127:4] do not pass through interrupt selector. Instead, if event under consideration has direct connection to EVT[127:4] bus, i.e. is CorePack primary event, event combiner will trigger one of its combined outputs to rise HWI. To let multiple ISR we register event them with event combiner inputs as follows:

    EventCombiner.events[31].fxn = '&myEvent31Fxn';
    EventCombiner.events[31].arg = 31;
    EventCombiner.events[31].unmask = true;
    

    The if event 31 is enabled and, and has its handler, that will be executed as HWI ISR. I hope this correct too. Both event combiner and interrupt selector are part of CorePack's INTC. However, as I see INTC module of CSL, there is no functions to handle above tasks. It looks that right module to use is ti.sysbios.family.c66.tci66xx.CpIntc. Is it correct, that this module handles both CIC and INTC?

    In CPINTC module function of particular interest is CSL_CPINTC_mapSystemIntrToChannel. Consider diagram:

    As I understand, calling CSL_CPINTC_mapSystemIntrToChannel() makes connection between System Event to Channel, which in C6670 is equivalent to Host Interrupt. In other words we link System Event input to CIC output. My doubt is how this channel/HostInt is related with CorePack's input. Particularly, where number of 114 HostInt comes from? In TMS320C66x DSP CorePac User Guide, Table 9-2 System Event Mapping I see available events mapping, these are ranges 4-8, 10, 15-95, 99, 102-109, 112, 114-115, total 108 if I counted right. Please explain about this mapping.

    Thanks in advance.

  • Well, perhaps I found little hint. In C6670 data manual I see table Table 7-38 System Event Mapping — C66x CorePac Primary Interrupts. And these are fixed event mappings. Among them I see

    Event Number  Interrupt  Event Description
    56            CIC0_OUT0  Interrupt Controller output
    57            CIC0_OUT1  Interrupt Controller output

    So I guess, when I map to channel 0 of CIC, it arrives as primary event 56 and so on. Is it correct?

    And next, if I want system event, like EDMACC0 to route through CIC, then though Event combiner - how do I achieve that? In CIC I need to map event 36 to 0, which will arrive to CorePack as primary event 56. Next I have to link HWI with combiner output like EventCombiner.eventGroupHwiNum[1] = 8; If so, where do I plug the ISR - at

    EventCombiner.events[56].fxn    = '&edma_isr';

    or at

    CpIntc.sysInts[36].fxn      = '&edma_isr';

    Thanks in advance.