From 2ea17d27836d98f55659e23502c91a33e2c06d29 Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Fri, 18 Aug 2023 16:37:44 +0200 Subject: [PATCH] stm32: allow setting the PWM output polarity --- embassy-stm32/src/timer/complementary_pwm.rs | 5 ++ embassy-stm32/src/timer/mod.rs | 49 ++++++++++++++++++++ embassy-stm32/src/timer/simple_pwm.rs | 4 ++ 3 files changed, 58 insertions(+) diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 533267cf..4f033e3a 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -108,6 +108,11 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { self.inner.set_compare_value(channel, duty) } + pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + self.inner.set_output_polarity(channel, polarity); + self.inner.set_complementary_output_polarity(channel, polarity); + } + /// Set the dead time as a proportion of max_duty pub fn set_dead_time(&mut self, value: u16) { let (ckd, value) = compute_dead_time_value(value); diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 6c2d6d82..4ffb2a28 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -53,6 +53,8 @@ pub(crate) mod sealed { fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); + fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity); + fn enable_channel(&mut self, channel: Channel, enable: bool); fn set_compare_value(&mut self, channel: Channel, value: u16); @@ -61,6 +63,8 @@ pub(crate) mod sealed { } pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance { + fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity); + fn set_dead_time_clock_division(&mut self, value: vals::Ckd); fn set_dead_time_value(&mut self, value: u8); @@ -71,6 +75,8 @@ pub(crate) mod sealed { pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance { fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); + fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity); + fn enable_channel(&mut self, channel: Channel, enable: bool); fn set_compare_value(&mut self, channel: Channel, value: u32); @@ -125,6 +131,21 @@ impl From for stm32_metapac::timer::vals::Ocm { } } +#[derive(Clone, Copy)] +pub enum OutputPolarity { + ActiveHigh, + ActiveLow, +} + +impl From for bool { + fn from(mode: OutputPolarity) -> Self { + match mode { + OutputPolarity::ActiveHigh => false, + OutputPolarity::ActiveLow => true, + } + } +} + pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {} @@ -265,6 +286,13 @@ macro_rules! impl_compare_capable_16bit { .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); } + fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + use sealed::GeneralPurpose16bitInstance; + Self::regs_gp16() + .ccer() + .modify(|w| w.set_ccp(channel.raw(), polarity.into())); + } + fn enable_channel(&mut self, channel: Channel, enable: bool) { use sealed::GeneralPurpose16bitInstance; Self::regs_gp16() @@ -325,6 +353,13 @@ foreach_interrupt! { Self::regs_gp32().ccmr_output(raw_channel / 2).modify(|w| w.set_ocm(raw_channel % 2, mode.into())); } + fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + use crate::timer::sealed::GeneralPurpose32bitInstance; + Self::regs_gp32() + .ccer() + .modify(|w| w.set_ccp(channel.raw(), polarity.into())); + } + fn enable_channel(&mut self, channel: Channel, enable: bool) { use crate::timer::sealed::GeneralPurpose32bitInstance; Self::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), enable)); @@ -388,6 +423,13 @@ foreach_interrupt! { .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); } + fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + use crate::timer::sealed::AdvancedControlInstance; + Self::regs_advanced() + .ccer() + .modify(|w| w.set_ccp(channel.raw(), polarity.into())); + } + fn enable_channel(&mut self, channel: Channel, enable: bool) { use crate::timer::sealed::AdvancedControlInstance; Self::regs_advanced() @@ -409,6 +451,13 @@ foreach_interrupt! { } impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst { + fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + use crate::timer::sealed::AdvancedControlInstance; + Self::regs_advanced() + .ccer() + .modify(|w| w.set_ccnp(channel.raw(), polarity.into())); + } + fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { use crate::timer::sealed::AdvancedControlInstance; Self::regs_advanced().cr1().modify(|w| w.set_ckd(value)); diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 40e3dd1b..9e28878b 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -104,4 +104,8 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { assert!(duty <= self.get_max_duty()); self.inner.set_compare_value(channel, duty) } + + pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { + self.inner.set_output_polarity(channel, polarity); + } }