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 Completion Interrupt

Hi

I have a Question. I want to have configured the EDMA3 multiple transfer complete interrupt on C6747. I already set single interrupt.But I can't multiple. I read SPRUH91A (16.2.9.1 Transfer Completion Interrupts)and programmed with ACNT = 3, BCNT = 4, CCNT = 5, and TCC = 0, TCINTEN = 1, ITCINTEN = 1. but Multiple interrupt did not occer. I do not know why. I shold change Channel??

Can you help me ?

  • Hiroyasu,

    Which DMA or QDMA channel do you use?

    How do you trigger it multiple times?

    Does all of the data get transferred correctly, but the only thing missing is the interrupt?

    When you get the interrupt, does this mean you are able to tell that you enter the Interrupt Service Routine?

    Do you clear the IPR bit after each interrupt has occurred?

    Regards,
    RandyP

  • Hi, RandyP

    Thank you for reply

    >Which DMA or QDMA channel do you use?

    I used DMA channel.

    >How do you trigger it multiple times?

    I used ESR trigger.It mean just one trigger.

    I want to use completion Interrupts after every ACNT and BCNT.

    >Does all of the data get transferred correctly, but the only thing missing is the interrupt?

    Yeah, Data transferred were completes. but interruped  was occer just one time.

    >When you get the interrupt, does this mean you are able to tell that you enter the Interrupt Service Routine?

    I can enter  the Interrupt Service Routine just one time.

    >Do you clear the IPR bit after each interrupt has occurred?

    Yes, I cleared IPR in Interrupt Service Routine.

    I explaine my code.

    extern void EDMA_2D(void){

    //EDMA PaRAM SET

    Pa_EDMARegs_0 -> OPT =  (EDMA3_ADDRMODE_INCR | EDMA3_SYNC_AB        | EDMA3_TCCMODE | EDMA3_TCINTEN | EDMA3_ITCINTEN);

    Pa_EDMARegs_0 -> OPT |=  EDMA_TCC ;

    Pa_EDMARegs_0 -> SRC =  0xC0000000;      //Start Address 

    Pa_EDMARegs_0 -> DST =  0xC1000000;      //DST Address 

    Pa_EDMARegs_0 -> A_B_CNT = 0x01E00280;     //640byte, 480frame 

    Pa_EDMARegs_0 -> SRC_DST_BIDX = 0x02800280;

    IER = 0x0;

    Ch_REGS_0 -> IESR = 0x1;        //Immediate interrupt Enable

    *(unsigned int *)0x01800104 = 0x0B0A0908;    //INTMUX1

    *(unsigned int *)0x01800108 = 0x0F0E0D0C;    //INTMUX2 

    *(unsigned int *)0x0180010C = 0x15141312;    //INTMUX3

    /* set ISTP to point to the vector table address                            */

    ISTP = (unsigned int)intcVectorTable;

    /* clear all interrupts, expect bits 4                                      */

    ICR = 0xFFF7;

    /* enable the bits for non maskable interrupt and CPUINT4                   */ 

    IER |= 0x12;

    /* enable interrupts, set GIE bit                                           */  _

    enable_interrupts();

    *(unsigned int *)0x01C00348 = 0x1;      //DRAE1 set

    Ch_REGS_0 -> ESR = 0x1;         //Trigger

    while(1);

    }

    interrupt void EDMA_2D_ISR(void){

    Flag_CNT = Flag_CNT + 1; 

    Ch_REGS_0 -> ICR = 0x1 ;

    /* enable interrupts, set GIE bit                                           */

    _enable_interrupts();

    }

    Best regards

    Hiroyasu

  • Hiroyasu,

    From the code that you have shown above, you only trigger DMA Channel 0 one time, just before the while(1) loop. Each time you trigger it there will be one transfer of ACNT*BCNT bytes of data, and CCNT will decrement by 1. You will have to trigger DMA Channel 0 again to make it transfer more data. You should get an interrupt after each ACNT*BCNT transfer which will be after each write to ESR bit 0.

    I do have a few comments on your code, below.

    Hiroyasu said:

    Pa_EDMARegs_0 -> A_B_CNT = 0x01E00280;     //640byte, 480frame 

    I do not see a value for CCNT. One 640x480 frame will be transferred each time you trigger channel 0 by writing 0x1 to ESR. And each transfer will generate an interrupt when that frame completes.

    Hiroyasu said:

    /* clear all interrupts, expect bits 4                                      */

    ICR = 0xFFF7;

    /* enable the bits for non maskable interrupt and CPUINT4                   */ 

    IER |= 0x12;

    Your comment says to preserve bit 4 but the value written to ICR preserves bit 3. Also, there is no need to enable NMI in bit 1 of IER.

    Hiroyasu said:

    Ch_REGS_0 -> ESR = 0x1;         //Trigger

    while(1);

    The fact that there is only one place where you write to ESR may be why you only get one interrupt. But you said that all the data gets transferred. Do you see several 640x480 frames of data get transferred, or only one frame of 640x480?

    Hiroyasu said:

    interrupt void EDMA_2D_ISR(void){

    Flag_CNT = Flag_CNT + 1; 

    Ch_REGS_0 -> ICR = 0x1 ;

    /* enable interrupts, set GIE bit                                           */

    _enable_interrupts();

    }

    The _enable_interrupts(); line should not be there. The 'interrupt' keyword will result in the GIE bit being restored when the ISR returns.

    As a test, after the write to ICR in your ISR, add a line after that write to ICR that will write to ESR to trigger another transfer. This is not a full solution, but just a test. It will probably result in an error at the end but it should at least get more transfers to occur.

    Regards,
    RandyP