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());
+ }
+}