stm32f3xx-hal
stm32f3xx-hal copied to clipboard
[Bug] Incorrect pwm frequency
tim1(dp.TIM1, 144, 1.mhz().into(), &clocks)
leads to actual timer frequency of 0.5 MHz, as code doesn't set/takes into account tim1sw bit in RCC CFGR3 register
Same thing with other timers and possibly peripherals most likely. (Occurs only when MCU is running with max frequency)
Note that center align modes will also cause incorrect freqs.
I have not had the time to dig into the PWM issues / PRs yet, but can this possible resolved or improved by https://github.com/stm32-rs/stm32f3xx-hal/pull/196?
Looks like current PWM and Timer implementation is wrong at source clock calculation. https://github.com/stm32-rs/stm32f3xx-hal/blob/f8eb2926a38c9a40c41ba53de60839ac25d78f6e/src/pwm.rs#L283-L284
As in, some timers use apb1 while others use apb2? Here's how I solved it, where paste is a macro crate that lets you build identifiers from parts, $apb is apb1 or apb2, and the apb1_timer() and apb2_timer() are traits the clocks struct implements. (Ie that calculation line is moved to the clock functionality; the timer module determines which to use, apb1 or apb2.)
paste! {
let mut timer = Timer { clock_speed: clocks.[<$apb _timer>](), tim };
// ...
}
Example trait implementation:
fn apb2_timer(&self) -> u32 {
if let ApbPrescaler::Div1 = self.apb2_prescaler {
self.apb2()
} else {
self.apb2() * 2
}
}