stm32f3xx-hal icon indicating copy to clipboard operation
stm32f3xx-hal copied to clipboard

[Bug] Incorrect pwm frequency

Open mstumbra opened this issue 4 years ago • 4 comments

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)

mstumbra avatar Mar 05 '21 01:03 mstumbra

Note that center align modes will also cause incorrect freqs.

David-OConnor avatar Mar 05 '21 04:03 David-OConnor

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?

Sh3Rm4n avatar Mar 05 '21 07:03 Sh3Rm4n

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

Piroro-hs avatar Mar 14 '21 12:03 Piroro-hs

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
        }
    }

David-OConnor avatar Mar 14 '21 15:03 David-OConnor