diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 4f033e3a..0ab72734 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -122,6 +122,46 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { } } +impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { + type Channel = Channel; + type Time = Hertz; + type Duty = u16; + + fn disable(&mut self, channel: Self::Channel) { + self.inner.enable_complementary_channel(channel, false); + self.inner.enable_channel(channel, false); + } + + fn enable(&mut self, channel: Self::Channel) { + self.inner.enable_channel(channel, true); + self.inner.enable_complementary_channel(channel, true); + } + + fn get_period(&self) -> Self::Time { + self.inner.get_frequency().into() + } + + fn get_duty(&self, channel: Self::Channel) -> Self::Duty { + self.inner.get_compare_value(channel) + } + + fn get_max_duty(&self) -> Self::Duty { + self.inner.get_max_compare_value() + 1 + } + + fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { + assert!(duty <= self.get_max_duty()); + self.inner.set_compare_value(channel, duty) + } + + fn set_period

(&mut self, period: P) + where + P: Into, + { + self.inner.set_frequency(period.into()); + } +} + fn compute_dead_time_value(value: u16) -> (Ckd, u8) { /* Dead-time = T_clk * T_dts * T_dtg diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index d88fbcfd..1e0999ed 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -70,6 +70,16 @@ pub(crate) mod sealed { fn set_autoreload_preload(&mut self, enable: vals::Arpe) { Self::regs().cr1().modify(|r| r.set_arpe(enable)); } + + fn get_frequency(&self) -> Hertz { + let timer_f = Self::frequency(); + + let regs = Self::regs(); + let arr = regs.arr().read().arr(); + let psc = regs.psc().read().psc(); + + timer_f / arr / (psc + 1) + } } pub trait GeneralPurpose16bitInstance: Basic16bitInstance { @@ -103,6 +113,16 @@ pub(crate) mod sealed { regs.egr().write(|r| r.set_ug(true)); regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT)); } + + fn get_frequency(&self) -> Hertz { + let timer_f = Self::frequency(); + + let regs = Self::regs_gp32(); + let arr = regs.arr().read().arr(); + let psc = regs.psc().read().psc(); + + timer_f / arr / (psc + 1) + } } pub trait AdvancedControlInstance: GeneralPurpose16bitInstance { @@ -183,6 +203,10 @@ pub(crate) mod sealed { fn get_max_compare_value(&self) -> u16 { Self::regs_gp16().arr().read().arr() } + + fn get_compare_value(&self, channel: Channel) -> u16 { + Self::regs_gp16().ccr(channel.raw()).read().ccr() + } } pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance + AdvancedControlInstance { @@ -219,6 +243,10 @@ pub(crate) mod sealed { fn get_max_compare_value(&self) -> u32 { Self::regs_gp32().arr().read().arr() } + + fn get_compare_value(&self, channel: Channel) -> u32 { + Self::regs_gp32().ccr(channel.raw()).read().ccr() + } } } diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 9e28878b..2b3a069a 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -109,3 +109,41 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { self.inner.set_output_polarity(channel, polarity); } } + +impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { + type Channel = Channel; + type Time = Hertz; + type Duty = u16; + + fn disable(&mut self, channel: Self::Channel) { + self.inner.enable_channel(channel, false); + } + + fn enable(&mut self, channel: Self::Channel) { + self.inner.enable_channel(channel, true); + } + + fn get_period(&self) -> Self::Time { + self.inner.get_frequency().into() + } + + fn get_duty(&self, channel: Self::Channel) -> Self::Duty { + self.inner.get_compare_value(channel) + } + + fn get_max_duty(&self) -> Self::Duty { + self.inner.get_max_compare_value() + 1 + } + + fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { + assert!(duty <= self.get_max_duty()); + self.inner.set_compare_value(channel, duty) + } + + fn set_period

(&mut self, period: P) + where + P: Into, + { + self.inner.set_frequency(period.into()); + } +}