cancel
Showing results for 
Search instead for 
Did you mean: 

ADC with DMA does not trigger new sample

Posted on October 15, 2012 at 14:13

Hi all, 

I use STM32L discovery with sample codes from standard peripheral library.

I need to measure several channels continuously but the original example does not work either.

After initialization only one sample is measured and no other conversion is trigerred automatically.

Does anyone has a clue what I could be doing wrong? This is my code.

ADC_InitTypeDef ADC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

__IO uint16_t ADC_ConvertedValue[3];

void ADC_DMA_Config(void)

{

  /*------------------------ DMA1 configuration ------------------------------*/

  /* Enable DMA1 clock */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  /* DMA1 channel1 configuration */

  DMA_DeInit(DMA1_Channel1);

  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADDRESS;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = 2;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel1, &DMA_InitStructure);

  /* Enable DMA1 channel1 */

  DMA_Cmd(DMA1_Channel1, ENABLE);

  /*----------------- ADC1 configuration with DMA enabled --------------------*/

  /* Enable the HSI oscillator */

  RCC_HSICmd(ENABLE);

  /* Enable GPIOB clock */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

  /* Configure PB.12 (ADC Channel18) in analog mode */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_15;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* Check that HSI oscillator is ready */

  while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);

  /* Enable ADC1 clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  /* ADC1 configuration */

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfConversion = 2;

  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel18 configuration */

  ADC_RegularChannelConfig(ADC1, ADC_Channel_21, 1, ADC_SampleTime_4Cycles);

  ADC_RegularChannelConfig(ADC1, ADC_Channel_18, 2, ADC_SampleTime_4Cycles);

  /* Enable the request after last transfer for DMA Circular mode */

  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

  /* Enable ADC1 DMA */

  ADC_DMACmd(ADC1, ENABLE);

  /* Enable ADC1 */

  ADC_Cmd(ADC1, ENABLE);

  /* Wait until the ADC1 is ready */

  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET)

  {

  }

  /* Start ADC1 Software Conversion */

  ADC_SoftwareStartConv(ADC1);

}

9 REPLIES 9
raptorhal2
Lead
Posted on October 15, 2012 at 15:27

MemoryInc needs to be enabled to get the DMA to put the second converted value in the buffer second position.

Cheers, Hal

Posted on October 15, 2012 at 16:06

Thank you. it is obviously true

but unfortunatelly it does not solve the problem that only one sample is converted and next conversion is not trigerred.

raptorhal2
Lead
Posted on October 15, 2012 at 18:00

I am not very familiar with the STM32L152 library, but on other processors, strange results occurred if the following was not included in the ADC initialization:

ADC_InitStructure.ADC_ExternalTrigConv = 0;

Try that. If that is not the answer, perhaps someone else can spot something.

Cheers, Hal

Posted on October 16, 2012 at 08:36

ADC_ExternalTrigConvEdge_None is declared by define and equals to 0.

I tried also this just to be sure, but it did not help.

frankmeyer9
Associate II
Posted on October 16, 2012 at 09:03

I can't spot an obvious problem, too.

And, to admit that, have no much experience with the L51.

I would change the initialization to an EOC interrupt for the ADC, and check with the debugger if there really just one conversion happens.

I'm also lost on the internal bus structure of the L51. You might check if DMA1 is actually capable of serving the ADC. I only remember this issue from the F4, with two DMA units on different busses.

zzdz2
Associate II
Posted on October 16, 2012 at 10:33

>>MemoryInc needs to be enabled to get the DMA to put the second converted value in

>>the buffer second position.

>Thank you. it is obviously true

>but unfortunatelly it does not solve the problem that only one sample is converted and

>next conversion is not trigerred.

I guess MemoryInc disabled can cause such problem, have you really tested it?

Posted on October 17, 2012 at 10:26

Thank you all for the collaboration.

When I tried to test EOC flag in Main I increased ADC_SampleTime_4Cycles to ADC_SampleTime_384Cycles just to have time enough to get there.

And then it started to work just because of this.

96+ cycles work correctly, 48 and less do not.

My workaround is to decrease the Sample time, but I do not know the real reason.

Maybe it is time to stury Sample time in reference manual again.

to knik:

I have had tested to change MemoryInc. I tried it again and played with it. If MemoryInc is disabled it the pointer is not incremented and the value alternates. With my original problem the ADC_ConvertedValue[0] was ''frozen'' since very first measurement.

frankmeyer9
Associate II
Posted on October 17, 2012 at 11:05

When I tried to test EOC flag in Main I increased ADC_SampleTime_4Cycles to ADC_SampleTime_384Cycles just to have time enough to get there.

 

And then it started to work just because of this.

 

I never had such an effect with F10x, F0 and F4 controllers. DMA worked regardless of ADC cycle time. Could be something L51 specific issue, possibly.

raptorhal2
Lead
Posted on October 17, 2012 at 16:21

Sections 11.3.2 and 11.9 in the L151 reference manual discuss an ADC versus bus clock consideration that could be the source of the problem. You may have to set a delay between samples to achieve success.

Cheers, Hal