2014-10-24 12:58 PM
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__
2014-10-24 01:26 PM
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;
}
}