diff --git a/cpu/stm32_common/cpu_common.c b/cpu/stm32_common/cpu_common.c index f894297770..83f542c606 100644 --- a/cpu/stm32_common/cpu_common.c +++ b/cpu/stm32_common/cpu_common.c @@ -24,6 +24,28 @@ #define ENABLE_DEBUG (0) #include "debug.h" +/** + * @brief Timer specific additional bus clock prescaler + * + * This prescale factor is dependent on the actual APBx bus clock divider, if + * the APBx presacler is != 1, it is set to 2, if the APBx prescaler is == 1, it + * is set to 1. + * + * See reference manuals section 'reset and clock control'. + */ +static const uint8_t apbmul[] = { +#if (CLOCK_APB1 < CLOCK_CORECLOCK) + [APB1] = 2, +#else + [APB1] = 1, +#endif +#if (CLOCK_APB2 < CLOCK_CORECLOCK) + [APB2] = 2 +#else + [APB2] = 1 +#endif +}; + uint32_t periph_apb_clk(uint8_t bus) { if (bus == APB1) { @@ -34,6 +56,11 @@ uint32_t periph_apb_clk(uint8_t bus) } } +uint32_t periph_timer_clk(uint8_t bus) +{ + return periph_apb_clk(bus) * apbmul[bus]; +} + void periph_clk_en(bus_t bus, uint32_t mask) { switch (bus) { diff --git a/cpu/stm32_common/include/periph_cpu_common.h b/cpu/stm32_common/include/periph_cpu_common.h index 5be53ddc77..b71390b373 100644 --- a/cpu/stm32_common/include/periph_cpu_common.h +++ b/cpu/stm32_common/include/periph_cpu_common.h @@ -297,6 +297,15 @@ typedef struct { */ uint32_t periph_apb_clk(uint8_t bus); +/** + * @brief Get the actual timer clock frequency + * + * @param[in] bus corresponding APBx bus + * + * @return timer clock frequency in Hz + */ +uint32_t periph_timer_clk(uint8_t bus); + /** * @brief Enable the given peripheral clock * diff --git a/cpu/stm32_common/periph/pwm.c b/cpu/stm32_common/periph/pwm.c index 20cb30496e..d7056f6209 100644 --- a/cpu/stm32_common/periph/pwm.c +++ b/cpu/stm32_common/periph/pwm.c @@ -42,10 +42,10 @@ static inline TIM_TypeDef *dev(pwm_t pwm) uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res) { - uint32_t bus_clk = periph_apb_clk(pwm_config[pwm].bus); + uint32_t timer_clk = periph_timer_clk(pwm_config[pwm].bus); /* verify parameters */ - assert((pwm < PWM_NUMOF) && ((freq * res) < bus_clk)); + assert((pwm < PWM_NUMOF) && ((freq * res) < timer_clk)); /* power on the used timer */ periph_clk_en(pwm_config[pwm].bus, pwm_config[pwm].rcc_mask); @@ -66,7 +66,7 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res) /* configure the PWM frequency and resolution by setting the auto-reload * and prescaler registers */ - dev(pwm)->PSC = (bus_clk / (res * freq)) - 1; + dev(pwm)->PSC = (timer_clk / (res * freq)) - 1; dev(pwm)->ARR = res - 1; /* set PWM mode */ @@ -95,7 +95,7 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res) dev(pwm)->CR1 |= TIM_CR1_CEN; /* return the actual used PWM frequency */ - return (bus_clk / (res * (dev(pwm)->PSC + 1))); + return (timer_clk / (res * (dev(pwm)->PSC + 1))); } uint8_t pwm_channels(pwm_t pwm) diff --git a/cpu/stm32_common/periph/timer.c b/cpu/stm32_common/periph/timer.c index b7e5f18880..d9ddc59cc4 100644 --- a/cpu/stm32_common/periph/timer.c +++ b/cpu/stm32_common/periph/timer.c @@ -23,28 +23,6 @@ #include "cpu.h" #include "periph/timer.h" -/** - * @brief Timer specific additional bus clock presacler - * - * This prescale factor is dependent on the actual APBx bus clock divider, if - * the APBx presacler is != 1, it is set to 2, if the APBx prescaler is == 1, it - * is set to 1. - * - * See reference manuals section 'reset and clock control'. - */ -static const uint8_t apbmul[] = { -#if (CLOCK_APB1 < CLOCK_CORECLOCK) - [APB1] = 2, -#else - [APB1] = 1, -#endif -#if (CLOCK_APB2 < CLOCK_CORECLOCK) - [APB2] = 2 -#else - [APB2] = 1 -#endif -}; - /** * @brief Interrupt context for each configured timer */ @@ -78,8 +56,7 @@ int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg) dev(tim)->ARR = timer_config[tim].max; /* set prescaler */ - dev(tim)->PSC = (((periph_apb_clk(timer_config[tim].bus) * - apbmul[timer_config[tim].bus]) / freq) - 1); + dev(tim)->PSC = ((periph_timer_clk(timer_config[tim].bus) / freq) - 1); /* generate an update event to apply our configuration */ dev(tim)->EGR = TIM_EGR_UG;