embassy icon indicating copy to clipboard operation
embassy copied to clipboard

STM32F072 TIM15 PWM not working (MOE bit)

Open martin2250 opened this issue 1 year ago • 3 comments

The following code should enable the PWM output on pin PA2:

    let output_green = PwmPin::new_ch1(p.PA2, OutputType::PushPull);
    let mut pwm_green = SimplePwm::new(
        p.TIM15,
        Some(output_green),
        None,
        None,
        None,
        khz(1),
        Default::default(),
    );
    pwm_green.enable(Channel::Ch1);
    pwm_green.set_duty(Channel::Ch1, 10);

However, the pin stays in high impedance mode. Looking around I found other people having the same issue and the suggested fix was setting the "master output enable" (MOE) bit in the BDTR register. The following code makes the PWM output work properly on my hardware:

    const TIM15A: embassy_stm32::pac::timer::TimAdv =
        unsafe { embassy_stm32::pac::timer::TimAdv::from_ptr(0x4001_4000 as usize as _) };
    TIM15A.bdtr().modify(|r| r.set_moe(true))

TIM15 is declared here as TimGp16, which does not have the BDTR register. I'm not sure, however, if is correctly described by TimAdv. Also, other chips are probably affected by this issue as well.

Cheers!

martin2250 avatar Jan 06 '24 14:01 martin2250

Same issue here with STM32G030C8 TIM16 and TIM17. Setting MOE bit works.

phycrax avatar Jan 29 '24 15:01 phycrax

This is also the case for TIM15, TIM16 and TIM17 for STM32F030x4/x6/x8/xC and STM32F070x6/xB. I would love to help here but am relatively new to this ecosystem. I guess we need some timer type between general and advanced timers?

nbars avatar Feb 06 '24 19:02 nbars

I have a similar problem in my project, that the PWM does not output any signal after updating Embassy.

There used to be a this.inner.enable_outputs(); in SimplePwm::new_inner(), which got removed by PR #2499. https://github.com/embassy-rs/embassy/pull/2499/files#diff-34e412deccc6f88af9fce995f7c4ef7fc8ce6502ea2df991b562ab205be4a93eL87

Just inserting it again, does not work, because it was also moved to trait GeneralPurpose1ChannelComplementaryInstance, which is not used by SimplePwm. https://github.com/embassy-rs/embassy/pull/2499/files#diff-d61a69bd589d81e3a1aea8bcddd14f22ce2dcba46d2edbf7fc0adb4722f5e4d0R437-R439

My current approach is to move enable_outputs() back to trait CaptureCompare16bitInstance which is a noop for most of the timers and use it in SimplePwm. ~https://github.com/embassy-rs/embassy/compare/main...jr-oss:embassy:fix_regression_simple_pwm_output_enable~ Edit: See PR #2670

But I haven't understood the timer hierarchy introduced by PR #2499 to be sure, that this is the right solution. Any feedback is appreciated.

BTW: The output enable seems to be fragile, as I already provided a similar fix in PR #2053

jr-oss avatar Mar 01 '24 17:03 jr-oss

My changes have been merged to main (PR #2670). Does this solve also your problem?

jr-oss avatar Mar 08 '24 13:03 jr-oss

This should now be fixed for all timers/chips after the last timer refactor and fixes in the above linked PRs.

If you find a timer that doesn't work due to this please open a new issue.

Dirbaio avatar May 29 '24 09:05 Dirbaio