DSPRelated.com
Forums

C6711 when should EDMA's terminate?

Started by Colin E. August 22, 2003
Dear All,

I am new to DSP's so this might seem like a very basic question ... I
am having problems with terminating simple EDMA's.

A bit of background, I am using a C6711 with Code Composer (2.20)
making use of the CSL.

I have a very simple application which performs an EDMA from a 1D
array to a single memory location (an LED bank on my development
board). This EDMA is synchronised by Timer 1, which I have set to tick
at about 1Hz for easy debugging.

The EDMA is set up as a non-frame synchronised (i.e.
element-by-element) transfer of a single frame of 5 elements as per
the following config:

EDMA_Config edmaCfg1 = {
    0x21110000,        /*  Option  */
    (Uint32) g_RampArray,        /*  Source Address - Extern Decl.Obj 
*/
    0x00000005,        /*  Transfer Counter - Numeric  */
    0x800D0000,        /*  Destination Address - Numeric   */
    0x00010001,        /*  Index register - Numeric  */
    0x000101C8         /*  Element Count Reload and Link Address  */
};

When I start this EDMA the 5 elements of my array are transferred to
the LED bank, however the EDMA does not stop ... it repeatedly
transfers the 5'th element (I can verify this by manuall setting the
destination address data, then sure enough within 1 sec it is change
back again!).

I have investigated further and found that if I set up the same
transfer as 5 single element frames, the EDMA still doesn't stop. I
can watch the frame count being decremented until it hits zero,
however the EDMA keeps repeating with a zero frame count. Surely it
shoudl stop!!!

I can manually stop the EDMA by catching the interrupt. Surely this
shouud not be necessary?

What is the usual procedure for the termination of an EDMA, does it
disable itself by writting to the Event Enable Register (EER)?

Any help would be very much appreciated!

Regards,
Colin E.
On 22 Aug 2003 03:07:11 -0700, ce@visitech.co.uk (Colin E.) wrote:

Some thoughts that may be useful for the moment...

