STM32F205, SPL, TIM one-shot mode does trigger ADC
Hi there,
I am trying to get TIM4-CC4 in one-shot mode to trigger ADC1. It seems that TIM4 and CC4 is configured well: if enabled it generates interrupts on TIM_IT_CC4. So I am pretty sure CC4 fires.
I configured ADC1 for external triggering through the Timer 4 CC4 event. I checked various example codes, but still ADC does not seem to start a conversion: I don't get an interrupt at the end of conversion. I am pretty sure the ADC1 interrupt handler is Ok: when starting a converion from software, the interrupt handler is called allright.
I am using the Standard Peripheral Library for the STM32F2xx.
After days of trial and error, checking example software and reading the reference manual, I am out of inspiration :)
There is no way of checking internal signals like CC, TRGI, TRGO, right?
Any way, I absolutely appreciate comments or suggestions!
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
ADC_CommonInitTypeDef ADC_CommonInitStruct;
ADC_InitTypeDef ADC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// ======================================================================
// == Configuration of Timer 4 ==
// ======================================================================
// - to be triggered by an rising edge on TIM3 TRGO output
// - after 6.25 us, TIM4 OC4Ref must be set
// - 1us later, the OC4Ref output can drop
// - input capture on Zero Cross Detector input TIM_Ch1, pin D3
// - max counter resolution, clock = 30 Mhz
// - 30000000UL = 30 MHz Timer Clock = HCLK / 4
// - counting up, measure time from zero count
// - Pulse length: CCR register (TIM_OCInitStructure.TIM_Pulse): 6.25E-6 * 30000000 = 187
// - Pulse+Delay length: The ARR register (TIM_TimeBaseStructure.TIM_Period): 7.25E-6 * 30000000 = 217
TIM_TimeBaseStruct.TIM_Period = ((ZCD2PEAKDELAY + ADCSTARTPULSEWIDTH) * TIMCLK);
TIM_TimeBaseStruct.TIM_Prescaler = 1;
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct);
// - One Pulse is a special case of output compare mode
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = (ZCD2PEAKDELAY * TIMCLK);
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM4, &TIM_OCInitStruct);
// - One single pulse when triggered
TIM_SelectOnePulseMode(TIM4, TIM_OPMode_Single);
// - counter starts when triggered from TIM3 TRGO
TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Trigger);
// TIM enable counter
TIM_Cmd(TIM4, ENABLE);
// OC4 can generate interrupt (code removed for clarity and TIM4 timing changes are seen, so probably ok....
// ======================================================================
// == Configuration of ADC ==
// ======================================================================
// - to be triggered by a rising edge of TIM4_Ch4 output
// - sample A0 analog input
// - at EOC, DMA stores the result in memory
// - Single ADC mode
// - Sample at 30MHz clock (prescaler = 2)
// - For now, no DMA
// - No delay between ADC1 and ADC2 required
ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStruct);
// - 12 bits resolution (=> 15 clock cycles = 0.5 us)
// - Single (one channel) scan mode
// - Single scan, not continuous
// - Trigger converion on a rising edge
// - Trigger from TIM4_CC4
// - Right aligned data, no scaling
// - 1 conversion
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStruct.ADC_ScanConvMode = ENABLE;
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStruct);
// - Setup A0 input channel as single channel, with highest speed sampling
ADC_RegularChannelConfig(ADC1, PIN_MAP[A0].adc_channel, 1, ADC_SampleTime_15Cycles);
// - For now, disable DMA
ADC_DMARequestAfterLastTransferCmd(ADC1, DISABLE);
ADC_DMACmd(ADC1, DISABLE);
// Temporary: for testing only
NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
// Enable ADC
ADC_Cmd(ADC1, ENABLE);
#output-compare #adc #tim #spl #stm32f205 #external-trigger #ons-shot