aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-04-04 19:35:25 -0500
committerxoviat <[email protected]>2023-04-04 19:35:25 -0500
commit991b22b6a1e845dc15eca72bf9881e60f1803840 (patch)
treedfbd251d3ffe42139ccd52c412fd1f065352916f
parent064ec9581e33fdd42f89ff75984254ccfec3f6c2 (diff)
stm32/pwm: add complementary pwm
-rw-r--r--embassy-stm32/src/pwm/complementary_pwm.rs145
-rw-r--r--embassy-stm32/src/pwm/mod.rs22
2 files changed, 167 insertions, 0 deletions
diff --git a/embassy-stm32/src/pwm/complementary_pwm.rs b/embassy-stm32/src/pwm/complementary_pwm.rs
new file mode 100644
index 000000000..b8761724a
--- /dev/null
+++ b/embassy-stm32/src/pwm/complementary_pwm.rs
@@ -0,0 +1,145 @@
1use core::marker::PhantomData;
2
3use embassy_hal_common::{into_ref, PeripheralRef};
4
5use super::*;
6#[allow(unused_imports)]
7use crate::gpio::sealed::{AFType, Pin};
8use crate::gpio::AnyPin;
9use crate::time::Hertz;
10use crate::Peripheral;
11
12pub struct Ch1;
13pub struct Ch2;
14pub struct Ch3;
15pub struct Ch4;
16
17pub struct PwmPin<'d, Perip, Channel> {
18 _pin: PeripheralRef<'d, AnyPin>,
19 phantom: PhantomData<(Perip, Channel)>,
20}
21
22pub struct ComplementaryPwmPin<'d, Perip, Channel> {
23 _pin: PeripheralRef<'d, AnyPin>,
24 phantom: PhantomData<(Perip, Channel)>,
25}
26
27macro_rules! channel_impl {
28 ($new_chx:ident, $channel:ident, $pin_trait:ident, $complementary_pin_trait:ident) => {
29 impl<'d, Perip: CaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> {
30 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd) -> Self {
31 into_ref!(pin);
32 critical_section::with(|_| unsafe {
33 pin.set_low();
34 pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
35 #[cfg(gpio_v2)]
36 pin.set_speed(crate::gpio::Speed::VeryHigh);
37 });
38 PwmPin {
39 _pin: pin.map_into(),
40 phantom: PhantomData,
41 }
42 }
43 }
44
45 impl<'d, Perip: CaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel> {
46 pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self {
47 into_ref!(pin);
48 critical_section::with(|_| unsafe {
49 pin.set_low();
50 pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
51 #[cfg(gpio_v2)]
52 pin.set_speed(crate::gpio::Speed::VeryHigh);
53 });
54 ComplementaryPwmPin {
55 _pin: pin.map_into(),
56 phantom: PhantomData,
57 }
58 }
59 }
60 };
61}
62
63channel_impl!(new_ch1, Ch1, Channel1Pin, Channel1ComplementaryPin);
64channel_impl!(new_ch2, Ch2, Channel2Pin, Channel2ComplementaryPin);
65channel_impl!(new_ch3, Ch3, Channel3Pin, Channel3ComplementaryPin);
66channel_impl!(new_ch4, Ch4, Channel4Pin, Channel4ComplementaryPin);
67
68pub struct ComplementaryPwm<'d, T> {
69 inner: PeripheralRef<'d, T>,
70}
71
72impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> {
73 pub fn new(
74 tim: impl Peripheral<P = T> + 'd,
75 _ch1: Option<PwmPin<'d, T, Ch1>>,
76 _ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>,
77 _ch2: Option<PwmPin<'d, T, Ch2>>,
78 _ch2n: Option<ComplementaryPwmPin<'d, T, Ch2>>,
79 _ch3: Option<PwmPin<'d, T, Ch3>>,
80 _ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>,
81 _ch4: Option<PwmPin<'d, T, Ch4>>,
82 _ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>,
83 freq: Hertz,
84 ) -> Self {
85 Self::new_inner(tim, freq)
86 }
87
88 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz) -> Self {
89 into_ref!(tim);
90
91 T::enable();
92 <T as crate::rcc::sealed::RccPeripheral>::reset();
93
94 let mut this = Self { inner: tim };
95
96 this.inner.set_frequency(freq);
97 this.inner.start();
98
99 unsafe {
100 this.inner.enable_outputs(true);
101
102 this.inner
103 .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1);
104 this.inner
105 .set_output_compare_mode(Channel::Ch2, OutputCompareMode::PwmMode1);
106 this.inner
107 .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1);
108 this.inner
109 .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1);
110 }
111 this
112 }
113
114 pub fn enable(&mut self, channel: Channel) {
115 unsafe {
116 self.inner.enable_channel(channel, true);
117 }
118 }
119
120 pub fn disable(&mut self, channel: Channel) {
121 unsafe {
122 self.inner.enable_channel(channel, false);
123 }
124 }
125
126 pub fn set_freq(&mut self, freq: Hertz) {
127 self.inner.set_frequency(freq);
128 }
129
130 pub fn get_max_duty(&self) -> u16 {
131 unsafe { self.inner.get_max_compare_value() }
132 }
133
134 pub fn set_duty(&mut self, channel: Channel, duty: u16) {
135 assert!(duty < self.get_max_duty());
136 unsafe { self.inner.set_compare_value(channel, duty) }
137 }
138
139 /*
140 set the value of the dead-time register
141 */
142 pub fn set_dead_time_value(&mut self, value: u8) {
143 unsafe { self.inner.set_dead_time_value(value) }
144 }
145}
diff --git a/embassy-stm32/src/pwm/mod.rs b/embassy-stm32/src/pwm/mod.rs
index d3713391c..6f3c12665 100644
--- a/embassy-stm32/src/pwm/mod.rs
+++ b/embassy-stm32/src/pwm/mod.rs
@@ -1,3 +1,4 @@
1pub mod complementary_pwm;
1pub mod simple_pwm; 2pub mod simple_pwm;
2 3
3#[cfg(feature = "unstable-pac")] 4#[cfg(feature = "unstable-pac")]
@@ -67,6 +68,10 @@ pub(crate) mod sealed {
67 unsafe fn get_max_compare_value(&self) -> u16; 68 unsafe fn get_max_compare_value(&self) -> u16;
68 } 69 }
69 70
71 pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance {
72 unsafe fn set_dead_time_value(&mut self, value: u8);
73 }
74
70 pub trait CaptureCompare32bitInstance: crate::timer::sealed::GeneralPurpose32bitInstance { 75 pub trait CaptureCompare32bitInstance: crate::timer::sealed::GeneralPurpose32bitInstance {
71 unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); 76 unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
72 77
@@ -82,6 +87,12 @@ pub trait CaptureCompare16bitInstance:
82 sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static 87 sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static
83{ 88{
84} 89}
90
91pub trait ComplementaryCaptureCompare16bitInstance:
92 sealed::ComplementaryCaptureCompare16bitInstance + crate::timer::AdvancedControlInstance + 'static
93{
94}
95
85pub trait CaptureCompare32bitInstance: 96pub trait CaptureCompare32bitInstance:
86 sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + crate::timer::GeneralPurpose32bitInstance + 'static 97 sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + crate::timer::GeneralPurpose32bitInstance + 'static
87{ 98{
@@ -209,6 +220,17 @@ foreach_interrupt! {
209 impl CaptureCompare16bitInstance for crate::peripherals::$inst { 220 impl CaptureCompare16bitInstance for crate::peripherals::$inst {
210 221
211 } 222 }
223
224 impl crate::pwm::sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {
225 unsafe fn set_dead_time_value(&mut self, value: u8) {
226 use crate::timer::sealed::AdvancedControlInstance;
227 Self::regs_advanced().bdtr().modify(|w| w.set_dtg(value));
228 }
229 }
230
231 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {
232
233 }
212 }; 234 };
213} 235}
214 236