>The EDMA is set up as a non-frame synchronised (i.e. >element-by-element) transfer of a single frame of 5 elements as per >the following config: > >EDMA_Config edmaCfg1 = { > 0x21110000, /* Option */
= 001 00 0 01 0 00 1 0001 0000 0000 0000 00 0 0 PRI = 001b High Priority ESIZE = 00b 32-bit Word 2DS = 0b Not a 2D transfer SUM = 01b Address increment depends on 2DD/2DS and FS field 2DD = 0b Not a 2D transfer DUM = 00b No address modification TCINT = 1b Transfer Complete Interrupt Enabled TCC = 0001b Transfer Complete Code rsvd = 00000000000000b LINK = 0b Linking Disabled FS = 0b FS not needed
> 0x00010001, /* Index register - Numeric */
Setting of SUM makes this redundant, try setting it to 0x00000000;
> 0x000101C8 /* Element Count Reload and Link Address */
Try setting this to 0x00000000. As a single transfer the reload count is not required, and the link address is certainly not required.
>I have investigated further and found that if I set up the same >transfer as 5 single element frames, the EDMA still doesn't stop. I >can watch the frame count being decremented until it hits zero, >however the EDMA keeps repeating with a zero frame count. Surely it >shoudl stop!!! > >I can manually stop the EDMA by catching the interrupt. Surely this >shouud not be necessary?
I believe the EDMA should complete at the end of your 5 element transfers. Can you give us some code? Best Regards John McCabe To reply by email replace 'nospam' with 'assen'
Hi John,

Thanks for replying to my post. Here is are some more details...

> > Some thoughts that may be useful for the moment... >
[..snip..]
> > 0x00010001, /* Index register - Numeric */ > > Setting of SUM makes this redundant, try setting it to 0x00000000; > > > 0x000101C8 /* Element Count Reload and Link Address */ > > Try setting this to 0x00000000. As a single transfer the reload count > is not required, and the link address is certainly not required.
I have made these changes (apart from the Link Address which teh Code Composer .cdb editor refuses to have as NULL), they do not solve the problem. As you mentioned, they do not relate to EDMA's with these dimensions. [...]
> I believe the EDMA should complete at the end of your 5 element > transfers. Can you give us some code?
I am glad you agree with me. Here is the code Code Composer generated header file ..... ------------------------------------------------ /* Do *not* directly modify this file. It was */ /* generated by the Configuration Tool; any */ /* changes risk being overwritten. */ /* INPUT LED.cdb */ /* Include Header File */ #include "LEDcfg.h" #pragma CODE_SECTION(CSL_cfgInit,".text:CSL_cfgInit") extern far unsigned int* g_pLED; extern far unsigned int g_RampArray[]; /* Config Structures */ EDMA_Config edmaCfg1 = { 0x21110000, /* Option */ (Uint32) g_RampArray, /* Source Address - Extern Decl.Obj */ 0x00000005, /* Transfer Counter - Numeric */ 0x800D0000, /* Destination Address - Numeric */ 0x00000000, /* Index register - Numeric */ 0x000001C8 /* Element Count Reload and Link Address */ }; TIMER_Config timerCfg0 = { 0x000002C0, /* Control Register (CTL) */ 0x023C3460, /* Period Register (PRD) */ 0x00000000 /* Counter Register (CNT) */ }; /* Handles */ EDMA_Handle hEdmaCha2; TIMER_Handle hTimer1; /* * ======== CSL_cfgInit() ======== */ void CSL_cfgInit() { hEdmaCha2 = EDMA_open(EDMA_CHA_TINT1, EDMA_OPEN_RESET); hTimer1 = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET); EDMA_config(hEdmaCha2, &edmaCfg1); TIMER_config(hTimer1, &timerCfg0); } ---------------------------------------------------------- My application... ---------------------------------------------------------- #include <stdio.h> #include "LEDcfg.h" interrupt void c_EDMAComplete(void); unsigned int g_RampPosition = 1; unsigned int* g_pLED = (unsigned int *)0x800d0000; unsigned int g_RampArray[16]; volatile unsigned int g_EDMAHalted = 0; void main() { unsigned int Loop; //initialise the ramp array for (Loop=0;Loop<16;Loop++) g_RampArray[Loop] = Loop; //load our EDMA's Timer, McBSP's CSL_init(); //set up the EDMA interrupt flags EDMA_intClear(1); EDMA_intEnable(1); //enable the timer one interrupt IRQ_globalEnable(); IRQ_clear(IRQ_EVT_EDMAINT); IRQ_enable(IRQ_EVT_EDMAINT); //clear the relavant bit in the event register EDMA_clearChannel(hEdmaCha2); EDMA_enableChannel(hEdmaCha2); while(g_EDMAHalted==0){} //I can verify that the EDMA is still running by trying to 'write' to the LEDs *g_pLED = 0x00; *g_pLED = 0xFF; } interrupt void c_EDMAComplete(void) { IRQ_clear(IRQ_EVT_EDMAINT); if (EDMA_intTest(1)) { EDMA_intClear(1); //if I do not disable teh EDMA here, it just keeps running! //EDMA_disableChannel(hEdmaCha2); g_EDMAHalted = 1; } } ------------------------------------------------ As you can see from my comments - I catch the end of the EDMA via the interrupt, however I have to disable the channel manually or it just keeps running. i.e. the fact that the frame count is zero is ignored, the Index Reload is applied (0 in this case) resulting in the last element being transferred ad infinitum! Thanks for you time, Colin E.
Colin,

You've set transfers to be event syncronized, and indeed EDMA
is started by each TIMER1 tick, once in 1 sec. It seem working
fine :)

Regards,

Andrew

