DSPRelated.com
Forums

DSK6711 + DSP STAR ADDA - problem with EDMA transfer in BIOS

Started by jednoucelovy March 15, 2008
Hi,
I use EDMA to transfer samples from two channel 12-bit A/D converter
(DSP STAR ADDA module) through EMIF into 2 buffers in internal SRAM.
EDMA is triggered by EXT_INT7 and moves two 16-bit samples on each
event. Buffers are switched after completing a block of 2*2560
samples using linked PARAM presets.

This program runs fine if NOT using BIOS. When I use the same EDMA
presets in BIOS-equipped program, data in buffers are strangely
corrupted in random fashion - they do even exceed 12-bit range. I use
graph tool in CC Studio to see the memory contents - when i
hit "Refresh", it sometimes shows correct data throughout whole
buffers and sometimes random data throughout whole buffers. I tried
sending a few samples using LOG_printf with similar results.

If i read those data through EXT_INT7 interrupt instead of EDMA, they
are always OK.

I have a another very similar program, which transfers data in the
opposite direction - from SRAM to the D/A through EMIF using EDMA and
this one works perfectly.

I am sure this is not a CACHE coherency issue. And I have a huge
stack of 0x800 words so all typical sources of randomness seem to be
eliminated...

This is really confusing me.

Thanks for any ideas.
Petr
Hello Petr,

In case you are still fighting this problem, I have included a few items
below.

On 3/15/08, jednoucelovy wrote:

> Hi,
> I use EDMA to transfer samples from two channel 12-bit A/D converter
> (DSP STAR ADDA module) through EMIF into 2 buffers in internal SRAM.
> EDMA is triggered by EXT_INT7 and moves two 16-bit samples on each
> event. Buffers are switched after completing a block of 2*2560
> samples using linked PARAM presets.
>
> This program runs fine if NOT using BIOS. When I use the same EDMA
> presets in BIOS-equipped program, data in buffers are strangely
> corrupted in random fashion - they do even exceed 12-bit range. I use
> graph tool in CC Studio to see the memory contents - when i
> hit "Refresh", it sometimes shows correct data throughout whole
> buffers and sometimes random data throughout whole buffers. I tried
> sending a few samples using LOG_printf with similar results.
>

Do both buffers get 'trashed'??
Once a buffer is 'trashed', does it ever clear up??
I assume that the BIOS is not using EXT_INT7 for anything else.
Are you allocating your buffer using BIOS??
You could still have a pointer problem even if your program 'works' using
interrupts.
Have you tried EDMA sans BIOS??

mikedunn

> If i read those data through EXT_INT7 interrupt instead of EDMA, they
> are always OK.
>
> I have a another very similar program, which transfers data in the
> opposite direction - from SRAM to the D/A through EMIF using EDMA and
> this one works perfectly.
>
> I am sure this is not a CACHE coherency issue. And I have a huge
> stack of 0x800 words so all typical sources of randomness seem to be
> eliminated...
>
> This is really confusing me.
>
> Thanks for any ideas.
> Petr
>

--
www.dsprelated.com/blogs-1/nf/Mike_Dunn.php
Thanks for your reply, mikedunn. My pesimistic answers:

Do both buffers get 'trashed'?? - Yes, each time i take a 'snapshot' of both buffers, none, one or both of them are trashed in totally random order.

Once a buffer is 'trashed', does it ever clear up?? - Yes, randomly. Interesting is, that it either destroys the whole buffer or it leaves it wholly untouched.

I assume that the BIOS is not using EXT_INT7 for anything else. - Correct.

Are you allocating your buffer using BIOS?? - No, they are globally declared arrays:
#pragma DATA_SECTION(inbuf1, ".internal");
#pragma DATA_ALIGN(inbuf1, 128);
unsigned short inbuf1[2560*2];
#pragma DATA_SECTION(inbuf2, ".internal");
#pragma DATA_ALIGN(inbuf2, 128);
unsigned short inbuf2[2560*2];

You could still have a pointer problem even if your program 'works' using
interrupts. - I can never be sure, but I really think that it is making troubles only with EDMA. And actually, there are no pointers used yet.

Have you tried EDMA sans BIOS?? - If "sans" means without, then the answer is yes. I performed this experiment: I wrote the whole program without BIOS (works OK, included below). Then I only added the bios configuration and changed L2 to have allocable SRAM. This was enough to introduce that misbehaviour - no interrups, no other bios structures used.

Can the BIOS itself be wrong?? (stupid question, huh)

