From 7dad187ff740a0a1940d2d503fbc373218f4bd01 Mon Sep 17 00:00:00 2001 From: Jakob Date: Wed, 6 Aug 2025 10:46:21 +0200 Subject: Add methods for setting ossi, ossr, osi and oisn along with software trigger for break input --- embassy-stm32/src/timer/complementary_pwm.rs | 45 +++++++++++++++++++++++++++- embassy-stm32/src/timer/low_level.rs | 25 ++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) (limited to 'embassy-stm32/src') diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index b00cc18ad..1178e7d83 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -2,7 +2,7 @@ use core::marker::PhantomData; -use stm32_metapac::timer::vals::Ckd; +pub use stm32_metapac::timer::vals::{Ckd, Ossi, Ossr}; use super::low_level::{CountingMode, OutputPolarity, Timer}; use super::simple_pwm::PwmPin; @@ -82,6 +82,49 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { this } + /// Set output idle state for all channels + /// - `output_high_when_idle` - true if the output for the normal channels should + /// be high when idle, which means that the complementary channels are low. Opposite + /// for `false`. + pub fn set_output_idle_state(&self, output_high_when_idle: bool) { + [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] + .iter() + .for_each(|&channel| { + self.inner.set_ois(channel, output_high_when_idle); + self.inner.set_oisn(channel, !output_high_when_idle); + }); + } + + /// Set state of OSSI-bit in BDTR register + pub fn set_off_state_selection_idle(&self, val: Ossi) { + self.inner.set_ossi(val); + } + + /// Set state of OSSR-bit in BDTR register + pub fn set_off_state_selection_run(&self, val: Ossr) { + self.inner.set_ossr(val); + } + + /// Trigger break input from software + pub fn trigger_software_break(&self, n: usize) { + self.inner.trigger_software_break(n); + } + + /// Set Master Output Enable + pub fn set_master_output_enable(&mut self, enable: bool) { + self.inner.set_moe(enable); + } + + /// Set Master Slave Mode 2 + pub fn set_mms2(&mut self, mms2: Mms2) { + self.inner.set_mms2_selection(mms2); + } + + /// Set Repetition Counter + pub fn set_repetition_counter(&mut self, val: u16) { + self.inner.set_repetition_counter(val); + } + /// Enable the given channel. pub fn enable(&mut self, channel: Channel) { self.inner.enable_channel(channel, true); diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index dc8ceb725..01bf60869 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs @@ -686,6 +686,16 @@ impl<'d, T: AdvancedInstance1Channel> Timer<'d, T> { self.regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); } + /// Set state of OSSI-bit in BDTR register + pub fn set_ossi(&self, val: vals::Ossi) { + self.regs_1ch_cmp().bdtr().modify(|w| w.set_ossi(val)); + } + + /// Set state of OSSR-bit in BDTR register + pub fn set_ossr(&self, val: vals::Ossr) { + self.regs_1ch_cmp().bdtr().modify(|w| w.set_ossr(val)); + } + /// Set state of MOE-bit in BDTR register to en-/disable output pub fn set_moe(&self, enable: bool) { self.regs_1ch_cmp().bdtr().modify(|w| w.set_moe(enable)); @@ -725,4 +735,19 @@ impl<'d, T: AdvancedInstance4Channel> Timer<'d, T> { .ccer() .modify(|w| w.set_ccne(channel.index(), enable)); } + + /// Set Output Idle State + pub fn set_ois(&self, channel: Channel, val: bool) { + self.regs_advanced().cr2().modify(|w| w.set_ois(channel.index(), val)); + } + /// Set Output Idle State Complementary Channel + pub fn set_oisn(&self, channel: Channel, val: bool) { + self.regs_advanced().cr2().modify(|w| w.set_oisn(channel.index(), val)); + } + + /// Trigger software break 1 or 2 + /// Setting this bit generates a break event. This bit is automatically cleared by the hardware. + pub fn trigger_software_break(&self, n: usize) { + self.regs_advanced().egr().write(|r| r.set_bg(n, true)); + } } -- cgit