From b7bb4b23f8e59e90cff4773cc1e93e493d72ae56 Mon Sep 17 00:00:00 2001 From: Ralf <jr-oss@gmx.net> Date: Fri, 1 Mar 2024 13:50:14 +0100 Subject: [PATCH] STM32 SimplePwm: Fix regression and re-enable output pin PR #2499 implemented timer hierarchy, but removed enable_outputs() from trait CaptureCompare16bitInstance and from SimplePwm. This functions is required for advanced timers to set bit BDTR.MOE and to enable the output signal. --- embassy-stm32/src/timer/mod.rs | 37 ++++++++++++++++++++++----- embassy-stm32/src/timer/simple_pwm.rs | 1 + 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 8530c5229..ef893c7f5 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -439,9 +439,9 @@ pub(crate) mod sealed { Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); } - /// Enable timer outputs. - fn enable_outputs(&self) { - Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); + /// Set state of MOE-bit in BDTR register to en-/disable output + fn set_moe(&self, enable: bool) { + Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(enable)); } } @@ -685,6 +685,13 @@ pub trait CaptureCompare16bitInstance: + sealed::GeneralPurpose16bitInstance + 'static { + // SimplePwm<'d, T> is implemented for T: CaptureCompare16bitInstance + // Advanced timers implement this trait, but the output needs to be + // enabled explicitly. + // To support general-purpose and advanced timers, this function is added + // here defaulting to noop and overwritten for advanced timers. + /// Enable timer outputs. + fn enable_outputs(&self) {} } #[cfg(not(stm32l0))] @@ -911,7 +918,13 @@ foreach_interrupt! { impl_1ch_cmp_timer!($inst); impl_2ch_cmp_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst { + /// Enable timer outputs. + fn enable_outputs(&self) { + use crate::timer::sealed::GeneralPurpose1ChannelComplementaryInstance; + self.set_moe(true); + } + } impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_1CH_CMP, CC, $irq:ident) => { @@ -929,7 +942,13 @@ foreach_interrupt! { impl_1ch_cmp_timer!($inst); impl_2ch_cmp_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst { + /// Enable timer outputs. + fn enable_outputs(&self) { + use crate::timer::sealed::GeneralPurpose1ChannelComplementaryInstance; + self.set_moe(true); + } + } impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_2CH_CMP, CC, $irq:ident) => { @@ -947,7 +966,13 @@ foreach_interrupt! { impl_1ch_cmp_timer!($inst); impl_2ch_cmp_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} - impl CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl CaptureCompare16bitInstance for crate::peripherals::$inst { + /// Enable timer outputs. + fn enable_outputs(&self) { + use crate::timer::sealed::GeneralPurpose1ChannelComplementaryInstance; + self.set_moe(true); + } + } impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; ($inst:ident, timer, TIM_ADV, CC, $irq:ident) => { diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 1acba504e..6df2f66ec 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -82,6 +82,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { this.inner.set_counting_mode(counting_mode); this.set_frequency(freq); + this.inner.enable_outputs(); // Required for advanced timers, see CaptureCompare16bitInstance for details this.inner.start(); [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4]