cancel
Showing results for 
Search instead for 
Did you mean: 

DMA problem is using ADC1 scan mode

abbas
Associate II
Posted on December 04, 2014 at 21:30

hello guys

I am using stm32f103RET

I want to use ADC1 in scan mode

I do software start conversion in a timer interrupt and I configured DMA to save conversion values to a memory buffer

my configuration code is here

void Volumes_init(uint32_t *volume_buff) // tuning for 0.1 sec interval interruption

{

TIM_TimeBaseInitTypeDef TIM_InitStruct;

  ADC_InitTypeDef     ADC_InitStructure;

  NVIC_InitTypeDef NVIC_InitStruct;

  GPIO_InitTypeDef GPIO_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

// Configure ADC_INPUT_PIN as analog input ------------------------------------

VOLUMES_GPIO_RCC_INIT();

GPIO_StructInit( &GPIO_InitStructure );

  GPIO_InitStructure.GPIO_Pin = VOLUME1_GPIO_PIN; 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init( VOLUME1_GPIO, &GPIO_InitStructure );

  GPIO_InitStructure.GPIO_Pin = VOLUME2_GPIO_PIN; 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init( VOLUME2_GPIO, &GPIO_InitStructure );

  GPIO_InitStructure.GPIO_Pin = VOLUME3_GPIO_PIN; 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init( VOLUME3_GPIO, &GPIO_InitStructure );

  GPIO_InitStructure.GPIO_Pin = SENSORS_GND_GPIO_PIN; 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

  GPIO_Init( SENSORS_GND_GPIO, &GPIO_InitStructure );

// ADC configuration ----------------------------------------------------------

VOLUMES_ADC_RCC_INIT();

RCC_ADCCLKConfig( RCC_PCLK2_Div6 ); // 72MHz / 6 = 12MHz // must not exceed 14MHz

ADC_InitStructure.ADC_Mode =  ADC_Mode_Independent;

ADC_InitStructure.ADC_ScanConvMode = ENABLE;

ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_NbrOfChannel = 3;

ADC_RegularChannelConfig( VOLUMES_ADC, ADC_Channel_9,  1, ADC_SampleTime_1Cycles5 );

ADC_RegularChannelConfig( VOLUMES_ADC, ADC_Channel_8,  2, ADC_SampleTime_1Cycles5 );

ADC_RegularChannelConfig( VOLUMES_ADC, ADC_Channel_15, 3, ADC_SampleTime_1Cycles5 );

  ADC_DeInit( VOLUMES_ADC ); // Put everything back to power-on defaults 

ADC_Init( VOLUMES_ADC, &ADC_InitStructure );

ADC_DMACmd( VOLUMES_ADC, ENABLE );

//ADC_ITConfig (VOLUMES_ADC, ADC_IT_EOC, ENABLE);

// DMA Configuration --------------------------------------------

VOLUMES_DMA_RCC_INIT();

  DMA_DeInit( DMA1_Channel1 );

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(ADC1->DR));

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(volume_buff);

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = 3;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word;

  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 );

DMA_ITConfig( DMA1_Channel1, DMA_IT_TC, ENABLE );

NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 1;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStruct);

// TIMERS initialization ----------------------------------------

// 36MHz / 4 = 9MHz / 25 = 360KHz / 45 = 8KHz

TIMER_VOLUMES_RCC_INIT();

TIM_Cmd( TIMER_VOLUMES, DISABLE );

TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV4; 

TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_InitStruct.TIM_Period = 100; // it seems that this timer clock is 72MHz!!!

TIM_InitStruct.TIM_Prescaler = 18000;

TIM_InitStruct.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit( TIMER_VOLUMES, &TIM_InitStruct );

TIM_ITConfig( TIMER_VOLUMES, TIM_IT_Update, ENABLE );

NVIC_InitStruct.NVIC_IRQChannel = TIMER_VOLUMES_IRQn;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 0;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStruct);

// starting -----------------------------

TIM_TimeBaseInit( TIMER_VOLUMES, &TIM_InitStruct );

DMA_Cmd( VOLUMES_DMA_Channel, ENABLE );

ADC_Cmd( VOLUMES_ADC, ENABLE );

TIM_Cmd( TIMER_VOLUMES, ENABLE );

}

and timer software start conversion IRQ handler is 

void TIMER_VOLUMES_IRQHandler(void)

{

GPIO_ResetBits (SENSORS_GND_GPIO, SENSORS_GND_GPIO_PIN);

ADC_SoftwareStartConvCmd (VOLUMES_ADC, ENABLE);

TIM_ClearITPendingBit ( TIMER_VOLUMES, TIM_IT_Update);

}

and DMA IRQ handler is 

void DMA1_Channel1_IRQHandler(void)

{

GPIO_SetBits (SENSORS_GND_GPIO, SENSORS_GND_GPIO_PIN);

DMA_ClearITPendingBit (DMA1_IT_GL1);

}

the buffer is defined as

uint32_t vol[3];

and the config function is called as

Volumes_init( vol );

the problem is that, after dma transfer complete interrupt, the data in memory address is not correct and it seems that only a wrong byte is transferred in every dma requst and a byte increment is done afterward

I mean only first element of vol (vol[0]) has value of 3 bytes and its bytes seems to be nonsense

I can't understand what is wrong here

can anyone help me?

#stm32-adc-scan-mode-dma
3 REPLIES 3
Posted on December 04, 2014 at 22:44

Would probably be reading the ADC1->DR as a HalfWord

Also be aware that the Timer's Period and Prescaler are written to the device as N-1, so to divide 72 MHz down to 1 MHz you'd set 72-1 or 71 into the Prescaler, not 72
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
abbas
Associate II
Posted on December 10, 2014 at 06:54

Thanks clive

The problem was that I  was using ADC3 but with channels if ADC1-2. It is weird to see such single-byte incrementation at DMA system! anyway if I did wrong, nothing would be guaranteed to work expectedly

Also thanks for my timer mistake correction

abbas
Associate II
Posted on December 10, 2014 at 06:56

Thanks clive

The problem was that I  was using ADC3 but with channels of ADC1-2. It is weird to see such single-byte incrementation at DMA system! anyway if I did wrong, nothing would be guaranteed to work expectedly

Also thanks for my timer mistake correction