Hello all.
I am using uDMA to get two channels of data of 1024 points each from the ADC0 sampling at 48KHz. Both channels (let's call them CHa and CHb) are sampled at the same time, so at the end of the pong buffer I have 2048 points alternated in the way:
array_of_data= CHa0-CHb0-CHa1-CHb1-.....-CHa1023-CHb1023
To do that I am initializating the ADC and DMA as:
//
// Configure and enable the uDMA controller
//
ROM_SysCtlPeripheralEnable (SYSCTL_PERIPH_UDMA);
ROM_IntEnable (INT_UDMAERR);
ROM_uDMAEnable ();
ROM_uDMAControlBaseSet (ucControlTable);
//
// Configure the ADC to capture one sample per sampling timer tick
//ROM_SysCtlPeripheralEnable (SYSCTL_PERIPH_ADC0);
ROM_SysCtlPeripheralReset (SYSCTL_PERIPH_ADC0);
ROM_ADCSequenceConfigure (ADC0_BASE, ADC_SEQUENCER, ADC_TRIGGER_TIMER, 0);ROM_ADCSequenceStepConfigure (ADC0_BASE, ADC_SEQUENCER, 0, ADC_CTL_CH1); //AIN1
ROM_ADCSequenceStepConfigure (ADC0_BASE, ADC_SEQUENCER, 1,
ADC_CTL_CH2 | ADC_CTL_IE | ADC_CTL_END); //AIN2//
// Enable the sequencer
//
ROM_ADCSequenceEnable (ADC0_BASE, ADC_SEQUENCER);
ROM_ADCIntEnable (ADC0_BASE, ADC_SEQUENCER);//
// Configure the DMA channel
//
ROM_uDMAChannelAttributeDisable (UDMA_CHANNEL_ADC2,
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY
| UDMA_ATTR_REQMASK);//DMA PING PONG
ROM_uDMAChannelControlSet (UDMA_CHANNEL_ADC2 | UDMA_PRI_SELECT,
UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_2);ROM_uDMAChannelControlSet (UDMA_CHANNEL_ADC2 | UDMA_ALT_SELECT,
UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_2);ROM_uDMAChannelTransferSet (UDMA_CHANNEL_ADC2 | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *) (ADC0_BASE + ADC_O_SSFIFO2 + (0x20 * UDMA_ARB_1)),
g_ulADCValues, NUM_SAMPLES);ROM_uDMAChannelTransferSet (UDMA_CHANNEL_ADC2 | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *) (ADC0_BASE + ADC_O_SSFIFO2 + (0x20 * UDMA_ARB_1)),
&g_ulADCValues[NUM_SAMPLES], NUM_SAMPLES);//
// Enable the DMA channel
//
uDMAChannelEnable(UDMA_CHANNEL_ADC2);
The interrupt handler for this DMA-ADC interrupt is:
ROM_ADCIntClear (ADC0_BASE, ADC_SEQUENCER);
//
// If the channel's not done capturing, we have an error
//
if (ROM_uDMAChannelIsEnabled (UDMA_CHANNEL_ADC2))
{
g_ulBadPeriphIsr2++;
return;}
//First block - PRI
ulMode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_ADC2 | UDMA_PRI_SELECT);if (ulMode == UDMA_MODE_STOP)
{
cnt_bloque1++;
estado_int_bloque1=!estado_int_bloque1;GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_3,estado_int_bloque1*0xFF);//pin AIN0
ROM_uDMAChannelTransferSet (UDMA_CHANNEL_ADC2 | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *) (ADC0_BASE + ADC_O_SSFIFO2 + (0x20 * UDMA_ARB_1)),
g_ulADCValues, NUM_SAMPLES);/**/
}//Second block - ALT
ulMode = ROM_uDMAChannelModeGet (UDMA_CHANNEL_ADC2 | UDMA_ALT_SELECT);if (ulMode == UDMA_MODE_STOP)
{cnt_bloque2++;
estado_int_bloque2=!estado_int_bloque2;GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_0,estado_int_bloque2*0xFF);//pin AIN3
ROM_uDMAChannelTransferSet (UDMA_CHANNEL_ADC2 | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *) (ADC0_BASE + ADC_O_SSFIFO2 + (0x20 * UDMA_ARB_1)),
&g_ulADCValues[NUM_SAMPLES], NUM_SAMPLES);/**/
arm_copy_q15(g_ulADCValues,Videos,2*NUM_SAMPLES);
}
ROM_uDMAChannelEnable (UDMA_CHANNEL_ADC2);
flag_data_ready=true;
The date seems to be consistent to what I am expecting, however, as you can see, I am changing the state of some GPIO pins to check in an oscilloscope the timing of the intterupt and what I find is this:
So both PRI and ALT states of the uDMA interrupt are interrupting at the same time!!!
I have checked also via JTAG and it happens the same, everytime "ulMode = ROM_uDMAChannelModeGet()" is checked I get a UDMA_MODE_STOP for both modes even in the same interrupt.
Shouldn't I get somethinbg like this and half the period?
I mean, shouldn't PRI and ALT modes interrupt alternated instead of interrupt at the same time? But the data seems to be OK, just a little glitch of some samples (about 8) at the beggining of the capture.
Regards