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.

C6748 EDMA & TCC Interrupt problem

Hi.

I got a problem about McBSP & EDMA debugging in silicon real-time mode in ccs.

I want to see infinite EDMA loop (same Param2) and ISR function call using TCC & Event Trigger (by EDMA Int8)

But It works just one time (ISR function called only one time).

Please let me know how can I solve it.

here is my EDMA & ISR function code.

// ======================================================

// EDMA function

// ======================================================

void EDMA_Initial(void){

EMCR = 0xFFFFFFFF; // Event missed clear register
QEMCR = 0xFFFFFFFF; // QDMA Event missed clear register
CCERRCLR = 0xFFFFFFFF; // Error clear register
DRAE1 = 0x00000004; // Enable DMA Channel to Shadow region
DMAQNUM0 |= (0 << 8); // E2 in queued on Q0
CCSTAT = 0x00000000; // Status register clear

ECR1 = 0xFFFFFFFF; // Event clear register
EECR1 = 0xFFFFFFFF; // Event enable clear register
SECR1 = 0xFFFFFFFF; // Secondary event clear register

USTIMER_delay(5);

OPT2 = (0 << 23 | // ITCCHEN Intermediate transfer completion chaining enable
0 << 22 | // TCCHEN Transfer complete chaining is enabled
0 << 21 | // ITCINTEN Intermediate transfer completion interrupt is enable
1 << 20 | // TCINTEN Transfer complete interrupt enable
2 << 12 | // TCC Transfer complete code (channel 2)
0 << 11 | // TCCMODE Normal completion
0 << 2 ); // SYNCDIM A-synchronized

SRC2 = 0x01D10000; // Channel source address (McBSP DRR)


A_B_CNT2 = ((range_num*scan_num) << 16 | // BCNT number of arrays in 1 frame
4 << 0 ); // ACNT bytes in array / 1st dimension

DST2 = (uint32_t)tempRX;


SRC_DST_BIDX2 = (4 << 16 | // Destination B index = same ACNT
0 << 0 ); // Source B index 

LINK_BCNTRLD2 = (0 << 16 | // B count reload
65535 << 0 ); // Link address (null)

SRC_DST_CIDX2 = (0 << 16 | // Destination C index
0 << 0 ); // Source C index

CCNT2 = (0 << 16 | // reserve
1 << 0 ); // C counter number of frames

EESR1 = 0x00000004; // channel & param 2

IESR1 = 0x00000004; // Interrupt Enable Set Register (channel 2)
}

// ======================================================

// ISR function

// ======================================================

interrupt void EDMA_ISR(void)

{

printf(" EDMA_ISR test START !!!!!! \n");

ICR1  = 0x00000004;     // Interrupt Clear Register

}

Thanks.

