Hi,
I'm working on a LPCXpresso55S36 evaluation board (SCH-47745 REV A) and i'm trying to read multiple ADC channels with DMA. I'm started from lpadc dma driver example in SDK 2.10.2. I've attached the lpadc_dma.c file with the changes i made, that are basically the following:
The result is that with ADC_READS set to 1,2, or 3 the DMA transfer completes correclty, but for ADC_READS > 3 the program gets stuck in the "while (false == g_DmaTransferDoneFlag)" loop.
In this loop, I've tried to read the XFERCOUNT bits from XFERCFG21 register of DMA, and seems that with ADC_READS > 3 there are always some transfers left (example, with ADC_READS 7, there are 2 transfers left). I've also tried to read the FCOUNT bits from FCTRL0 register of ADC and there are also some elements in the fifo (example, with ADC_READS 7, there are 3 elements left in the fifo). Before the starting of DMA transfer i can see correctly a total of ADC_READS elements in the fifo.
Morevoer, i've tried to set the lpadcConfigStruct.FIFO0Watermark fixed to value 2, and in this case, due to some delays, the DMA transfer works correctly up to ADC_READS 15.
Obviously this is not a correctly solution.
How can i configure the DMA correctly also with more than 3 channels?
Best regards.
Enrico
Hi @Martifly ,
Unfortunately I couldn't find a way to solve that problem, so i decided to read the converted values directly form FIFOs. In my case the process takes a couple of microseconds, but it works correctly, unlike what happened with the use of DMA
Hi, thank you for your reply.
I'm going to use a sort of "workaround" using the lpadc + dma to read 3 channel at a time with 2 different Software triggers (since I need to read 6 adc channels every 60 microseconds).
In any case, I think I will try to contact an NXP support and I will keep you updated in case of a solution!
Martina
Hi @xiangjun_rong,
Thank you for your reply. Sorry but i can't see any difference from your configuration and mine:
for (i=0;i<ADC_READS;i++)
{
/* Set conversion CMD configuration. */
LPADC_GetDefaultConvCommandConfig(&g_LpadcCommandConfigStruct);
g_LpadcCommandConfigStruct.channelNumber = i;
g_LpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
if(i == (ADC_READS - 1))
g_LpadcCommandConfigStruct.chainedNextCommandNumber = 0;
else
g_LpadcCommandConfigStruct.chainedNextCommandNumber = i+2;
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, i+1, &g_LpadcCommandConfigStruct);
}
with this loop, using ADC_READS 3, it is the same as your configuration:
i=0 configures command 1, which reads channel 0 with chainedNextCommandNumber = 2.
i=1 configures command 2, which reads channel 1 with chainedNextCommandNumber = 3.
i=2 configures command 3, which reads channel 2 with chainedNextCommandNumber = 0.
As i said in my question, using a number of channels <= 3 the dma transfer ends correctly. Using a number of channel grater than 4 (ADC_READS 4, ADC_READS 5 ... ADC_READS 15) the dma transfer never ends. For completeness i've also tried to add a fourth channel to your version:
/* Set conversion CMD configuration. */
//First command ID index 1 which can configue ONE ADC analog channel
LPADC_GetDefaultConvCommandConfig(&g_LpadcCommandConfigStruct);
g_LpadcCommandConfigStruct.channelNumber = ADC_CHANNEL;
//it can be 0,1,2,3,4..whatever you are samplg
g_LpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
g_LpadcCommandConfigStruct.chainedNextCommandNumber = 2;
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 1, &g_LpadcCommandConfigStruct);
//second command ID index 2 which can configue another ADC analog channel
LPADC_GetDefaultConvCommandConfig(&g_LpadcCommandConfigStruct);
g_LpadcCommandConfigStruct.channelNumber = ANOTHER_ADC_CHANNEL;
//it can be 0,1,2,3,4..whatever you are sampling
g_LpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
g_LpadcCommandConfigStruct.chainedNextCommandNumber = 3;
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 2, &g_LpadcCommandConfigStruct);
//third command ID index 3 which can configue another ADC analog channel
LPADC_GetDefaultConvCommandConfig(&g_LpadcCommandConfigStruct);
g_LpadcCommandConfigStruct.channelNumber = Another_ADC_CHANNEL;// it can be 0,1,2,3,4...
g_LpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
g_LpadcCommandConfigStruct.chainedNextCommandNumber = 4;
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 3, &g_LpadcCommandConfigStruct);
//fourth command ID index 4 which can configue another ADC analog channel
LPADC_GetDefaultConvCommandConfig(&g_LpadcCommandConfigStruct);
g_LpadcCommandConfigStruct.channelNumber = Just_Another_ADC_CHANNEL;// it can be 0,1,2,3,4...
g_LpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
g_LpadcCommandConfigStruct.chainedNextCommandNumber = 0;
// Rong:0 means last channel
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 4, &g_LpadcCommandConfigStruct);
And the result is the same as mine: main loop gets stuck in "while (false == g_DmaTransferDoneFlag)".