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.

RTOS/AM5728: EDMA transfer complete interrupt not generated

Part Number: AM5728
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

Hi, 

I have trying to use the internal DSP EDMA controller to sort an array. I have validated my ParamSet and confirmed while looking at the memory with Code Composer that the operation was successful. However, the interrupt is never generated to the CPU. 

I have validated that the IER register is properly set before starting the transfer and that the IPR is asserted once the transfer is completed. 

I am using the TDA2xx sample code to initialize the DMA engine. 

Note that I am also running Linux on the A15s. 

What could cause the interrupt to not be generated on my board?

Any help would be appreciated. 

Regards, 

- David

  • David Beaulieu said:
    I have validated that the IER register is properly set before starting the transfer and that the IPR is asserted once the transfer is completed. 

    Is IPR the same thing as IFR (Interrupt Flag Register)?

    If you see a bit set to 1 in the IFR register then that means that global interrupts are disabled (CSR.GIE bit is 0).  If global interrupts were enabled and IER was set properly, you would never see the bit being set in the IFR since as soon as it gets set, the CPU services the interrupt and it gets cleared almost immediately.

    What version of TI-RTOS (or SYS/BIOS) are you using?

    Are you trying to do this from main()?  (global interrupts are not enabled in main() in SYS/BIOS).

    Do you have any Hwi_disable() calls in your code?

    Regards,

    - Rob

  • Hi Rob, 

    EDMA IPR is the "Interrupt pending Register". This is the register that is set when an interrupt condition occurs on a TCC.

    I am using SYS/BIOS version 6.45.01.29 (Processor SDK RTOS v3.01.00.06).

    I am doing the initialization from my main function but are enabling EDMA transfers from a SYS/BIOS task. I tried moving the init in the task but that didn't change the behavior. 

    I also tried calling Hwi_enable() right before my test but that didn't change anything. 

    Where is the IFR? Is that a register in the EDMA controller? I didn't see it if it is... The same for the CSR.GIE. Is this an EDMA register?

    Also, I have noticed that the demo is using the following code when enabling the interrupts:

    EventCombiner_dispatchPlug(ccXferCompInt[edma3Id][dsp_num],
        						(EventCombiner_FuncPtr)(&lisrEdma3ComplHandler0),
                            	edma3Id, (Bool)1);
        EventCombiner_enableEvent(ccXferCompInt[edma3Id][dsp_num]);
    
        /* Enable the CC Error Event Interrupt */
        EventCombiner_dispatchPlug(ccErrorInt[edma3Id],
        						(EventCombiner_FuncPtr)(&lisrEdma3CCErrHandler0),
        						edma3Id, (Bool)1);
        EventCombiner_enableEvent(ccErrorInt[edma3Id]);
    
        /* Enable the TC Error Event Interrupt, according to the number of TCs. */
        while (numTc < numEdma3Tc[edma3Id])
    	    {
            EventCombiner_dispatchPlug(tcErrorInt[edma3Id][numTc],
                                (EventCombiner_FuncPtr)(ptrEdma3TcIsrHandler[numTc]),
                                edma3Id, (Bool)1);
            EventCombiner_enableEvent(tcErrorInt[edma3Id][numTc]);
            numTc++;
        	}

    This has been taken from the sample_tda2xx_int_reg.c file when using EDMA ID 1 (the internal DSP EDMA engine). I see in the ROV that the eventCombiner is properly configured. Do I need to create a Hwi as well?

    Regards, 

    - David

  • Hi Rob,

    FYI, I have upgraded to the latest Processor SDK RTOS version (3.02.00.05). Unfortunately, the problem still persist.

    Regards,
    - David
  • David Beaulieu said:
    EDMA IPR is the "Interrupt pending Register". This is the register that is set when an interrupt condition occurs on a TCC.

    David Beaulieu said:
    Where is the IFR? Is that a register in the EDMA controller? I didn't see it if it is... The same for the CSR.GIE. Is this an EDMA register?

    We were talking different register spaces.  When you mentioned IER I was thinking of the CPU's IER (Interrupt Enable Register) which controls the CPU's interrupts.  IFR is the Interrupt Flag Register, where a bit gets set when an interrupt occurs.  CSR is the Control Status Register of the CPU, and the CSR.GIE bit (bit 0 of CSR) is the Global Interrupt Enable bit.  For an interrupt to be taken, CSR.GIE must be 1, the interrupt's bit in IER must be enabled, and the interrupt will be taken when the interrupt's bit in IFR gets set.

    In order for EDMA Transfer Completion events to interrupt the CPU, an Hwi must be created using Hwi_create() at runtime (or Hwi.create in static .cfg file).  This Hwi must be given the DSP's system event ID by setting Hwi_Params.eventId for the Hwi_create() call.

    The EventCombiner API calls that you are making in your included code will not create the Hwi, so you must do so yourself.  Take a look at the EventCombiner cdoc, or at the file <sysbios_install_dir>/packages/ti/sysbios/family/c64p/EventCombiner.xdc.  They both have an example of setting up the EventCombiner to service events.  Note the params.eventId setting, where it takes the actual event ID and divides it by 32 to get the event group to which the event belongs.  I don't know the event IDs for the EDMA, but they all probably fall within the same event group (event group 0 services events 0-31, event group 1 services events 32-63, event group 2 services events 64-95, and event group 3 services events 96-127)

    In your above code, the 1st parameter to EventCombiner_dispatchPlug() is the event ID that you wish to service.  The array identifier names end in "Int", but they are probably event IDs and shouldn't be interrupt IDs (which are always in the range 4-15).  Your Hwi_create() code will specify the actual interrupt ID that will service the combined event group, and it's up to you to pick which one (any unused one in the range 4-15 is OK).

    Also, in your above code, the EventCombiner_dispatchPlug() function is being called with the 4th parameter as 1 (TRUE).  This is the "unmask" parameter, and by passing 1, the event is unmasked (enabled) in association with plugging the dispatcher.  The EventCombiner_enableEvent() calls don't need to be done, since the event has already been enabled with the "unmask" parameter to EventCombiner_dispatchPlug() (although it doesn't hurt to do it again, it's just not necessary).

    I hope this solves your issue.

    Regards,

    - Rob

  • Hi Rob,

    I was hoping this would fix my problem but I still can't get the EDMA DSP1 interrupt event after I manually added the Hwi handler.

    The EDMA DSP1 event id are from 16 to 20 (for the transfer complete interrupts) and 27-29 for the TC error interrupts.

    It it my understanding that I do not need to use the cross bar for these events since they are direct to the CPU. Is that true?

    Regards,
    - David
  • I finally got it to work.
    I was using the Board package to initialize part of the system and that was interfering with the initialization that already took place by the Linux kernel.

    I know have interrupts that are properly generated and handled.

    Thanks for your help,
    - David
  • That's great to hear.  It didn't occur to me to think about Linux's system handling, but that makes sense.

    Thanks for letting us know.

    Regards,

    - Rob