Woo.

  • If you look at your parameter set before/during/after the transfer you'll notice that the set is being updated as the transfer progresses.  Specifically, each time you get an event from the McBSP to transfer data the channel controller decrements BCNT in your parameter set.  Once your transfer has completed you will have a BCNT value of 0 (or maybe it's CCNT=0).  In order to keep transferring data you need to reinitialize your parameter RAM to its intial values.  The easiest way to accomplish this is through the use of "linking".  When you do the initialization you should put the same exact parameters into TWO parameter RAM entries.  That way after the transfer is completed the channel controller will take that second parameter set and copy it over the "exhausted" first set to reinitialize things.  Please read about linking in the User Guide for more details.

  • Hi Brad.

    Thanks for your advice.

    According to your help, I made two same param set and could see infinite EDMA ISR loop.

    But another problem is that EDMA data doesn't change, just shows the same data repeatedly.

    I use while(1){} in main and silicon real-time mode in CCS5,

    and ADC & McBSP, I want to see the ADC outdata changing in real time mode.

    I guess this problem related to EDMA event trigger mode.

    I didn't set ESR, ECR EDMA register (about ER), only use EECR, EESR (about EER).

    and I don't know about mapping McBSP receive event to EDMA event trigger.

    Please let me know about this problem.

     

    Thanks.

    Woo.

     

  • sung chul woo said:
    I want to see the ADC outdata changing in real time mode.

    In addition to enabling real-time mode you must also right-click on the memory window and select "continuous refresh".

  • Yes of course.

     I solved real-time mode problem, but I have another problem.

    When My ISR function has printf function and ICR set, my counter works well (increase by 1).

    But when ISR has some signal processing code additionally, my counter increase by 2

    and push Restart and Resume, my counter is not reset and increase 4..

    ex) Resume => printf cnt 1, 2 => Resume & Restart => printf cnt 3, 1, 2, 3 ...

    I have reset cnt = 0 in my main(), and ISR function has cnt++.

    I really don't understand above result.

    By any chance, do I use both TCCHEN and TCINTENT together?

    I didn't use TCCHEN now in EDMA code.

    Thanks for your help.

    Woo.

  • I found the reason about problem.

    when I use 2 Param by linking, it called ISR function twice.

    But I want to call ISR function once,

    and I want to call ISR function infinitely in real-time mode.

    How can I solve above problem?

    Do I have to use Chain (TCCHEN) & Interrupt mode (TCINTEN) at the same time?

    (I think this is not right way)

    or can I call ISR function once using 2 Param linking?

     

    Thanks.

  • You should use linking but not chaining.  Set TCINTEN=1 and ITCINTEN=0. 

  • I set those register like my EDMA code.

    I solved this problem by using EECR & EESR register in my ISR.

    Thanks.

  • sung chul woo said:
    I solved this problem by using EECR & EESR register in my ISR.

    You shouldn't need to manipulate those registers in your ISR.  It sounds to me like you have something configured incorrectly still.  Although it is apparently working for you now, I don't believe you have correctly resolved the issue.  Please post your parameter sets and I'll have a quick look.

  •  

    //============================================================================  

    // EDMA Param2 setting  

    //============================================================================  

    OPT2 = (0 << 23  |  // ITCCHEN Intermediate transfer completion chaining enable       

    0 << 22  |  // TCCHEN Transfer complete chaining is enabled      

    0 << 21  |  // ITCINTEN Intermediate transfer completion interrupt is enable      

    1 << 20  |  // TCINTEN Transfer complete interrupt enable      

    2 << 12  |  // TCC Transfer complete code (channel 2)      

    0 << 11  |  // TCCMODE Normal completion      

    0 << 2  );  // SYNCDIM A-synchronized

     

    SRC2 = 0x01D10000; // Channel source address (McBSP DRR)

     

     A_B_CNT2 = (40000 << 16  |  // BCNT number of arrays in 1 frame                          

    4 << 0  );  // ACNT bytes in array / 1st dimension

     

     DST2 = (uint32_t)tempRX;

     

     SRC_DST_BIDX2 = (4 << 16  |  // Destination B index = same ACNT   

    0 << 0  );  // Source B index

     

     LINK_BCNTRLD2 = (0 << 16  |  // B count reload        

    16480 << 0  );  // Link address (4060 Param3)

     

     SRC_DST_CIDX2 = (0 << 16  |  // Destination C index         

     0 << 0  );  // Source C index

     

     CCNT2 = (0 << 16  |  // reserve    

    1 << 0  );  // C counter number of frames

    ============================================================================

    Param3 is same like Param2.

    I found that my CPU register IER & CSR is changed but IFR is not.

    If IFR is not set by enable, ISR function could be called? 

    And should I have to connect McBSP receive event to EDMA event trigger?

    (Infinite Loop : McBSP receive => EDMA trigger => EDMA Transfer Complete => ISR (signal processing) => McBSP receive)

    I don't know about mapping McBSP receive event to EDMA event trigger.

    Thanks.

    Woo. 

  • I guess that EDMA Interrupt works well but CPU Interrupt doesn't work.

    So ISR is called several times (ISR cnt increased 2 or 3) and IFR is not changed although I did run project only one loop.

    Here is my CPU Interrupt register code.

     

    #define EVTSET0  *((volatile unsigned int *)(0x01800020))

    #define INTMUX2  *((volatile unsigned int *)(0x01800108))

    extern cregister volatile unsigned int CSR;

    extern cregister volatile unsigned int IER;

    extern cregister volatile unsigned int ICR;

    extern cregister volatile unsigned int ISTP;

    extern cregister volatile unsigned int IFR;

     

    void CPU_Int_Init(void) {   

    //============================================================================   

    // CPU interrupt controller   

    //============================================================================

    EVTSET0 |= (1 << 8);  // EDMA TCC EVT 8 set   

    INTMUX2 |= (8 << 0);  // EDMA EVT 8 => INT8 => IFR

    //============================================================================   

    // CPU interrupt enable (IER, GIE.CSR)   

    //============================================================================

    ISTP = (unsigned int)(intcVectorTable);   

    ICR  = (1 << 8);    // EVT 8 clear   

    IER |= (1 << 1);   // NMI enable   

    IER |= (1 << 8);   // EVT 8 enable   

    CSR |= (1 << 0);   // GIE enable

    }

     

    Thanks.

    Woo.

  • I solve this problem by using CPU ISR register in my main, I didn't set it...

    but It works as infinite loop although I didn't use that.

    Is it caused by 2 param link?

    It called ISR function twice when I did use 1 param (use null link),

    and called ISR function infinitly when I did use 2 param link (not use infinite loop).

    Is that right result?

     

    Thanks.

    Woo. 

     

     

  • sung chul woo said:

    EVTSET0 |= (1 << 8);  // EDMA TCC EVT 8 set   

    INTMUX2 |= (8 << 0);  // EDMA EVT 8 => INT8 => IFR

    The EVTSETn registers are related to the event combiner.  Since you are directly mapping the interrupt to the CPU (i.e. to INT8) there is no need to touch EVTSETn.  The only reason to use those registers is if you have more than 12 total interrupts in your system then you need to use the event combiner to have a shared interrupt.

     

    sung chul woo said:

    I guess that EDMA Interrupt works well but CPU Interrupt doesn't work.

    So ISR is called several times (ISR cnt increased 2 or 3) and IFR is not changed although I did run project only one loop.

    Maybe I misunderstood what you're trying to do, but the setup you have with the two parameter sets and linking will give you infinite interrupts.  Once the original set of transfers is completed the EDMA CC generates an interrupt and copies the linked parameter set over the now depleted original parameter set.  In this way you can run forever without any CPU intervention to reconfigure the EDMA.  It's more typical to have ping pong buffers (aka double-buffered I/O).  In that case you would actually use 3 parameter sets: 1 for the "active" set plus 2 reloads (i.e. one for "ping" and one for "pong").

    Do you have code somewhere that is configuring the interrupt vector table such that it correctly jumps to your EDMA ISR?  I assume so since it sounds like you are getting interrupts.

     

    sung chul woo said:
    So ISR is called several times (ISR cnt increased 2 or 3) and IFR is not changed although I did run project only one loop.

    Normally you don't "see" IFR change because pretty much the instant it gets set the CPU takes the interrupt and so it gets automatically cleared by the hardware again.

  • Thanks for your answer.

    Please check below my post.

     

    I solve this problem by using CPU ISR register in my main, I didn't set it...

    but It works as infinite loop although I didn't use that (for(;;) or while(1)).

    Is it caused by 2 param link?

    It called ISR function twice when I use 1 param (use null link),

    and called ISR function infinitly when I use 2 param link (not use infinite loop).

    I don't know why it works like that.

    Is that right result?