AnsweredAssumed Answered

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

Question asked by Legrand.Thomas.001 on Feb 12, 2013
Latest reply on Feb 12, 2013 by Legrand.Thomas.001
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.

Outcomes