AnsweredAssumed Answered

stm32f2xx ADC EOC interrupt doesn't

Question asked by on May 9, 2012
Latest reply on May 10, 2012 by
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 */ 

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);

  //  COMMON ADC configuration.  
  // Configures the ADC to operate in independent or multi mode.
  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

  // 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 */

  /* Enable ADC3 */
  // Enable ADC EOC interrupt
  NVIC_SetPriority(ADC_IRQn, 0);

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
   // 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);  

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...

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.