Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Incorrect pwm frequency #205

Open
mstumbra opened this issue Mar 5, 2021 · 4 comments
Open

[Bug] Incorrect pwm frequency #205

mstumbra opened this issue Mar 5, 2021 · 4 comments
Labels
bug Something isn't working

Comments

@mstumbra
Copy link

mstumbra commented Mar 5, 2021

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)

@David-OConnor
Copy link
Contributor

David-OConnor commented Mar 5, 2021

Note that center align modes will also cause incorrect freqs.

@Sh3Rm4n Sh3Rm4n added the bug Something isn't working label Mar 5, 2021
@Sh3Rm4n
Copy link
Member

Sh3Rm4n commented Mar 5, 2021

I have not had the time to dig into the PWM issues / PRs yet, but can this possible resolved or improved by #196?

@Piroro-hs
Copy link
Contributor

Piroro-hs commented Mar 14, 2021

Looks like current PWM and Timer implementation is wrong at source clock calculation.

stm32f3xx-hal/src/pwm.rs

Lines 283 to 284 in f8eb292

// TODO: ppre1 is used in timer.rs (never ppre2), should this be dynamic?
let clock_freq = clocks.$pclkz().0 * if clocks.ppre1() == 1 { 1 } else { 2 };

@David-OConnor
Copy link
Contributor

David-OConnor commented Mar 14, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants