cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 ADC-DMA weird behaviour

gavinli
Associate II
Posted on October 24, 2014 at 21:58

I am using T2 to trigger ADC1,ADC2 and ADC3, all the ADCs are working in indepent mode. each ADC EOC will trigger a DMA2 in a dedicate channel.

T2->ADC1->DMA2_Stream0.Channel_0 T2->ADC2->DMA2_Stream2.Channel_1 T2->ADC3->DMA2_Stream1.Channel_2 when I am doing single step and go into every single function calls, the code runs as expected. all interrupt can be generated correctly. LEDs blink correctly. when I run in full speed mode or single step over function calls, the code seems frozen, LEDs never blink. But when I set a break point in ISRs, it will stop at the break point and everything seems normal. I don't understand what wrong, please help me and pointing me to a direction. Thanks.

/* Local Includes */ 
#include ''adc.h'' 
#include ''stm32f4xx_syscfg.h'' 
#include ''stdio.h'' 
#include ''string.h'' 
/* Local Type Definitions */ 
/* Local Globals */ 
/* Local Functions */ 
static void NVIC_DMA2_init(void); 
static void TIM2_init(void); 
static void ADC_Common_init(void); 
static void ADC_init(const ADCDev *dev); 
static void DMA2_init(uint32_t* buf, uint32_t buf_size); 
static volatile int adc1_rdy = 0; 
static volatile int adc2_rdy = 0; 
static volatile int adc3_rdy = 0; 
static void NVIC_DMA2_init(void) 
{ 
NVIC_InitTypeDef NVIC_InitStructure; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4; 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; 
NVIC_Init(&NVIC_InitStructure); 
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn; 
NVIC_Init(&NVIC_InitStructure); 
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn; 
NVIC_Init(&NVIC_InitStructure); 
} 
void DMA2_Stream0_IRQHandler(void) 
{ 
if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0); 
adc1_rdy |= ADC_DMA_HT_RDY; 
} 
if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); 
adc1_rdy |= ADC_DMA_TC_RDY; 
} 
} 
void DMA2_Stream1_IRQHandler(void) 
{ 
if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_HTIF0)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_HTIF0); 
adc2_rdy |= ADC_DMA_HT_RDY; 
} 
if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF0)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF0); 
adc2_rdy |= ADC_DMA_TC_RDY; 
} 
} 
void DMA2_Stream2_IRQHandler(void) 
{ 
if(DMA_GetITStatus(DMA2_Stream2, DMA_IT_HTIF0)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_HTIF0); 
adc3_rdy |= ADC_DMA_HT_RDY; 
} 
if(DMA_GetITStatus(DMA2_Stream2, DMA_IT_TCIF0)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF0); 
adc3_rdy |= ADC_DMA_TC_RDY; 
} 
} 
static void TIM2_init(void) 
{ 
TIM_Cmd(TIM2, DISABLE); 
TIM_UpdateRequestConfig(TIM2, TIM_UpdateSource_Regular); 
/* TIM2 TRGO selection */ 
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); // ADC_ExternalTrigConv_T2_TRGO 
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
/* Time base configuration */ 
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 
TIM_TimeBaseStructure.TIM_Period = (uint32_t)(42000000) *1 - 1; // very long for test 
TIM_TimeBaseStructure.TIM_Prescaler = 0; 
TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 
} 
static void ADC_Common_init(void) 
{ 
ADC_CommonInitTypeDef ADC_CommonInitStructure; 
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; 
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; 
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; 
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; 
ADC_CommonInit(&ADC_CommonInitStructure); 
} 
static void ADC_init(const ADCDev *dev) 
{ 
ADC_InitTypeDef ADC_InitStruct; 
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; 
ADC_InitStruct.ADC_ScanConvMode = ENABLE; 
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; // Scan on Demand (Trigger) 
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; 
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; 
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; 
ADC_InitStruct.ADC_NbrOfConversion = dev->chn_nr; 
ADC_Init(dev->adc, &ADC_InitStruct); 
for (int i=0;i<
sizeof
(dev->chn_nr);i++) 
ADC_RegularChannelConfig(dev->adc, dev->chn[i], i+1, ADC_SampleTime_56Cycles); 
ADC_EOCOnEachRegularChannelCmd(dev->adc, ENABLE); 
ADC_DMARequestAfterLastTransferCmd(dev->adc, ENABLE); 
ADC_DMACmd(dev->adc, ENABLE); 
} 
static void DMA2_init(uint32_t* buf, uint32_t buf_size) 
{ 
NVIC_DMA2_init(); 
DMA_InitTypeDef DMA_InitStructure; 
DMA_DeInit(DMA2_Stream0); 
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; 
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
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_FIFOMode = DMA_FIFOMode_Enable; 
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; 
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; 
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; 
DMA_InitStructure.DMA_Channel = DMA_Channel_0; 
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; 
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buf; 
DMA_InitStructure.DMA_BufferSize = 4; 
DMA_Init(DMA2_Stream0, &DMA_InitStructure); 
DMA_ITConfig(DMA2_Stream0, DMA_IT_HT | DMA_IT_TC, ENABLE); 
DMA_Cmd(DMA2_Stream0, ENABLE); //Enable the DMA2 - Stream0 - Channel0 
DMA_InitStructure.DMA_Channel = DMA_Channel_1; 
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC2->DR; 
DMA_InitStructure.DMA_Memory0BaseAddr += DMA_InitStructure.DMA_BufferSize * 2; 
DMA_InitStructure.DMA_BufferSize = 4; 
DMA_Init(DMA2_Stream2, &DMA_InitStructure); 
DMA_ITConfig(DMA2_Stream2, DMA_IT_HT | DMA_IT_TC, ENABLE); 
DMA_Cmd(DMA2_Stream2, ENABLE); //Enable the DMA2 - Stream2 - Channel1 
DMA_InitStructure.DMA_Channel = DMA_Channel_2; 
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC3->DR; 
DMA_InitStructure.DMA_Memory0BaseAddr += DMA_InitStructure.DMA_BufferSize * 2; 
DMA_InitStructure.DMA_BufferSize = 4; 
DMA_Init(DMA2_Stream1, &DMA_InitStructure); 
DMA_ITConfig(DMA2_Stream1, DMA_IT_HT | DMA_IT_TC, ENABLE); 
DMA_Cmd(DMA2_Stream1, ENABLE); //Enable the DMA2 - Stream1 - Channel2 
} 
/* Exposed API */ 
void adc_init(const ADCDev *dev1, const ADCDev *dev2, const ADCDev *dev3, uint32_t* buf, uint32_t buf_size) 
{ 
DMA2_init(buf, buf_size); 
ADC_Common_init(); 
ADC_init(dev1); 
ADC_init(dev2); 
ADC_init(dev3); 
TIM2_init(); 
} 
void adc_start(void) 
{ 
TIM_Cmd(TIM2, ENABLE); 
ADC_Cmd(ADC1, ENABLE); 
ADC_Cmd(ADC2, ENABLE); 
ADC_Cmd(ADC3, ENABLE); 
} 
void adc_stop(void) 
{ 
TIM_Cmd(TIM2, DISABLE); 
} 
int adc1_get_status(void) 
{ 
int tmp = adc1_rdy; 
adc1_rdy = 0; 
return tmp; 
} 
int adc2_get_status(void) 
{ 
int tmp = adc2_rdy; 
adc2_rdy = 0; 
return tmp; 
} 
int adc3_get_status(void) 
{ 
int tmp = adc3_rdy; 
adc3_rdy = 0; 
return tmp; 
} 
static const ADCDev adc1 = {ADC1, 4, { 1, 2, 3, 4,}}; 
static const ADCDev adc2 = {ADC2, 4, {10, 11, 12, 13,}}; 
static const ADCDev adc3 = {ADC3, 4, { 4, 5, 6, 7,}}; 
volatile uint16_t adc_buf[ADCBUFSIZE]; 
int main(void) 
{ 
int led1_onoff, led2_onoff, led3_onoff; 
/* Local Globals */ 
platform_init(); 
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); 
memset((uint32_t*)adc_buf, 0, ADCBUFSIZE); 
led1_onoff = led2_onoff = led3_onoff = 0; 
adc_init(&adc1, &adc2, &adc3, (uint32_t*)adc_buf, ADCBUFSIZE); 
adc_start(); 
while(TRUE) 
{ 
if (adc1_get_status() & ADC_DMA_TC_RDY) { 
gpio_write_pin(GPIOPortID_G, GPIOPinID_6, led1_onoff); //LED1 
led1_onoff = !led1_onoff; 
} 
if (adc2_get_status() & ADC_DMA_TC_RDY) { 
gpio_write_pin(GPIOPortID_G, GPIOPinID_8, led2_onoff); //LED1 
led2_onoff = !led2_onoff; 
} 
if (adc3_get_status() & ADC_DMA_TC_RDY) { 
gpio_write_pin(GPIOPortID_I, GPIOPinID_9, led3_onoff); //LED1 
led3_onoff = !led3_onoff; 
} 
} 
} 
#ifndef __ADC_H__ 
#define __ADC_H__ 
/* Includes */ 
#include ''config.h'' 
#include ''stm32f4xx_adc.h'' 
#include ''stm32f4xx_dma.h'' 
#define TOTAL_CHN 8 
#define TOTAL_ADC 3 
#define ADCBUFSIZE (TOTAL_CHN*TOTAL_ADC) 
typedef struct { 
ADC_TypeDef * adc; 
int chn_nr; //total channels 
uint8 chn[TOTAL_CHN]; 
} ADCDev; 
/* Function Prototypes */ 
void adc_init(const ADCDev *dev1, const ADCDev *dev2, const ADCDev *dev3, uint32_t* buf, uint32_t buf_size); 
void adc_start(void); 
void adc_stop(void); 
#define ADC_DMA_HT_RDY 1 
#define ADC_DMA_TC_RDY 2 
int adc_get_status(void); 
int adc1_get_status(void); 
int adc2_get_status(void); 
int adc3_get_status(void); 
#endif //__ADC_H__ 

1 REPLY 1
gavinli
Associate II
Posted on October 24, 2014 at 22:26

I found the problem.

They are in the ISRs, the flag DMA_IT_HTIFx and DMA_IT_TCIFx, I forgot to change them accordingly for DMA2_Stream1_IRQHandler() and DMA2_Stream2_IRQHandler().

void DMA2_Stream1_IRQHandler(void) 
{ 
if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_HTIF1)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_HTIF1); 
adc2_rdy |= ADC_DMA_HT_RDY; 
} 
if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1); 
adc2_rdy |= ADC_DMA_TC_RDY; 
} 
} 
void DMA2_Stream2_IRQHandler(void) 
{ 
if(DMA_GetITStatus(DMA2_Stream2, DMA_IT_HTIF2)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_HTIF2); 
adc3_rdy |= ADC_DMA_HT_RDY; 
} 
if(DMA_GetITStatus(DMA2_Stream2, DMA_IT_TCIF2)) 
{ 
DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF2); 
adc3_rdy |= ADC_DMA_TC_RDY; 
} 
}