cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f2xx ADC EOC interrupt doesn't

bruce2399
Associate II
Posted on May 09, 2012 at 06:29

Working on our own hardware with an external mux.  

Want to switch the mux on the interrupt, so I need the interrupt to happen.  So far I see no interrupt.   Configured as ADC3 so the default IRQ is either of ADC_IRQHandler or ADC3_IRQHandler....  

The code goes through the usual config for the ADC Controller:  

void ADC3_IRQHandler(void)

{

   ADC_ClearITPendingBit(ADC3, ADC_IT_EOC);

     ...

     /* Start ADC3 Software Conversion */ 

   ADC_SoftwareStartConv(ADC3);

}

void configureAdc(void)

{

  ADC_InitTypeDef ADC_InitStructure;

  DMA_InitTypeDef DMA_InitStructure;

  NVIC_InitTypeDef  NVIC_InitStructure;

  ADC_CommonInitTypeDef ADC_CommonInitStructure;

 // Enable DMA2 clock 

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

  // Enable ADC3 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

  ADC_DeInit();

  //  COMMON ADC configuration.  

  // Configures the ADC to operate in independent or multi mode.

  ADC_CommonStructInit(&ADC_CommonInitStructure);

  ADC_CommonInitStructure.ADC_Mode  = ADC_Mode_Independent;     

  //  Select the frequency of the clock 

  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;          

  // multi-ADC mode  -  DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)  

  ADC_CommonInitStructure.ADC_DMAAccessMode =   ADC_DMAAccessMode_Disabled;   

  // Delay between sampling phases.  // commented?  

  ADC_CommonInitStructure.ADC_TwoSamplingDelay =  ADC_TwoSamplingDelay_5Cycles;   // Range is 5-20

  ADC_CommonInit(&ADC_CommonInitStructure);

  // Noting  that the DMA works OK and  generates regular interrupts 

  .... 

  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;  // enable multichannels 

  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // One Conversion at a time

  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfConversion = NUMBER_STATIONS;

  ADC_Init(ADC3, &ADC_InitStructure);

  /* ADC3 regular channel configuration */ 

  ADC_RegularChannelConfig(ADC3, ADC_Channel_0, 1,    ADC_SampleTime_28Cycles);

    // allow settling after mux channel change

  ADC_RegularChannelConfig(ADC3, ADC_Channel_13, 2, ADC_SampleTime_15Cycles);

  ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 3, ADC_SampleTime_15Cycles);

  ADC_RegularChannelConfig(ADC3, ADC_Channel_8, 4, ADC_SampleTime_15Cycles);

  ADC_RegularChannelConfig(ADC3, ADC_Channel_6, 5, ADC_SampleTime_15Cycles); 

  ADC_RegularChannelConfig(ADC3, ADC_Channel_7, 6, ADC_SampleTime_15Cycles); 

 /* Enable ADC3 DMA */

  ADC_DMACmd(ADC3, ENABLE);

  /* Enable ADC3 */

  ADC_Cmd(ADC3, ENABLE);

  // Enable ADC EOC interrupt

  ADC_ITConfig(ADC3, ADC_IT_EOC, ENABLE);

  NVIC_SetPriority(ADC_IRQn, 0);

  NVIC_EnableIRQ(ADC_IRQn);

}

void beginSampling(void)

{  

   /* We Set up A2D Timer when task is started  */

   DMA2_Stream0->M0AR = (uint32_t)&AdcData[2]; // filterIndex];  // M1AR not used unless double buffered.  FIFO not used

   DMA2_Stream0->NDTR = NUMBER_STATIONS * NUMBER_COLORS;

   

   // Set the TC (Transfer Complete) bit in the Configuration Register , enables error bits. 

   DMA_ITConfig( DMA2_Stream0, DMA_IT_TC, SET );

   DMA_Cmd(DMA2_Stream0, ENABLE);  

   (void)ctl_unmask_isr(ADC_IRQn);

   NVIC_EnableIRQ(ADC_IRQn);

   ADC_SoftwareStartConv(ADC3);

   (void)ctl_unmask_isr(TIM4_IRQn);

   TIM_Cmd(TIM4, ENABLE);

}

Many diverse versions of this have failed to produce a single entry into the interrupt handler. Checking the NVIC registers it is not masked.  Checking the ADC3 registers it is enabled. 

Checking the GPIO configuration, the analog pins are connected and the mux is powered up. 

TIM4 is enabled, runs and gives interrupts. 

DMA2_Stream0 is enabled, runs and gives interrupts. 

Nothing seems to persuade the ADC converter to give interrupts.  My perception/guess is that the EOC is not firing because the conversion isn't actually running.    What I can't work out is where else it needs to be poked.   I get the feeling that it is laughing at me.  :)  

Thanks for any suggestions about what to look for and how...

  

BJ

I note that in the debugger, I am unable to alter the EOC status.  I presume it is read only as a result, but have also seen this sort of thing with an incorrectly configured clock.  

BJ

#answered #stm32f2-adc-eoc
5 REPLIES 5
raptorhal2
Lead
Posted on May 09, 2012 at 15:00

One fix you need is to add:

  ADC_InitStructure.ADC_ExternalTrigConv = 0;

That may not fix the observed problem, but will fix a source of incorrect ADC values.

How does '' our own hardware with an external mux '' relate to converting six ADC3 channels ?

Cheers, Hal

Posted on May 09, 2012 at 20:25

The name in the vector table is surely ADC_IRQHandler ? Unless you change that it's not going to call something else.

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0);

  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bruce2399
Associate II
Posted on May 10, 2012 at 00:52

Thanks Guys.  

Problem was actually that I was trying to do 6 conversions of 6 simultaneous channels (which was a legacy operation from a prior incarnation)   so I was getting the overflow on the first attempt to convert and that interrupt was NOT enabled (or cleared)  so it just died before it could get started.  

Elsewhere saw the ADC3_InterruptHandler named... docs I've seen aren't that clear.   ''ADC_IRQHandler''  works just fine.  

Checking your other notes now too. 

Thanks very much

ciao

BJ

bruce2399
Associate II
Posted on May 10, 2012 at 00:58

Fortunately I abandoned the NVIC lines in favor of the simpler 

  NVIC_SetPriority(ADC_IRQn, 0);

  NVIC_EnableIRQ(ADC_IRQn);

...but puzzled that this is seen at all.  How could copy-paste go so wrong?  

bruce2399
Associate II
Posted on May 10, 2012 at 01:04

Got 6 stations with 4 sensors ( of different frequency sensitivities) each.  The mux switches between the sensors, the stations are attached to the A2D.   Gives us a batch of 24 ALMOST synchronous readings on what is currently a 500 uSec clock (which may get to be tuned a bit)

Thanks

BJ