LPC55S36 issue configuring ADC with DMA

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

LPC55S36 issue configuring ADC with DMA

3,490 次查看
EnBono
Contributor I

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:

  • added the define of a constant value named ADC_READS which represents how many channels of the ADC are read. For simplicity, i read channels from 0 to ADC_READS - 1 only side A. For example, defining  ADC_READS 3, only ADC0_CH0A, ADC0_CH1A and ADC0_CH2A are read.
  • changed the dimension of the destination array g_AdcConvResult, from one element to ADC_READS elements.
  • changed the transfer configuration variable, defining the destination increment as kDMA_AddressInterleave1xWidth (every transfer goes to one element of the destination array), and the total bytes of the transfer as sizeof(g_AdcConvResult).
  • set the fifo0 watermark level in the adc configuration: lpadcConfigStruct.FIFO0Watermark = ADC_READS - 1;
  • added multiple ADC channel reading. As i mentioned before, for simplicity i read the first ADC_READS - 1 ADC channels, so i can configure the conversion commands with a for loop.

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

标签 (2)
0 项奖励
回复
5 回复数

2,959 次查看
Martifly
Contributor I

Hi! 
Did you solve your problem? I'm currently facing with exactly the same issue using the LPC55S06 mcu and the lpadc_dma example

 

Martina

0 项奖励
回复

2,947 次查看
EnBono
Contributor I

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

0 项奖励
回复

2,939 次查看
Martifly
Contributor I

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

0 项奖励
回复

3,475 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport
Hi, It appears that the ADC configuration is incorrect. If you want to sample 3 ADC channel for each triggering(either software or hardware), you can use the command chain like: /* 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 = 0; // Rong:0 means last channel LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 3, &g_LpadcCommandConfigStruct); Pls have a try. BR XiangJun Rong
0 项奖励
回复

3,462 次查看
EnBono
Contributor I

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)".

0 项奖励
回复