If anybody is interested in the actual program, here it goes (without several uninteresting headers and CMD file):
#define PRI (2<<29) // 2:Low priority
#define ESIZE (1<<27) // 1:16bit
#define DS2 (0<<26) // 0:1-Dimensional source
#define SUM (0<<24) // 0:no update in source address (FIFO)
#define DD2 (1<<23) // 1:2-Dimensional destination
#define DUM (1<<21) // 1:increment dest. addr.
#define TCINT (0<<20) // 0:disable interrupt
#define TCC (0<<16) // 4 bit code - nothing
#define LINK (1<<1) // 1:enable linking
#define FS (0<<0) // array synchronized mode
#define OptionField (PRI|ESIZE|DS2|SUM|DD2|DUM|TCINT|TCC|LINK|FS)

#define N 1024 //No. of samples/channel-now only 1024 for graph view
#define CH 2 //two channels

#pragma DATA_SECTION(inbuf1, ".internal"); /* set-up in BIOS conf. tool +
external CMD file */
#pragma DATA_ALIGN(inbuf1, 128);
unsigned short inbuf1[2560*2]; //first buffer
#pragma DATA_SECTION(inbuf2, ".internal");
#pragma DATA_ALIGN(inbuf2, 128);
unsigned short inbuf2[2560*2]; //second buffer

int *Event,*EventLink,*EventLink2; //pointers to EDMA PARAM presets