> Dear All, > > I am new to DSP's so this might seem like a very basic question ... I > am having problems with terminating simple EDMA's. > > A bit of background, I am using a C6711 with Code Composer (2.20) > making use of the CSL. > > I have a very simple application which performs an EDMA from a 1D > array to a single memory location (an LED bank on my development > board). This EDMA is synchronised by Timer 1, which I have set to tick > at about 1Hz for easy debugging. > > The EDMA is set up as a non-frame synchronised (i.e. > element-by-element) transfer of a single frame of 5 elements as per > the following config: > > EDMA_Config edmaCfg1 = { > 0x21110000, /* Option */ > (Uint32) g_RampArray, /* Source Address - Extern Decl.Obj > */ > 0x00000005, /* Transfer Counter - Numeric */ > 0x800D0000, /* Destination Address - Numeric */ > 0x00010001, /* Index register - Numeric */ > 0x000101C8 /* Element Count Reload and Link Address */ > }; > > When I start this EDMA the 5 elements of my array are transferred to > the LED bank, however the EDMA does not stop ... it repeatedly > transfers the 5'th element (I can verify this by manuall setting the > destination address data, then sure enough within 1 sec it is change > back again!). > > I have investigated further and found that if I set up the same > transfer as 5 single element frames, the EDMA still doesn't stop. I > can watch the frame count being decremented until it hits zero, > however the EDMA keeps repeating with a zero frame count. Surely it > shoudl stop!!! > > I can manually stop the EDMA by catching the interrupt. Surely this > shouud not be necessary? > > What is the usual procedure for the termination of an EDMA, does it > disable itself by writting to the Event Enable Register (EER)? > > Any help would be very much appreciated! > > Regards, > Colin E.
On 22 Aug 2003 09:41:24 -0700, ce@visitech.co.uk (Colin E.) wrote:

>Hi John, > >Thanks for replying to my post. Here is are some more details...
no problem, sorry it was of little use, although Andrew's point seems reasonable.
>> Try setting this to 0x00000000. As a single transfer the reload count >> is not required, and the link address is certainly not required.
>I have made these changes (apart from the Link Address which teh Code >Composer .cdb editor refuses to have as NULL), they do not solve the >problem. As you mentioned, they do not relate to EDMA's with these >dimensions.
Ah - so you're allowing the DSP/BIOS to initialise the configuration? I generally set them up in my own code, based on that config, but using some of the macros available to make it obvious what I'm doing. This makes it easier for me to access the handles etc. E.g.: m_cfgEDMA.opt = EDMA_OPT_RMK(EDMA_OPT_PRI_LOW, EDMA_OPT_ESIZE_32BIT, EDMA_OPT_2DS_NO, EDMA_OPT_SUM_NONE, EDMA_OPT_2DD_NO, EDMA_OPT_DUM_INC, EDMA_OPT_TCINT_YES, EDMA_OPT_TCC_OF(5), EDMA_OPT_LINK_YES, EDMA_OPT_FS_NO); m_cfgEDMA.src = EDMA_SRC_OF(0); m_cfgEDMA.cnt = EDMA_CNT_OF(NO_SAMPLES); m_cfgEDMA.dst = EDMA_DST_OF(&arrSampleData[0]); m_cfgEDMA.idx = EDMA_IDX_OF(0); m_cfgEDMA.rld = EDMA_RLD_OF(0); Then use the CSL routines to initialise anything I haven't done yet... m_hEDMA = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); if (m_hEDMA != 0) { // Allocate handles for the two link pointers. m_hEDMALink0 = EDMA_allocTable(-1); m_hEDMALink1 = EDMA_allocTable(-1); // Sort out the source and reload fields of the initial EDMA // options. m_cfgEDMA.src = MCBSP_getRcvAddr(m_hMcBSP1); m_cfgEDMA.dst = (Uint32)&arrSampleData[0]; m_cfgEDMA.rld = (m_cfgEDMA.rld & 0xFFFF0000) | (EDMA_RLD_RMK(0, m_hEDMALink0)); EDMA_config(m_hEDMA, &m_cfgEDMA); // The second link, m_hEDMALink1, is identical to the original // config EDMA_config(m_hEDMALink1, &m_cfgEDMA); // The first link should point to the other buffer as the data // destination, and set up EDMALink1 as the next config. m_cfgEDMA.dst = (Uint32)&arrSampleData[1]; m_cfgEDMA.rld = (m_cfgEDMA.rld & 0xFFFF0000) | (EDMA_RLD_RMK(0, m_hEDMALink1)); EDMA_config(m_hEDMALink0, &m_cfgEDMA); etc....
>I am glad you agree with me.
Not so sure after Andrew's comment :-) Best Regards John McCabe To reply by email replace 'nospam' with 'assen'