From d2abd471a5badb253c7e9a096ac7cf5d1490dd19 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 16 Dec 2016 21:55:55 +0000 Subject: [PATCH] stm32: timer: further clarify example commentary The "timer" example is actually "the same" for both f1 and f4. Do a sanity sweep over the commentary, remove all vestiges that this was cloned from a motor control example, and synchronize both examples. Future work should extract the common portions "somewhere" but at least make them consistent for now. --- .../stm32/f4/stm32f4-discovery/timer/timer.c | 69 ++++++------------- 1 file changed, 20 insertions(+), 49 deletions(-) diff --git a/examples/stm32/f4/stm32f4-discovery/timer/timer.c b/examples/stm32/f4/stm32f4-discovery/timer/timer.c index 927228d..b9cf04c 100644 --- a/examples/stm32/f4/stm32f4-discovery/timer/timer.c +++ b/examples/stm32/f4/stm32f4-discovery/timer/timer.c @@ -18,14 +18,18 @@ * along with this library. If not, see . */ +#include #include #include #include -#include #include #include +#ifndef ARRAY_LEN +#define ARRAY_LEN(array) (sizeof((array))/sizeof((array)[0])) +#endif + uint16_t frequency_sequence[18] = { 1000, 500, @@ -80,75 +84,41 @@ static void tim_setup(void) /* Enable TIM2 interrupt. */ nvic_enable_irq(NVIC_TIM2_IRQ); - /* Reset TIM2 peripheral. */ + /* Reset TIM2 peripheral to defaults. */ rcc_periph_reset_pulse(RST_TIM2); /* Timer global mode: * - No divider * - Alignment edge * - Direction up + * (These are actually default values after reset above, so this call + * is strictly unnecessary, but demos the api for alternative settings) */ timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); - - /* Reset prescaler value. - * Running the clock at 10kHz. - */ - /* - * On STM32F4 the timers are not running directly from pure APB1 or - * APB2 clock busses. The APB1 and APB2 clocks used for timers might - * be the double of the APB1 and APB2 clocks. This depends on the - * setting in DCKCFGR register. By default the behaviour is the - * following: If the Prescaler APBx is greater than 1 the derived timer - * APBx clocks will be double of the original APBx frequencies. Only if - * the APBx prescaler is set to 1 the derived timer APBx will equal the - * original APBx frequencies. - * - * In our case here the APB1 is system frequency divided by 4 and APB2 - * is system frequency divided by 2. This means APB1 timer will be 2 x - * APB1 and APB2 will be 2 x APB2. So when we try to calculate the - * prescaler value we have to use rcc_apb1_freqency * 2!!! - * - * For additional information see reference manual for the stm32f4 - * familiy of chips. Page 204 and 213 - */ + /* + * Please take note that the clock source for STM32F4 timers + * might not be the raw APB1/APB2 clocks. In various conditions they + * are doubled. See the Reference Manual for full details! + * In our case, TIM2 on APB1 is running at double frequency, so this + * sets the prescaler to have the timer run at 10kHz + */ timer_set_prescaler(TIM2, ((rcc_apb1_frequency * 2) / 10000)); /* Disable preload. */ timer_disable_preload(TIM2); - - /* Continous mode. */ timer_continuous_mode(TIM2); - /* Period (36kHz). */ + /* count full range, as we'll update compare value continuously */ timer_set_period(TIM2, 65535); - /* Disable outputs. */ - timer_disable_oc_output(TIM2, TIM_OC1); - timer_disable_oc_output(TIM2, TIM_OC2); - timer_disable_oc_output(TIM2, TIM_OC3); - timer_disable_oc_output(TIM2, TIM_OC4); - - /* -- OC1 configuration -- */ - - /* Configure global mode of line 1. */ - timer_disable_oc_clear(TIM2, TIM_OC1); - timer_disable_oc_preload(TIM2, TIM_OC1); - timer_set_oc_slow_mode(TIM2, TIM_OC1); - timer_set_oc_mode(TIM2, TIM_OC1, TIM_OCM_FROZEN); - - /* Set the capture compare value for OC1. */ + /* Set the initual output compare value for OC1. */ timer_set_oc_value(TIM2, TIM_OC1, 1000); - /* ---- */ - - /* ARR reload enable. */ - timer_disable_preload(TIM2); - /* Counter enable. */ timer_enable_counter(TIM2); - /* Enable commutation interrupt. */ + /* Enable Channel 1 compare interrupt to recalculate compare values */ timer_enable_irq(TIM2, TIM_DIER_CC1IE); } @@ -170,8 +140,9 @@ void tim2_isr(void) new_time = compare_time + frequency; timer_set_oc_value(TIM2, TIM_OC1, new_time); - if (frequency_sel == 18) + if (frequency_sel == ARRAY_LEN(frequency_sequence)) { frequency_sel = 0; + } /* Toggle LED to indicate compare event. */ gpio_toggle(GPIOD, GPIO12);