void main()
{
CE2_SCR = 0x31f3c723; // CE2 : 32 bit async. memory space-this is RIGHT
ad_init(CH,5000); /* this initializes A/D for 2 channels,
5000 sps/ch and sets timer TM0 to serve
as a clock source providing external output.
BIOS uses TM1 as a system clock set to 1000
microseconds. CPU runs at 150 MHz.*/

EDMA_EER = 0;

//channel 7 PARAM entry pointer:
Event = (int *)(0x01a00000 + 24 * EXT_INT7);
//first PARAM link entry pointer:
EventLink = (int *)(0x01a00180 + 24 * EXT_INT7);
//second PARAM link entry pointer:
EventLink2 = (int *)(0x01a00180 + 24 * EXT_INT7-24);

Event[PaRAM_OPT] = OptionField;
Event[PaRAM_SRC] = (int)ADCS; //AD is on EMIF CE2: (short *)0xA0000000
Event[PaRAM_CNT] = ((N-1)<<16) | CH;
Event[PaRAM_DST] = (int)inbuf1; //destination
Event[PaRAM_IDX] = (2*CH<<16)|(2);
Event[PaRAM_REL] = (int)EventLink & 0x0ffff;

EventLink[PaRAM_OPT] = OptionField;
EventLink[PaRAM_SRC] = (int)ADCS;
EventLink[PaRAM_CNT] = ((N-1)<<16) | CH;
EventLink[PaRAM_DST] = (int)inbuf2;
EventLink[PaRAM_IDX] = (2*CH<<16)|(2);
EventLink[PaRAM_REL] = (int)EventLink2 & 0x0ffff;

EventLink2[PaRAM_OPT] = OptionField;
EventLink2[PaRAM_SRC] = (int)ADCS;
EventLink2[PaRAM_CNT] = ((N-1)<<16) | CH;
EventLink2[PaRAM_DST] = (int)inbuf1;
EventLink2[PaRAM_IDX] = (2*CH<<16)|(2);
EventLink2[PaRAM_REL] = (int)EventLink & 0x0ffff;

EDMA_EER = (1< }

Thats all of it. If I put a BIOS configuration (with altered L2 to serve as data SRAM) to this stupidly simple program, miracles happen.

Petr
Oh, that last line should be

EDMA_EER = (1< }

Petr
I dont get it. I wrote it well, but this forum keeps screwing it. You see, there is supposed to be external_interrupt_seven being attached as an triggering event to that EDMA, uffff.
Petr
Petr,

On 3/18/08, j...@centrum.cz wrote:
>
> Thanks for your reply, mikedunn. My pesimistic answers:
>
> Do both buffers get 'trashed'?? - Yes, each time i take a 'snapshot' of
> both buffers, none, one or both of them are trashed in totally random order.
>
> Once a buffer is 'trashed', does it ever clear up?? - Yes, randomly.
> Interesting is, that it either destroys the whole buffer or it leaves it
> wholly untouched.
>
> I assume that the BIOS is not using EXT_INT7 for anything else. - Correct.
>
> Are you allocating your buffer using BIOS?? - No, they are globally
> declared arrays:
> #pragma DATA_SECTION(inbuf1, ".internal");
> #pragma DATA_ALIGN(inbuf1, 128);
> unsigned short inbuf1[2560*2];
> #pragma DATA_SECTION(inbuf2, ".internal");
> #pragma DATA_ALIGN(inbuf2, 128);
> unsigned short inbuf2[2560*2];
>
> You could still have a pointer problem even if your program 'works' using
> interrupts. - I can never be sure, but I really think that it is making
> troubles only with EDMA. And actually, there are no pointers used yet.
>
> Have you tried EDMA sans BIOS?? - If "sans" means without, then the answer
> is yes. I performed this experiment: I wrote the whole program without BIOS
> (works OK, included below). Then I only added the bios configuration and
> changed L2 to have allocable SRAM. This was enough to introduce that
> misbehaviour - no interrups, no other bios structures used.
>
> Can the BIOS itself be wrong?? (stupid question, huh)
>

Probably not in this case. Take a look in the 'examples' directory of CCS.
I'm not sure which DSP that you have - but there are several EDMA/BIOS
examples there.

mikedunn

If anybody is interested in the actual program, here it goes (without
> several uninteresting headers and CMD file):
>
> #define PRI (2<<29) // 2:Low priority
> #define ESIZE (1<<27) // 1:16bit
> #define DS2 (0<<26) // 0:1-Dimensional source
> #define SUM (0<<24) // 0:no update in source address (FIFO)
> #define DD2 (1<<23) // 1:2-Dimensional destination
> #define DUM (1<<21) // 1:increment dest. addr.
> #define TCINT (0<<20) // 0:disable interrupt
> #define TCC (0<<16) // 4 bit code - nothing
> #define LINK (1<<1) // 1:enable linking
> #define FS (0<<0) // array synchronized mode
> #define OptionField (PRI|ESIZE|DS2|SUM|DD2|DUM|TCINT|TCC|LINK|FS)
>
> #define N 1024 //No. of samples/channel-now only 1024 for graph view
> #define CH 2 //two channels
>
> #pragma DATA_SECTION(inbuf1, ".internal"); /* set-up in BIOS conf. tool +
> external CMD file */
> #pragma DATA_ALIGN(inbuf1, 128);
> unsigned short inbuf1[2560*2]; //first buffer
> #pragma DATA_SECTION(inbuf2, ".internal");
> #pragma DATA_ALIGN(inbuf2, 128);
> unsigned short inbuf2[2560*2]; //second buffer
>
> int *Event,*EventLink,*EventLink2; //pointers to EDMA PARAM presets
>
> void main()
> {
> CE2_SCR = 0x31f3c723; // CE2 : 32 bit async. memory space-this is RIGHT
> ad_init(CH,5000); /* this initializes A/D for 2 channels,
> 5000 sps/ch and sets timer TM0 to serve
> as a clock source providing external output.
> BIOS uses TM1 as a system clock set to 1000
> microseconds. CPU runs at 150 MHz.*/
>
> EDMA_EER = 0;
>
> //channel 7 PARAM entry pointer:
> Event = (int *)(0x01a00000 + 24 * EXT_INT7);
> //first PARAM link entry pointer:
> EventLink = (int *)(0x01a00180 + 24 * EXT_INT7);
> //second PARAM link entry pointer:
> EventLink2 = (int *)(0x01a00180 + 24 * EXT_INT7-24);
>
> Event[PaRAM_OPT] = OptionField;
> Event[PaRAM_SRC] = (int)ADCS; //AD is on EMIF CE2: (short *)0xA0000000
> Event[PaRAM_CNT] = ((N-1)<<16) | CH;
> Event[PaRAM_DST] = (int)inbuf1; //destination
> Event[PaRAM_IDX] = (2*CH<<16)|(2);
> Event[PaRAM_REL] = (int)EventLink & 0x0ffff;
>
> EventLink[PaRAM_OPT] = OptionField;
> EventLink[PaRAM_SRC] = (int)ADCS;
> EventLink[PaRAM_CNT] = ((N-1)<<16) | CH;
> EventLink[PaRAM_DST] = (int)inbuf2;
> EventLink[PaRAM_IDX] = (2*CH<<16)|(2);
> EventLink[PaRAM_REL] = (int)EventLink2 & 0x0ffff;
>
> EventLink2[PaRAM_OPT] = OptionField;
> EventLink2[PaRAM_SRC] = (int)ADCS;
> EventLink2[PaRAM_CNT] = ((N-1)<<16) | CH;
> EventLink2[PaRAM_DST] = (int)inbuf1;
> EventLink2[PaRAM_IDX] = (2*CH<<16)|(2);
> EventLink2[PaRAM_REL] = (int)EventLink & 0x0ffff;
>
> EDMA_EER = (1< > }
>
> Thats all of it. If I put a BIOS configuration (with altered L2 to serve
> as data SRAM) to this stupidly simple program, miracles happen.
>
> Petr

--
www.dsprelated.com/blogs-1/nf/Mike_Dunn.php