cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32F205RC] Cannot get ADC ISR to trigger ...

root
Associate II
Posted on February 12, 2013 at 20:08

Hello,

Just want to convert one channel and trigger an interrupt when finished, just the basic stuff ... but can't get the ADC interrupt to trigger :

/* 
* adc.c 
* 
* Created on: Feb 12, 2013 
* Author: root 
*/ 
#include ''analog.h'' 
#include ''stm32f2xx_gpio.h'' 
#include ''stm32f2xx_adc.h'' 
#include ''stm32f2xx_rcc.h'' 
#include ''opsy_api.h'' 
#include ''misc.h'' 
#include ''semaphores.h'' 
void ANALOG_Init(void) 
{ 
ADC_InitTypeDef adc_init; 
ADC_CommonInitTypeDef adc_common_init; 
GPIO_InitTypeDef gpio_init; 
NVIC_InitTypeDef nvic_init; 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 
gpio_init.GPIO_Mode = GPIO_Mode_AN; 
gpio_init.GPIO_OType = GPIO_OType_PP; 
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; 
gpio_init.GPIO_Speed = GPIO_Speed_2MHz; 
gpio_init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 
| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; 
GPIO_Init(GPIOA, &gpio_init); 
gpio_init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; 
GPIO_Init(GPIOB, &gpio_init); 
gpio_init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; 
GPIO_Init(GPIOC, &gpio_init); 
ADC_CommonStructInit(&adc_common_init); 
ADC_CommonInit(&adc_common_init); 
ADC_StructInit(&adc_init); 
adc_init.ADC_ScanConvMode = ENABLE; 
ADC_Init(ADC1, &adc_init); 
ADC_RegularChannelConfig(ADC1, (unsigned char)adc, 1, ADC_SampleTime_480Cycles); 
nvic_init.NVIC_IRQChannel = ADC_IRQn; 
nvic_init.NVIC_IRQChannelCmd = ENABLE; 
nvic_init.NVIC_IRQChannelPreemptionPriority = 2; 
nvic_init.NVIC_IRQChannelSubPriority = 3; 
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); 
OPSY_API_NvicInit(&nvic_init); 
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); 
ADC_Cmd(ADC1, ENABLE); 
} 
unsigned short ANALOG_GetValue(adc_t adc) 
{ 
ADC_SoftwareStartConv(ADC1); 
OPSY_API_WaitOnSemaphore(ADC_CONVERSION_DONE); 
return ADC_GetConversionValue(ADC1); 
} 
void ADC1_3_IRQHandler(void) 
{ 
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); 
OPSY_API_SignalSemaphore(ADC_CONVERSION_DONE); 
} 

I verified the linker script and ADC1_3_IRQHandler is the correct name. ST doesn't give any code example using only interrupts, they use DMA even for single channel conversion. I may give the DMA a try, but having to use DMA for ONE conversion of ONE channel seems a ''bit'' odd. Anyway if I bypass the interrupt and wait for the EOC flag to be set (using a while loop), it does work as expected (and I verified the EOC flag is correctly set, nothing seems unusual). Any idea ? Thomas.
5 REPLIES 5
Posted on February 12, 2013 at 21:46

I verified the linker script and ADC1_3_IRQHandler is the correct name.

The firmware library, startup_sm32f2xx.s normally has this as: ADC_IRQHandler()

void ANALOG_Init(void)
{
ADC_InitTypeDef adc_init;
ADC_CommonInitTypeDef adc_common_init;
GPIO_InitTypeDef gpio_init;
NVIC_InitTypeDef nvic_init;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
gpio_init.GPIO_Mode = GPIO_Mode_AN;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio_init.GPIO_Speed = GPIO_Speed_2MHz;
gpio_init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOA, &gpio_init);
gpio_init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOB, &gpio_init);
gpio_init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_Init(GPIOC, &gpio_init);
ADC_CommonStructInit(&adc_common_init);
ADC_CommonInit(&adc_common_init);
ADC_StructInit(&adc_init);
adc_init.ADC_ContinuousConvMode = ENABLE; // Hit interrupt over and over
ADC_Init(ADC1, &adc_init);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_480Cycles); // some channel
nvic_init.NVIC_IRQChannel = ADC_IRQn;
nvic_init.NVIC_IRQChannelCmd = ENABLE;
nvic_init.NVIC_IRQChannelPreemptionPriority = 2;
nvic_init.NVIC_IRQChannelSubPriority = 3;
NVIC_Init(&nvic_init);
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_SoftwareStartConv(ADC1); /* Start ADC1 Software Conversion, light off first */
}
void ADC_IRQHandler(void)
{
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
ADC_GetConversionValue(ADC1);
} 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
root
Associate II
Posted on February 12, 2013 at 22:01

Hello Clive,

Nop, verified the linker script and it's ok, even tried changing it to ADC_IRQHandler, same.

I'm using TASKING so the linker script sometimes uses different names.

I'm already using other interrupts (USART1, SVC, pendSV, etc) and it's working good, so the problem is related to ADC.

Tried to put it in continuous mode, still no ISR trigger.

There is something missing but can't find what (doing a search on the forum it seems I'm not the first one to encounter the issue).

Thomas.
Posted on February 12, 2013 at 22:05

Hi Thomas,

I have the above pasted back code generating a stream of interrupts when I dumped it into a shell project on a 205ZC. I mashed the code a little to remove the RTOS stuff, and needed to start the software conversion. With your original scan mode it generated a singular interrupt after I started the conversion. I didn't dig in any deeper, but definitely got interrupt breakpoints after I modified your code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
root
Associate II
Posted on February 12, 2013 at 23:27

Indeed, copied the code to a blank new project and the isr is triggering ...

I guess I'll spend some hours debugging now :D

Thomas.
root
Associate II
Posted on February 12, 2013 at 23:52

Back,

Found it :D

I'm playing with real time operating system developement ... and left the tasks stack to 128 bytes for after some tests.

Was ''just'' a stack overflow (found it while observing PSP on interrupt stacking). I guess I'll add some protections against this if possible.

Increased tasks stack to 2kB each and it's working as expected.

Thanks once again Clive !

Thomas.