STM32F205, SPL, TIM one-shot mode does trigger ADC
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-01-02 10:23 AM
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- Labels:
-
ADC
-
SPL
-
STM32F2 Series
-
TIM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-01-02 2:47 PM
TIM_OC1Init(TIM4, &TIM_OCInitStruct);
// HOW DOES THIS USE TIM4_CC4 ??Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-01-02 8:22 PM
OMG, that was stupid... it was the remainder of one of my experiments
Changed that to:
TIM_OC4Init(TIM4, &TIM_OCInitStruct);
But still no luck, the ADC is still not triggered...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-01-02 10:35 PM
There's a lot missing...
I'll note the Period and Prescaler are N-1, so a prescaler of 1 is DIV2, the TIMCLK is twice the APB clock in this instance.
>>There is no way of checking internal signals like CC, TRGI, TRGO, right?
You can get TIM4_CC4 to a pin, if you don't see a waveform there the ADC isn't going to trigger, work back from there.
You could get the trigger input to reset the counter, with a maximal period you should be able to see by observation that the count doesn't go full cycle.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-01-12 1:27 PM
Thanks for your suggestions, Clive!
The TIMCLK being twice the APB clock: This means that the counters are counting at the double speed as the registers are clocked, right? Could that lead to problems?
I have tried to connect the EXTI line 11 to an input pin. Unfortunately I have a WM-N-BM-09 WICED module, where the STM32F205 is mounted below a wifi chip. The GPIO pin connected to the EXI Line 11 is not available for connection.
So I concentrated on trying different external trigger sources: I tried not only TIM5 but also TIM8 which can also be selected as external ADC trigger, both TRGO and CC1, both unsuccessfull. These timers do run properly (I checked by means of an timer interrupt handler, which triggers with the right period).
Since I also am able to start ADC conversions through software (ADC_SoftwareStartConv(ADC1)), including an interrupt handling the EOC, I suspect a missing configuration of the link between a timer and the ADC external trigger circuit.
I have some questions on triggering the ADC from an external source:
- When setup for external triggering CR2.EXTEN=0x01, must conversions still be enabled through CR2.SWSTART or an other register?
- When setup for external triggering on a CC event (e.g. CR2.EXTSEL = 1101 - Timer 8 CC1 event), must this CC event be released by some register?
- When setup for external triggering on a TRGO event (e.g. CR2.EXTSEL = 1110 - Timer 8 TRGO event), must this TRGO event be released other than by TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_OC1Ref) and TIM_SelectMasterSlaveMode(TIM8, TIM_MasterSlaveMode_Enable)
- Is the CC event only available when the associated GPIO pin is configured as AF Alternative Function?
- Does the trigger link between timers and ADC require some special clock configuration RSS?
I also noticed that the start/trigger registers for the ADC in STM32F2xx differ somewhat from the STM32F1xx.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-01-16 12:15 PM
I'm answering based on the STM32L471 chip I'm using since I just spent over a day stumbling through the undocumented bits of hardware trigger setup; it seems to have the same ADC and timer peripherals.
- When setup for external triggering CR2.EXTEN=0x01, must conversions still be enabled through CR2.SWSTART or an other register?Yes. When EXTEN=00, ADSTART is a trigger signal (resets after the conversion completes). When EXTEN has any other value, ADSTART becomes an enable latch. Hardware trigger signals are ignored when ADSTART=0. This is described in the reference manual section 'Starting Conversions (ADSTART, JADSTART)'.
- When setup for external triggering on a CC event (e.g. CR2.EXTSEL = 1101 - Timer 8 CC1 event), must this CC event be released by some register?Yes. The ADC trigger is edge-sensitive (see description of EXTEN) so the output compare mode set in CCMRj in the timer must be a PWM mode, since those produce regular edges. Also, the output enable for that channel must be enabled in CCER.
- When setup for external triggering on a TRGO event (e.g. CR2.EXTSEL = 1110 - Timer 8 TRGO event), must this TRGO event be released other than by TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_OC1Ref) and TIM_SelectMasterSlaveMode(TIM8, TIM_MasterSlaveMode_Enable)I didn't use the TRGO signal for ADC triggering, since I need it for another purpose.
- Is the CC event only available when the associated GPIO pin is configured as AF Alternative Function?No, it's enough to enable the output from the timer peripheral, you do not need to have any pin connected.
- Does the trigger link between timers and ADC require some special clock configuration RSS?The reset/clock control needs to be configured properly for the timer and the ADC (remember to both enable clock for the register bus interface and also the timebase / sampleclock which these peripherals use internally). There wasn't any additional RCC settings needed to make the hardware trigger work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-01-16 1:50 PM
The F2/F4 are very similar, they differ from the F1 in numerous ways as ST learned a lot of things, and improved/fixed them in subsequent designs.
You don't have to get triggers to pins, but it helps to see them if you think things are broken.
The TIM, ADC and DMA clocks need to be enabled, I'd generally enable ALL the clocks I need in one subroutine rather than pick my way through them as I initialize specific peripherals. Also usually put all the GPIO stuff in one place.
Up vote any posts that you find helpful, it shows what's working..
