AnsweredAssumed Answered

STM32F205, SPL, TIM one-shot mode does trigger ADC

Question asked by van_Beek.Raymond on Jan 2, 2017
Latest reply on Jan 16, 2017 by Clive One

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

Outcomes