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.

C6747 EDMA complete interrupt problem

Hello:

i am trying to trigger EDMA processes by rising edges of a GPIO pin. for one trigger, it is OK. but it seems that when a second EDMA process is finished, the DSP refuses to execute the EDMA complete interrupt function.

i find that when a second rising edge is attached to the GPIO pin, the data transportion is done, but corresponding EDMACC IPR bit is still 1,and corresponding EDMATC SCANT bits is (which as far as i know should be zero once the transportion is finished). is there anything i have missed?

follewed is some related functions:

interrupt void c_int04() {// GPIO interrupt handle...trigger a new transportion
    IER &= 0xFFFFFFEF;  //disable GPIO bank2 interrupt
                           /* so that any toggling of the HF flag is disregarded until the DMA*/
     EDMA_ESR |= 0x1;    /* Starts the DMA transfer, if haven’t transferred the desired number of frames.  */
     printf("a new frame is started\n");
}

interrupt void c_int05(){  /* DMA complete Interrupt */
    printf("one frame has been transmitted\n");
    EDMA_ICR |= 0x01;
    EDMA_SECR |=0x01;
    EMCR |= 0x01;
    set_EDMA();
   IER |= 0x01<<4;    /* enable GPIO bank2 interrupt, to detect the next rising edge of HF */
   done = 0;
   src[0] = 3;}

void set_EDMA(){
 /* Step 1: EDMA initialization */
 SAOPT0 = 0x00100071;             // lowest priority
 QWMTHRA =(16<<8u)|(16 & 0xFF);   // when event number equals in queue or exceeds it, errs are generated
 EMCR =  0xFFFFFFFF;              // clear previous missed events
 CCERRCLR = 0xFFFFFFFF;           // Clear previous errs
    EDMA_DARE1 |=0x01;
 /* Step 2: Programming DMA Channel (and Param set) */
 DMAQNUM0=0x0;                    // Event is queued in queue 0
 CH0_OPT = 0x00100000;            
 CH0_SRC = (Uint32)&src;
 CH0_A_B_CNT = ((1 << 16u) | (0x000F & 0xFFFFu));    /* ACNT = 128, BCNT = 1 */
 CH0_DST = (Uint32)&dst;
 CH0_SRC_DST_BIDX = (0 << 16u) | (0 & 0xFFFFu);    /* SRC_BIDX = 0, DST_BIDX = 128 */
 CH0_LINK_BCNTRLD = ((0 & 0xFFFFu) << 0u) | 0xFFFFu;    /* LINK = 0xFFFF, BCNTRLD = 1 */
 CH0_SRC_DST_CIDX = 0;
 CH0_CCNT = 1;
 /* Step 3: Triggering the Transfer and Waiting for Transfer Completion */
    EDMA_ISER |= 0x01; //enable channel0 complete interrupt
    //EDMA_ICR = 0x01;
}

  • Hi

    I recommend that you look at some rCSL example for GPIO and DSP Interrupt to make sure you are not missing something in your GPIO/ INTC setup

    You can find those in the PSP package

    http://software-dl.ti.com/dsps/dsps_public_sw/psp/BIOSPSP/index.html

    Additionally I don't understand some of the lines of in your code, please clarify what registers are being written to

     SAOPT0 = 0x00100071;             // lowest priority

     EDMA_ISER |= 0x01; //enable channel0 complete interrupt

    Why are you using TC registers to look at transfer completion.

    Please also note that in your EDMA ISR, you will still need to explicitly clear the IPR register via write to ICR , I don't see that in your ISR ( see it commented out in the bottom of the code).

    Details on this can be found in the EDMA user guide (section 2.9.2)

    http://focus.ti.com/lit/ug/sprufl1c/sprufl1c.pdf

    Regards

    Mukul

  • HI:

    thanks for the reply.

    1.SAOPT0 = 0x00100071;  SAOPT is Source Active Options Register .set TCINTEN bit to enable Transfer complete interrupt ; set Priority number to 7; set SAM bit to let EDMA works in Constant addressing (CONST) mode

    2. actually EDMA_ISER is a mis-spelling, sorry for that ,it is EDMA_IESR register..

    3. Why are you using TC registers to look at transfer completion.

    because i find in page 131in SPRUFL1C which says that " ACINT--A dimension count. Number of bytes to be transferred in first dimension. It is decremented after each
    Read command appropriately. Represents the amount of data remaining to be Read. It should be 0 when transfer request (TR) is complete".so i check that. In my situation i think the data transportion is well done because data in destination address is just what i want to see,  IPR is still set but EDMA complete interrupt handle is not executed.

    4.Please also note that in your EDMA ISR, you will still need to explicitly clear the IPR register via write to ICR , I don't see that in your ISR ( see it commented out in the bottom of the code).

    i think i have cleared it in my EDMA complete interrupt handle during the first EDMA completion:

    interrupt void c_int05(){  /* DMA complete Interrupt */
        printf("one frame has been transmitted\n");
        EDMA_ICR |= 0x01;
        EDMA_SECR |=0x01;
        EMCR |= 0x01;
        set_EDMA();
        IER |= 0x01<<4;    /* enable GPIO bank2 interrupt, to detect the next rising edge of HF */
       done = 0;
       src[0] = 3;
    }[

    5. I am now getting started without DSP/BIOS because of lacking of time , is there any example on the EDMA tranportion on C67x?

  • Thanks for the clarifications

    FENG SUN said:
    1.SAOPT0 = 0x00100071;  SAOPT is Source Active Options Register .set TCINTEN bit to enable Transfer complete interrupt ; set Priority number to 7; set SAM bit to let EDMA works in Constant addressing (CONST) mode

    FENG SUN said:
    because i find in page 131in SPRUFL1C which says that " ACINT--A dimension count. Number of bytes to be transferred in first dimension. It is decremented after each

    It is not recommended to program the EDMA3 TC registers to do a transfer. You should use the CC to program the transfer context, using the PARAM associated with the GPIO channel that you are trying to use. Please also not that it is not recommended to use CONST mode for any EDMA transfers on these devices, recommend sticking to  INCR mode only.

    For EDMA , the recommendation is to use the EDMA3 LLD driver, there are no rCSL examples for EDMA.
    You can see if the following device agnostic wiki article helps you to get started

    http://processors.wiki.ti.com/index.php/Programming_EDMA_without_EDMA3LLD_package

    This shows a manually triggered transfer, but you should be build on this to convert it to a GPIO event based transfer. It would be good to look at the INTC and GPIO examples in the package I pointed (It has some non BIOS examples also).

    Regards

    Mukul

     

     

  • thanks for that

    today i rerote my code as

     while (frm_number>0){
       while ((EDMA_IPR &= 0x01)==0);
          set_EDMA();
       printf("one frame has been transmitted:%d\n",frm_number);
          IER |= 0x01<<4;
       src[0]++;
          frm_number--;  
     }

    in which i poll IPR[0] untill it is 1. now it works well. but from my point of view (maybe i am wrong), it is not a good way to poll IPR to check wether the EDMA has finished a data movement, because i think the CPU wastes to much usage on that. Maybe i will still try the interrupt way, although i really dont understand why the ISR(c_int_05) refuses to work for a second time, as far as every register related seems OK. Hope i can find out who is the bad boy soon.