aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2025-08-12 19:27:28 +0200
committerGitHub <[email protected]>2025-08-12 19:27:28 +0200
commite2921be35cb2d02b7cc25605c4a1cfed090a13cb (patch)
treed907d4bcb6d2e8918179b6fabefc66d3405df33c /embassy-stm32
parent1f57e2130a123a2e36cea25a3fc8c5b660313f47 (diff)
parentc228ffe666c4354c909ea454cebc14387930c9c0 (diff)
Merge pull request #4522 from WattStep/complementary_pwm_idle_state
Add methods for idle-state control in STM32 Complementary PWM
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs55
-rw-r--r--embassy-stm32/src/timer/low_level.rs40
2 files changed, 94 insertions, 1 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index b00cc18ad..b291fc155 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -2,7 +2,7 @@
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5use stm32_metapac::timer::vals::Ckd; 5pub use stm32_metapac::timer::vals::{Ckd, Ossi, Ossr};
6 6
7use super::low_level::{CountingMode, OutputPolarity, Timer}; 7use super::low_level::{CountingMode, OutputPolarity, Timer};
8use super::simple_pwm::PwmPin; 8use super::simple_pwm::PwmPin;
@@ -43,6 +43,15 @@ pub struct ComplementaryPwm<'d, T: AdvancedInstance4Channel> {
43 inner: Timer<'d, T>, 43 inner: Timer<'d, T>,
44} 44}
45 45
46#[derive(Copy, Clone, Debug, PartialEq, Eq)]
47/// Determines which outputs are active when PWM is in idle mode
48pub enum IdlePolarity {
49 /// Normal channels are forced active and complementary channels are forced inactive
50 OisActive,
51 /// Normal channels are forced inactive and complementary channels are forced active
52 OisnActive,
53}
54
46impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { 55impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
47 /// Create a new complementary PWM driver. 56 /// Create a new complementary PWM driver.
48 #[allow(clippy::too_many_arguments)] 57 #[allow(clippy::too_many_arguments)]
@@ -82,6 +91,50 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
82 this 91 this
83 } 92 }
84 93
94 /// Sets the idle output state for the given channels.
95 pub fn set_output_idle_state(&mut self, channels: &[Channel], polarity: IdlePolarity) {
96 let ois_active = matches!(polarity, IdlePolarity::OisActive);
97 for &channel in channels {
98 self.inner.set_ois(channel, ois_active);
99 self.inner.set_oisn(channel, !ois_active);
100 }
101 }
102
103 /// Set state of OSSI-bit in BDTR register
104 pub fn set_off_state_selection_idle(&mut self, val: Ossi) {
105 self.inner.set_ossi(val);
106 }
107
108 /// Get state of OSSI-bit in BDTR register
109 pub fn get_off_state_selection_idle(&self) -> Ossi {
110 self.inner.get_ossi()
111 }
112
113 /// Set state of OSSR-bit in BDTR register
114 pub fn set_off_state_selection_run(&mut self, val: Ossr) {
115 self.inner.set_ossr(val);
116 }
117
118 /// Get state of OSSR-bit in BDTR register
119 pub fn get_off_state_selection_run(&self) -> Ossr {
120 self.inner.get_ossr()
121 }
122
123 /// Trigger break input from software
124 pub fn trigger_software_break(&mut self, n: usize) {
125 self.inner.trigger_software_break(n);
126 }
127
128 /// Set Master Output Enable
129 pub fn set_master_output_enable(&mut self, enable: bool) {
130 self.inner.set_moe(enable);
131 }
132
133 /// Get Master Output Enable
134 pub fn get_master_output_enable(&self) -> bool {
135 self.inner.get_moe()
136 }
137
85 /// Enable the given channel. 138 /// Enable the given channel.
86 pub fn enable(&mut self, channel: Channel) { 139 pub fn enable(&mut self, channel: Channel) {
87 self.inner.enable_channel(channel, true); 140 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..ac039bb0d 100644
--- a/embassy-stm32/src/timer/low_level.rs
+++ b/embassy-stm32/src/timer/low_level.rs
@@ -686,10 +686,35 @@ impl<'d, T: AdvancedInstance1Channel> Timer<'d, T> {
686 self.regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); 686 self.regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value));
687 } 687 }
688 688
689 /// Set state of OSSI-bit in BDTR register
690 pub fn set_ossi(&self, val: vals::Ossi) {
691 self.regs_1ch_cmp().bdtr().modify(|w| w.set_ossi(val));
692 }
693
694 /// Get state of OSSI-bit in BDTR register
695 pub fn get_ossi(&self) -> vals::Ossi {
696 self.regs_1ch_cmp().bdtr().read().ossi()
697 }
698
699 /// Set state of OSSR-bit in BDTR register
700 pub fn set_ossr(&self, val: vals::Ossr) {
701 self.regs_1ch_cmp().bdtr().modify(|w| w.set_ossr(val));
702 }
703
704 /// Get state of OSSR-bit in BDTR register
705 pub fn get_ossr(&self) -> vals::Ossr {
706 self.regs_1ch_cmp().bdtr().read().ossr()
707 }
708
689 /// Set state of MOE-bit in BDTR register to en-/disable output 709 /// Set state of MOE-bit in BDTR register to en-/disable output
690 pub fn set_moe(&self, enable: bool) { 710 pub fn set_moe(&self, enable: bool) {
691 self.regs_1ch_cmp().bdtr().modify(|w| w.set_moe(enable)); 711 self.regs_1ch_cmp().bdtr().modify(|w| w.set_moe(enable));
692 } 712 }
713
714 /// Get state of MOE-bit in BDTR register
715 pub fn get_moe(&self) -> bool {
716 self.regs_1ch_cmp().bdtr().read().moe()
717 }
693} 718}
694 719
695#[cfg(not(stm32l0))] 720#[cfg(not(stm32l0))]
@@ -725,4 +750,19 @@ impl<'d, T: AdvancedInstance4Channel> Timer<'d, T> {
725 .ccer() 750 .ccer()
726 .modify(|w| w.set_ccne(channel.index(), enable)); 751 .modify(|w| w.set_ccne(channel.index(), enable));
727 } 752 }
753
754 /// Set Output Idle State
755 pub fn set_ois(&self, channel: Channel, val: bool) {
756 self.regs_advanced().cr2().modify(|w| w.set_ois(channel.index(), val));
757 }
758 /// Set Output Idle State Complementary Channel
759 pub fn set_oisn(&self, channel: Channel, val: bool) {
760 self.regs_advanced().cr2().modify(|w| w.set_oisn(channel.index(), val));
761 }
762
763 /// Trigger software break 1 or 2
764 /// Setting this bit generates a break event. This bit is automatically cleared by the hardware.
765 pub fn trigger_software_break(&self, n: usize) {
766 self.regs_advanced().egr().write(|r| r.set_bg(n, true));
767 }
728} 768}