DSPRelated.com
Forums

Linked EDMA example?

Started by William C Bonner March 19, 2008
I've got a sequence of items that I'm trying to accomplish with a linked
EDMA sequence. I believe that linking and chaining are two completely
different things, and I'm trying to use linking, with the last item in
the linked list set to produce an EDMA completion interrupt.

I've got error handling that makes sure that the table entries are
allocated correctly, and the initial channel opens.

My setup code opens the EDMA Channel, allocates extra table entries and
then starts the first acquisition step.

The acquisition step configures the first handle, and then loops through
the table first configuring all of the table entries and then linking
them. with a last entry of all zeros.

The acquisition step is called by the interrupt service routine until
the number of acquisitions that I want have been captured, and then when
I've got that number I call the cleanup step.

If I put a breakpoint in the acquisition step, it only gets there three
times, and then is off in lala land. Am I doing something explicitly
wrong in my setup?

I am under the impression that the user ram that I've got my table
declared will not be modified unless I explicitly modify it. Is that
correct?

Can anyone point me to a linked EDMA example, preferably ending by
setting an interrupt on completion?

While what I'm doing is more involved with the interrupt setup,
essentially I'm doing the following:

// declarations
unsigned char AttMax;
unsigned char AttMinPlus12;
unsigned char AttMinPlus7;
unsigned char AttMinPlus3;
unsigned char AttMinPlus2;
unsigned char AttMinPlus1;
unsigned char AttMin;
unsigned char PS0Up;
unsigned char PS0Down;
unsigned short ADCTrash;
const Uint32 MY_DMA1 = EDMA_OPT_RMK(EDMA_OPT_PRI_HIGH,
EDMA_OPT_ESIZE_16BIT, EDMA_OPT_2DS_NO, EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_NO, EDMA_OPT_DUM_NONE, EDMA_OPT_TCINT_NO,
EDMA_OPT_TCC_DEFAULT, EDMA_OPT_LINK_YES, EDMA_OPT_FS_NO);
const Uint32 MY_DMA2 = EDMA_OPT_RMK(EDMA_OPT_PRI_HIGH,
EDMA_OPT_ESIZE_8BIT, EDMA_OPT_2DS_NO, EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_NO, EDMA_OPT_DUM_NONE, EDMA_OPT_TCINT_NO,
EDMA_OPT_TCC_DEFAULT, EDMA_OPT_LINK_YES, EDMA_OPT_FS_NO);
const Uint32 MY_DMA3 = EDMA_OPT_RMK(EDMA_OPT_PRI_HIGH,
EDMA_OPT_ESIZE_16BIT, EDMA_OPT_2DS_NO, EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_NO, EDMA_OPT_DUM_INC, EDMA_OPT_TCINT_NO,
EDMA_OPT_TCC_DEFAULT, EDMA_OPT_LINK_YES, EDMA_OPT_FS_NO);
const Uint32 MY_DMA4 = EDMA_OPT_RMK(EDMA_OPT_PRI_HIGH,
EDMA_OPT_ESIZE_16BIT, EDMA_OPT_2DS_NO, EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_NO, EDMA_OPT_DUM_NONE, EDMA_OPT_TCINT_YES,
EDMA_OPT_TCC_DEFAULT, EDMA_OPT_LINK_NO, EDMA_OPT_FS_NO);
EDMA_Config SimpleSweepSequence[] = {
// { opt, src, cnt, dst, idx, rld }
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus12), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus12
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus7), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus7
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus3), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus3
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus2), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus2
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus1), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus1
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMin), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMin
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&PS0Up), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+3), 0, 0 }, // PS0=1 makes DDS sweep up
{ MY_DMA3, EDMA_SRC_OF(ADC_DestRAM),
EDMA_CNT_OF(N_SAMPLE_+N_OFFSET_),
EDMA_DST_OF(&(RampSampleBuffer[RampSample][0])), 0, 0 }, // ADC
Data Acquire useful data
{ MY_DMA2, EDMA_SRC_OF(&PS0Down), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+3), 0, 0 }, // PS0=0 makes DDS sweep down
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus1), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus1
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus2), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus2
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus3), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus3
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus7), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus7
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMinPlus12), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMinPlus12
{ MY_DMA1, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(1),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ MY_DMA2, EDMA_SRC_OF(&AttMax), EDMA_CNT_OF(1),
EDMA_DST_OF(CPLD_BASE+2), 0, 0 }, // Attenuator AttMax
{ MY_DMA4, EDMA_SRC_OF(ADC_DestRAM), EDMA_CNT_OF(58),
EDMA_DST_OF(&ADCTrash), 0, 0 }, // ADC Data acquire data for
time keeping only
{ 0, 0, 0, 0, 0, 0 } // End of EDMA Linking
};
const int SimpleSweepSequenceCount = sizeof(SimpleSweepSequence) /
sizeof(EDMA_Config);
EDMA_Handle SimpleSweepSequenceHandles[SimpleSweepSequenceCount-1];
const int SimpleSweepSequenceHandleCount sizeof(SimpleSweepSequenceHandles) / sizeof(EDMA_Handle);

// setup
hEdma = EDMA_open(EDMA_CHA_EXTINT5,EDMA_OPEN_RESET); // EDMA sample
transfer synchronized by INT5 Input
int cnt EDMA_allocTableEx(SimpleSweepSequenceCount-1,SimpleSweepSequenceHandles);

// acquisition step
SimpleSweepSequence[13].dst EDMA_DST_OF(&(RampSampleBuffer[RampSample][0]));
EDMA_config(hEdma, &(SimpleSweepSequence[0])); // setup EDMA for
sample data transfer
for (int index = 0; index < SimpleSweepSequenceHandleCount; index++)

EDMA_config(SimpleSweepSequenceHandles[index],&(SimpleSweepSequence[index+1]));
EDMA_link(hEdma,SimpleSweepSequenceHandles[0]);
for (int index = 0; index < SimpleSweepSequenceHandleCount-1; index++)

EDMA_link(SimpleSweepSequenceHandles[index],SimpleSweepSequenceHandles[index+1]);
EDMA_intClear(0); // Clears EDMA transfer completion
interrupt pending flag
EDMA_enableChannel(hEdma); // start datatransfer

// cleanup
EDMA_freeTableEx(SimpleSweepSequenceCount-1,SimpleSweepSequenceHandles);
EDMA_disableChannel(hEdma);
EDMA_close(hEdma); // EDMA sample transfer synchronized by INT5 Input
hEdma = (EDMA_Handle) INV;