cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Interrupt/DMA/Array issue

joesnyder
Associate II
Posted on September 03, 2015 at 19:21

I'm having a problem where when I try to access an array from within a timer interrupt callback, everything seems to fall apart. To keep it simple, I have:

Timer 2 is set up to interrupt every 10us. Timer 3 is set up to interrupt every 10ms (1000x longer than Timer 2). Those interrupts are verified by toggling I/Os. That works great. I have a 3 element array (RealTimeADCValue[3]), that I have continuous ADC conversion set up on ADC 0-2 with DMA. I can see those values in STM Studio and output them to a display. That works great too. I'm trying to tally up a running total of the ADC channel 0 values with each Timer 2 tick. Essentially, tally up ADC values with each 10us tick (1000 samples) until Timer 3 rolls over, then store that total. The callback code is:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance==TIM2) //this timer is 1000x longer than TIM3
{
ADCSamplesLast=ADCSamplesWorking; //store number of samples taken, then reset
ADCSamplesWorking=0;
ADCTallyLast=ADCTallyWorking; //store the tally of ADC values, then reset
ADCTallyWorking=0;
}
if (htim->Instance==TIM3)
{
//ADCTallyWorking = ADCTallyWorking + RealTimeADCValue[0]; //add up the ADC values (have tried ''+='' as well...)
ADCSamplesWorking++; //inc count of samples taken
}
}

With it as-is, with the tallying of the ADC array commented out, it reads as expected, and ''ADCSamplesLast'' is ~1000. However, when I un-comment that line, the number of samples taken goes to like 2500, and it only stores one ADC value in ADCTallyLast. I even just tried reading ''RealTimeADCValue[0]'' into a dummy variable with the same results. Is there something I'm not getting about accessing an array, controlled by DMA, from within a callback? Thanks for your input. Joe
3 REPLIES 3
joesnyder
Associate II
Posted on September 03, 2015 at 20:42

For amplifying info, I defined a dummy array ''DeleteMe[3]'', and this worked:

if (htim->Instance==TIM3)
{
DeleteMe[0]=RealTimeADCValue[0]; //move ADC/DMA generated array element to a different dummy array....
ADCTallyWorking += DeleteMe[0]; //...then use the dummy array, and it works. ??
ADCSamplesWorking++; //inc count of samples taken
}

I'm trying to figure out why I can't just use ''ADCTallyWorking += RealTimeADCValue[0]'' directly.
jpeacock
Associate II
Posted on September 03, 2015 at 22:04

Are your counters declared as volatile?

joesnyder
Associate II
Posted on September 03, 2015 at 23:08

They were not. I just tried declaring all the counters and arrays as volatile:

uint32_t volatile RealTimeADCValue[3];
//uint32_t volatile DeleteMe[3];
uint32_t volatile ADCSamplesWorking=0; //number of ADC samples this cycle
uint32_t volatile ADCTallyWorking=0;
uint32_t volatile ADCSamplesLast=0; //number of ADC samples this cycle
uint32_t volatile ADCTallyLast=0;

...and the same thing is happening. It works fine now using the dummy array, it's just one of those things that works and you don't know why, and you shouldn't have to do. Joe