2012-05-08 09:29 PM
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... BJI 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-eoc2012-05-09 06:00 AM
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, Hal2012-05-09 11:25 AM
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);2012-05-09 03:52 PM
2012-05-09 03:58 PM
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?2012-05-09 04:04 PM
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)
ThanksBJ