aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs41
-rw-r--r--embassy-stm32/src/timer/mod.rs521
-rw-r--r--embassy-stm32/src/timer/qei.rs4
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs39
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs4
5 files changed, 272 insertions, 337 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index b9cd044c9..72f1ec864 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -1,7 +1,6 @@
1//! PWM driver with complementary output support. 1//! PWM driver with complementary output support.
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::ops::{Deref, DerefMut};
5 4
6use embassy_hal_internal::{into_ref, PeripheralRef}; 5use embassy_hal_internal::{into_ref, PeripheralRef};
7use stm32_metapac::timer::vals::Ckd; 6use stm32_metapac::timer::vals::Ckd;
@@ -24,7 +23,7 @@ pub struct ComplementaryPwmPin<'d, T, C> {
24 23
25macro_rules! complementary_channel_impl { 24macro_rules! complementary_channel_impl {
26 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 25 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
27 impl<'d, T: AdvancedControlInstance> ComplementaryPwmPin<'d, T, $channel> { 26 impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwmPin<'d, T, $channel> {
28 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] 27 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")]
29 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { 28 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self {
30 into_ref!(pin); 29 into_ref!(pin);
@@ -53,7 +52,7 @@ pub struct ComplementaryPwm<'d, T> {
53 inner: PeripheralRef<'d, T>, 52 inner: PeripheralRef<'d, T>,
54} 53}
55 54
56impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> { 55impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> {
57 /// Create a new complementary PWM driver. 56 /// Create a new complementary PWM driver.
58 #[allow(clippy::too_many_arguments)] 57 #[allow(clippy::too_many_arguments)]
59 pub fn new( 58 pub fn new(
@@ -88,12 +87,8 @@ impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> {
88 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] 87 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4]
89 .iter() 88 .iter()
90 .for_each(|&channel| { 89 .for_each(|&channel| {
91 sealed::GeneralPurpose16bitInstance::set_output_compare_mode( 90 this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1);
92 this.inner.deref_mut(), 91 this.inner.set_output_compare_preload(channel, true);
93 channel,
94 OutputCompareMode::PwmMode1,
95 );
96 sealed::GeneralPurpose16bitInstance::set_output_compare_preload(this.inner.deref_mut(), channel, true);
97 }); 92 });
98 93
99 this 94 this
@@ -101,14 +96,14 @@ impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> {
101 96
102 /// Enable the given channel. 97 /// Enable the given channel.
103 pub fn enable(&mut self, channel: Channel) { 98 pub fn enable(&mut self, channel: Channel) {
104 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); 99 self.inner.enable_channel(channel, true);
105 sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, true); 100 self.inner.enable_complementary_channel(channel, true);
106 } 101 }
107 102
108 /// Disable the given channel. 103 /// Disable the given channel.
109 pub fn disable(&mut self, channel: Channel) { 104 pub fn disable(&mut self, channel: Channel) {
110 sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, false); 105 self.inner.enable_complementary_channel(channel, false);
111 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); 106 self.inner.enable_channel(channel, false);
112 } 107 }
113 108
114 /// Set PWM frequency. 109 /// Set PWM frequency.
@@ -136,13 +131,13 @@ impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> {
136 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 131 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
137 pub fn set_duty(&mut self, channel: Channel, duty: u16) { 132 pub fn set_duty(&mut self, channel: Channel, duty: u16) {
138 assert!(duty <= self.get_max_duty()); 133 assert!(duty <= self.get_max_duty());
139 sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) 134 self.inner.set_compare_value(channel, duty)
140 } 135 }
141 136
142 /// Set the output polarity for a given channel. 137 /// Set the output polarity for a given channel.
143 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { 138 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
144 sealed::GeneralPurpose16bitInstance::set_output_polarity(self.inner.deref_mut(), channel, polarity); 139 self.inner.set_output_polarity(channel, polarity);
145 sealed::AdvancedControlInstance::set_complementary_output_polarity(self.inner.deref_mut(), channel, polarity); 140 self.inner.set_complementary_output_polarity(channel, polarity);
146 } 141 }
147 142
148 /// Set the dead time as a proportion of max_duty 143 /// Set the dead time as a proportion of max_duty
@@ -154,19 +149,19 @@ impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> {
154 } 149 }
155} 150}
156 151
157impl<'d, T: AdvancedControlInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { 152impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> {
158 type Channel = Channel; 153 type Channel = Channel;
159 type Time = Hertz; 154 type Time = Hertz;
160 type Duty = u16; 155 type Duty = u16;
161 156
162 fn disable(&mut self, channel: Self::Channel) { 157 fn disable(&mut self, channel: Self::Channel) {
163 sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, false); 158 self.inner.enable_complementary_channel(channel, false);
164 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); 159 self.inner.enable_channel(channel, false);
165 } 160 }
166 161
167 fn enable(&mut self, channel: Self::Channel) { 162 fn enable(&mut self, channel: Self::Channel) {
168 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); 163 self.inner.enable_channel(channel, true);
169 sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, true); 164 self.inner.enable_complementary_channel(channel, true);
170 } 165 }
171 166
172 fn get_period(&self) -> Self::Time { 167 fn get_period(&self) -> Self::Time {
@@ -174,7 +169,7 @@ impl<'d, T: AdvancedControlInstance> embedded_hal_02::Pwm for ComplementaryPwm<'
174 } 169 }
175 170
176 fn get_duty(&self, channel: Self::Channel) -> Self::Duty { 171 fn get_duty(&self, channel: Self::Channel) -> Self::Duty {
177 sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) 172 self.inner.get_compare_value(channel)
178 } 173 }
179 174
180 fn get_max_duty(&self) -> Self::Duty { 175 fn get_max_duty(&self) -> Self::Duty {
@@ -183,7 +178,7 @@ impl<'d, T: AdvancedControlInstance> embedded_hal_02::Pwm for ComplementaryPwm<'
183 178
184 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { 179 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) {
185 assert!(duty <= self.get_max_duty()); 180 assert!(duty <= self.get_max_duty());
186 sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) 181 self.inner.set_compare_value(channel, duty)
187 } 182 }
188 183
189 fn set_period<P>(&mut self, period: P) 184 fn set_period<P>(&mut self, period: P)
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs
index 3e303a6cf..5f40be957 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -1,6 +1,8 @@
1//! Timers, PWM, quadrature decoder. 1//! Timers, PWM, quadrature decoder.
2 2
3// Timer inheritance 3//! Timer inheritance
4
5// sealed:
4// 6//
5// Core -------------------------> 1CH -------------------------> 1CH_CMP 7// Core -------------------------> 1CH -------------------------> 1CH_CMP
6// | | ^ | 8// | | ^ |
@@ -12,7 +14,18 @@
12// | +--------------------------------------|-----------+ 14// | +--------------------------------------|-----------+
13// +----------------------------------------------------+ 15// +----------------------------------------------------+
14 16
15#[cfg(not(any(stm32l0, stm32l1)))] 17//! BasicInstance --> CaptureCompare16bitInstance --+--> ComplementaryCaptureCompare16bitInstance
18//! |
19//! +--> CaptureCompare32bitInstance
20//!
21//! mapping:
22//!
23//! Basic Timer --> BasicInstance
24//! 1-channel Timer, 2-channel Timer, General Purpose 16-bit Timer --> CaptureCompare16bitInstance
25//! General Purpose 32-bit Timer --> CaptureCompare32bitInstance
26//! 1-channel with one complentary Timer, 2-channel with one complentary Timer, Advance Control Timer --> ComplementaryCaptureCompare16bitInstance
27
28#[cfg(not(stm32l0))]
16pub mod complementary_pwm; 29pub mod complementary_pwm;
17pub mod qei; 30pub mod qei;
18pub mod simple_pwm; 31pub mod simple_pwm;
@@ -32,157 +45,6 @@ pub mod low_level {
32pub(crate) mod sealed { 45pub(crate) mod sealed {
33 use super::*; 46 use super::*;
34 47
35 macro_rules! add_capture_compare_common_methods {
36 ($regs:ident) => {
37 /// Set input capture filter.
38 fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) {
39 let raw_channel = channel.index();
40 Self::$regs()
41 .ccmr_input(raw_channel / 2)
42 .modify(|r| r.set_icf(raw_channel % 2, icf));
43 }
44
45 /// Clear input interrupt.
46 fn clear_input_interrupt(&mut self, channel: Channel) {
47 Self::$regs().sr().modify(|r| r.set_ccif(channel.index(), false));
48 }
49
50 /// Enable input interrupt.
51 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) {
52 Self::$regs()
53 .dier()
54 .modify(|r| r.set_ccie(channel.index(), enable));
55 }
56
57 /// Set input capture prescaler.
58 fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) {
59 let raw_channel = channel.index();
60 Self::$regs()
61 .ccmr_input(raw_channel / 2)
62 .modify(|r| r.set_icpsc(raw_channel % 2, factor));
63 }
64
65 /// Set input TI selection.
66 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) {
67 let raw_channel = channel.index();
68 Self::$regs()
69 .ccmr_input(raw_channel / 2)
70 .modify(|r| r.set_ccs(raw_channel % 2, tisel.into()));
71 }
72
73 /// Set input capture mode.
74 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) {
75 Self::$regs().ccer().modify(|r| match mode {
76 InputCaptureMode::Rising => {
77 r.set_ccnp(channel.index(), false);
78 r.set_ccp(channel.index(), false);
79 }
80 InputCaptureMode::Falling => {
81 r.set_ccnp(channel.index(), false);
82 r.set_ccp(channel.index(), true);
83 }
84 InputCaptureMode::BothEdges => {
85 r.set_ccnp(channel.index(), true);
86 r.set_ccp(channel.index(), true);
87 }
88 });
89 }
90
91 /// Set output compare mode.
92 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
93 let raw_channel: usize = channel.index();
94 Self::$regs()
95 .ccmr_output(raw_channel / 2)
96 .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
97 }
98
99 /// Set output polarity.
100 fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
101 Self::$regs()
102 .ccer()
103 .modify(|w| w.set_ccp(channel.index(), polarity.into()));
104 }
105
106 /// Enable/disable a channel.
107 fn enable_channel(&mut self, channel: Channel, enable: bool) {
108 Self::$regs()
109 .ccer()
110 .modify(|w| w.set_cce(channel.index(), enable));
111 }
112
113 /// Get enable/disable state of a channel
114 fn get_channel_enable_state(&self, channel: Channel) -> bool {
115 Self::$regs().ccer().read().cce(channel.index())
116 }
117
118 /// Set compare value for a channel.
119 fn set_compare_value(&mut self, channel: Channel, value: u16) {
120 Self::$regs().ccr(channel.index()).modify(|w| w.set_ccr(value));
121 }
122
123 /// Get capture value for a channel.
124 fn get_capture_value(&mut self, channel: Channel) -> u16 {
125 Self::$regs().ccr(channel.index()).read().ccr()
126 }
127
128 /// Get compare value for a channel.
129 fn get_compare_value(&self, channel: Channel) -> u16 {
130 Self::$regs().ccr(channel.index()).read().ccr()
131 }
132
133 /// Set output compare preload.
134 fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) {
135 let channel_index = channel.index();
136 Self::$regs()
137 .ccmr_output(channel_index / 2)
138 .modify(|w| w.set_ocpe(channel_index % 2, preload));
139 }
140 };
141 }
142
143 macro_rules! add_capture_compare_dma_methods {
144 ($regs:ident) => {
145 /// Get capture compare DMA selection
146 fn get_cc_dma_selection(&self) -> super::vals::Ccds {
147 Self::$regs().cr2().read().ccds()
148 }
149
150 /// Set capture compare DMA selection
151 fn set_cc_dma_selection(&mut self, ccds: super::vals::Ccds) {
152 Self::$regs().cr2().modify(|w| w.set_ccds(ccds))
153 }
154
155 /// Get capture compare DMA enable state
156 fn get_cc_dma_enable_state(&self, channel: Channel) -> bool {
157 Self::$regs().dier().read().ccde(channel.index())
158 }
159
160 /// Set capture compare DMA enable state
161 fn set_cc_dma_enable_state(&mut self, channel: Channel, ccde: bool) {
162 Self::$regs().dier().modify(|w| w.set_ccde(channel.index(), ccde))
163 }
164 };
165 }
166
167 #[cfg(not(any(stm32l0, stm32l1)))]
168 macro_rules! add_complementary_capture_compare_methods {
169 ($regs:ident) => {
170 /// Set complementary output polarity.
171 fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
172 Self::$regs()
173 .ccer()
174 .modify(|w| w.set_ccnp(channel.index(), polarity.into()));
175 }
176
177 /// Enable/disable a complementary channel.
178 fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) {
179 Self::$regs()
180 .ccer()
181 .modify(|w| w.set_ccne(channel.index(), enable));
182 }
183 };
184 }
185
186 /// Virtual Core 16-bit timer instance. 48 /// Virtual Core 16-bit timer instance.
187 pub trait CoreInstance: RccPeripheral { 49 pub trait CoreInstance: RccPeripheral {
188 /// Interrupt for this timer. 50 /// Interrupt for this timer.
@@ -326,8 +188,6 @@ pub(crate) mod sealed {
326 fn get_max_compare_value(&self) -> u16 { 188 fn get_max_compare_value(&self) -> u16 {
327 Self::regs_1ch().arr().read().arr() 189 Self::regs_1ch().arr().read().arr()
328 } 190 }
329
330 add_capture_compare_common_methods!(regs_1ch);
331 } 191 }
332 192
333 /// Gneral-purpose 1 channel 16-bit timer instance. 193 /// Gneral-purpose 1 channel 16-bit timer instance.
@@ -339,8 +199,6 @@ pub(crate) mod sealed {
339 /// for a given set of capabilities, and having it transparently work with 199 /// for a given set of capabilities, and having it transparently work with
340 /// more capable timers. 200 /// more capable timers.
341 fn regs_2ch() -> crate::pac::timer::Tim2ch; 201 fn regs_2ch() -> crate::pac::timer::Tim2ch;
342
343 add_capture_compare_common_methods!(regs_2ch);
344 } 202 }
345 203
346 /// Gneral-purpose 16-bit timer instance. 204 /// Gneral-purpose 16-bit timer instance.
@@ -372,11 +230,128 @@ pub(crate) mod sealed {
372 (cr1.cms(), cr1.dir()).into() 230 (cr1.cms(), cr1.dir()).into()
373 } 231 }
374 232
375 add_capture_compare_common_methods!(regs_gp16); 233 /// Set input capture filter.
376 add_capture_compare_dma_methods!(regs_gp16); 234 fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) {
235 let raw_channel = channel.index();
236 Self::regs_gp16()
237 .ccmr_input(raw_channel / 2)
238 .modify(|r| r.set_icf(raw_channel % 2, icf));
239 }
240
241 /// Clear input interrupt.
242 fn clear_input_interrupt(&mut self, channel: Channel) {
243 Self::regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false));
244 }
245
246 /// Enable input interrupt.
247 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) {
248 Self::regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable));
249 }
250
251 /// Set input capture prescaler.
252 fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) {
253 let raw_channel = channel.index();
254 Self::regs_gp16()
255 .ccmr_input(raw_channel / 2)
256 .modify(|r| r.set_icpsc(raw_channel % 2, factor));
257 }
258
259 /// Set input TI selection.
260 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) {
261 let raw_channel = channel.index();
262 Self::regs_gp16()
263 .ccmr_input(raw_channel / 2)
264 .modify(|r| r.set_ccs(raw_channel % 2, tisel.into()));
265 }
266
267 /// Set input capture mode.
268 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) {
269 Self::regs_gp16().ccer().modify(|r| match mode {
270 InputCaptureMode::Rising => {
271 r.set_ccnp(channel.index(), false);
272 r.set_ccp(channel.index(), false);
273 }
274 InputCaptureMode::Falling => {
275 r.set_ccnp(channel.index(), false);
276 r.set_ccp(channel.index(), true);
277 }
278 InputCaptureMode::BothEdges => {
279 r.set_ccnp(channel.index(), true);
280 r.set_ccp(channel.index(), true);
281 }
282 });
283 }
284
285 /// Set output compare mode.
286 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
287 let raw_channel: usize = channel.index();
288 Self::regs_gp16()
289 .ccmr_output(raw_channel / 2)
290 .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
291 }
292
293 /// Set output polarity.
294 fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
295 Self::regs_gp16()
296 .ccer()
297 .modify(|w| w.set_ccp(channel.index(), polarity.into()));
298 }
299
300 /// Enable/disable a channel.
301 fn enable_channel(&mut self, channel: Channel, enable: bool) {
302 Self::regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable));
303 }
304
305 /// Get enable/disable state of a channel
306 fn get_channel_enable_state(&self, channel: Channel) -> bool {
307 Self::regs_gp16().ccer().read().cce(channel.index())
308 }
309
310 /// Set compare value for a channel.
311 fn set_compare_value(&mut self, channel: Channel, value: u16) {
312 Self::regs_gp16().ccr(channel.index()).modify(|w| w.set_ccr(value));
313 }
314
315 /// Get capture value for a channel.
316 fn get_capture_value(&mut self, channel: Channel) -> u16 {
317 Self::regs_gp16().ccr(channel.index()).read().ccr()
318 }
319
320 /// Get compare value for a channel.
321 fn get_compare_value(&self, channel: Channel) -> u16 {
322 Self::regs_gp16().ccr(channel.index()).read().ccr()
323 }
324
325 /// Set output compare preload.
326 fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) {
327 let channel_index = channel.index();
328 Self::regs_gp16()
329 .ccmr_output(channel_index / 2)
330 .modify(|w| w.set_ocpe(channel_index % 2, preload));
331 }
332
333 /// Get capture compare DMA selection
334 fn get_cc_dma_selection(&self) -> super::vals::Ccds {
335 Self::regs_gp16().cr2().read().ccds()
336 }
337
338 /// Set capture compare DMA selection
339 fn set_cc_dma_selection(&mut self, ccds: super::vals::Ccds) {
340 Self::regs_gp16().cr2().modify(|w| w.set_ccds(ccds))
341 }
342
343 /// Get capture compare DMA enable state
344 fn get_cc_dma_enable_state(&self, channel: Channel) -> bool {
345 Self::regs_gp16().dier().read().ccde(channel.index())
346 }
347
348 /// Set capture compare DMA enable state
349 fn set_cc_dma_enable_state(&mut self, channel: Channel, ccde: bool) {
350 Self::regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde))
351 }
377 } 352 }
378 353
379 #[cfg(not(any(stm32f1, stm32l0, stm32c0)))] 354 #[cfg(not(stm32l0))]
380 /// Gneral-purpose 32-bit timer instance. 355 /// Gneral-purpose 32-bit timer instance.
381 pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance { 356 pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance {
382 /// Get access to the general purpose 32bit timer registers. 357 /// Get access to the general purpose 32bit timer registers.
@@ -437,7 +412,7 @@ pub(crate) mod sealed {
437 } 412 }
438 } 413 }
439 414
440 #[cfg(not(any(stm32l0, stm32l1)))] 415 #[cfg(not(stm32l0))]
441 /// Gneral-purpose 1 channel with one complementary 16-bit timer instance. 416 /// Gneral-purpose 1 channel with one complementary 16-bit timer instance.
442 pub trait GeneralPurpose1ChannelComplementaryInstance: BasicNoCr2Instance + GeneralPurpose1ChannelInstance { 417 pub trait GeneralPurpose1ChannelComplementaryInstance: BasicNoCr2Instance + GeneralPurpose1ChannelInstance {
443 /// Get access to the general purpose 1 channel with one complementary 16bit timer registers. 418 /// Get access to the general purpose 1 channel with one complementary 16bit timer registers.
@@ -462,11 +437,9 @@ pub(crate) mod sealed {
462 fn enable_outputs(&mut self) { 437 fn enable_outputs(&mut self) {
463 Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); 438 Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true));
464 } 439 }
465
466 add_complementary_capture_compare_methods!(regs_1ch_cmp);
467 } 440 }
468 441
469 #[cfg(not(any(stm32l0, stm32l1)))] 442 #[cfg(not(stm32l0))]
470 /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. 443 /// Gneral-purpose 2 channel with one complementary 16-bit timer instance.
471 pub trait GeneralPurpose2ChannelComplementaryInstance: 444 pub trait GeneralPurpose2ChannelComplementaryInstance:
472 BasicInstance + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance 445 BasicInstance + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance
@@ -478,11 +451,9 @@ pub(crate) mod sealed {
478 /// for a given set of capabilities, and having it transparently work with 451 /// for a given set of capabilities, and having it transparently work with
479 /// more capable timers. 452 /// more capable timers.
480 fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp; 453 fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp;
481
482 add_complementary_capture_compare_methods!(regs_2ch_cmp);
483 } 454 }
484 455
485 #[cfg(not(any(stm32l0, stm32l1)))] 456 #[cfg(not(stm32l0))]
486 /// Advanced control timer instance. 457 /// Advanced control timer instance.
487 pub trait AdvancedControlInstance: 458 pub trait AdvancedControlInstance:
488 GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance 459 GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance
@@ -490,7 +461,19 @@ pub(crate) mod sealed {
490 /// Get access to the advanced timer registers. 461 /// Get access to the advanced timer registers.
491 fn regs_advanced() -> crate::pac::timer::TimAdv; 462 fn regs_advanced() -> crate::pac::timer::TimAdv;
492 463
493 add_complementary_capture_compare_methods!(regs_advanced); 464 /// Set complementary output polarity.
465 fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
466 Self::regs_advanced()
467 .ccer()
468 .modify(|w| w.set_ccnp(channel.index(), polarity.into()));
469 }
470
471 /// Enable/disable a complementary channel.
472 fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) {
473 Self::regs_advanced()
474 .ccer()
475 .modify(|w| w.set_ccne(channel.index(), enable));
476 }
494 } 477 }
495} 478}
496 479
@@ -681,96 +664,66 @@ impl From<OutputPolarity> for bool {
681 } 664 }
682} 665}
683 666
684/// Virtual Core 16-bit timer instance.
685pub trait CoreInstance: sealed::CoreInstance + 'static {}
686
687/// Virtual Basic 16-bit timer without CR2 register instance.
688pub trait BasicNoCr2Instance: sealed::BasicNoCr2Instance + CoreInstance + 'static {}
689
690/// Basic 16-bit timer instance. 667/// Basic 16-bit timer instance.
691pub trait BasicInstance: sealed::BasicInstance + BasicNoCr2Instance + 'static {} 668pub trait BasicInstance: sealed::BasicInstance + sealed::BasicNoCr2Instance + sealed::CoreInstance + 'static {}
692
693/// 1 channel 16-bit instance.
694pub trait GeneralPurpose1ChannelInstance: sealed::GeneralPurpose1ChannelInstance + CoreInstance + 'static {}
695
696/// 2 channel 16-bit instance.
697pub trait GeneralPurpose2ChannelInstance:
698 sealed::GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelInstance + 'static
699{
700}
701 669
702/// General-purpose 16-bit timer instance. 670/// General-purpose 16-bit timer instance.
703pub trait GeneralPurpose16bitInstance: 671pub trait CaptureCompare16bitInstance:
704 sealed::GeneralPurpose16bitInstance + BasicInstance + GeneralPurpose2ChannelInstance + 'static 672 BasicInstance
673 + sealed::GeneralPurpose2ChannelInstance
674 + sealed::GeneralPurpose1ChannelInstance
675 + sealed::GeneralPurpose16bitInstance
676 + 'static
705{ 677{
706} 678}
707 679
708#[cfg(not(any(stm32f1, stm32l0, stm32c0)))] 680#[cfg(not(stm32l0))]
709/// Gneral-purpose 32-bit timer instance. 681/// Gneral-purpose 32-bit timer instance.
710pub trait GeneralPurpose32bitInstance: 682pub trait CaptureCompare32bitInstance:
711 sealed::GeneralPurpose32bitInstance + GeneralPurpose16bitInstance + 'static 683 sealed::GeneralPurpose32bitInstance + CaptureCompare16bitInstance + 'static
712{ 684{
713} 685}
714 686
715#[cfg(not(any(stm32l0, stm32l1)))] 687#[cfg(not(stm32l0))]
716/// General-purpose 1 channel with one complementary 16-bit timer instance. 688/// Advanced control timer instance.
717pub trait GeneralPurpose1ChannelComplementaryInstance: 689pub trait ComplementaryCaptureCompare16bitInstance:
718 sealed::GeneralPurpose1ChannelComplementaryInstance + GeneralPurpose1ChannelInstance + 'static 690 CaptureCompare16bitInstance
719{ 691 + sealed::GeneralPurpose1ChannelComplementaryInstance
720} 692 + sealed::GeneralPurpose2ChannelComplementaryInstance
721 693 + sealed::AdvancedControlInstance
722#[cfg(not(any(stm32l0, stm32l1)))]
723/// General-purpose 2 channel with one complementary 16-bit timer instance.
724pub trait GeneralPurpose2ChannelComplementaryInstance:
725 sealed::GeneralPurpose2ChannelComplementaryInstance
726 + BasicInstance
727 + GeneralPurpose2ChannelInstance
728 + GeneralPurpose1ChannelComplementaryInstance
729 + 'static 694 + 'static
730{ 695{
731} 696}
732 697
733#[cfg(not(any(stm32f37, stm32l0, stm32l1)))] 698pin_trait!(Channel1Pin, CaptureCompare16bitInstance);
734/// Advanced control timer instance. 699pin_trait!(Channel2Pin, CaptureCompare16bitInstance);
735pub trait AdvancedControlInstance: 700pin_trait!(Channel3Pin, CaptureCompare16bitInstance);
736 sealed::AdvancedControlInstance + GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance + 'static 701pin_trait!(Channel4Pin, CaptureCompare16bitInstance);
737{ 702pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance);
738} 703
704#[cfg(not(stm32l0))]
705pin_trait!(Channel1ComplementaryPin, ComplementaryCaptureCompare16bitInstance);
706#[cfg(not(stm32l0))]
707pin_trait!(Channel2ComplementaryPin, ComplementaryCaptureCompare16bitInstance);
708#[cfg(not(stm32l0))]
709pin_trait!(Channel3ComplementaryPin, ComplementaryCaptureCompare16bitInstance);
710#[cfg(not(stm32l0))]
711pin_trait!(Channel4ComplementaryPin, ComplementaryCaptureCompare16bitInstance);
712
713#[cfg(not(stm32l0))]
714pin_trait!(BreakInputPin, ComplementaryCaptureCompare16bitInstance);
715#[cfg(not(stm32l0))]
716pin_trait!(BreakInput2Pin, ComplementaryCaptureCompare16bitInstance);
739 717
740pin_trait!(Channel1Pin, GeneralPurpose1ChannelInstance); 718#[cfg(not(stm32l0))]
741pin_trait!(Channel2Pin, GeneralPurpose2ChannelInstance); 719pin_trait!(BreakInputComparator1Pin, ComplementaryCaptureCompare16bitInstance);
742pin_trait!(Channel3Pin, GeneralPurpose16bitInstance); 720#[cfg(not(stm32l0))]
743pin_trait!(Channel4Pin, GeneralPurpose16bitInstance); 721pin_trait!(BreakInputComparator2Pin, ComplementaryCaptureCompare16bitInstance);
744 722
745#[cfg(not(stm32l0))] 723#[cfg(not(stm32l0))]
746pin_trait!(ExternalTriggerPin, GeneralPurpose16bitInstance); 724pin_trait!(BreakInput2Comparator1Pin, ComplementaryCaptureCompare16bitInstance);
747 725#[cfg(not(stm32l0))]
748#[cfg(stm32l0)] 726pin_trait!(BreakInput2Comparator2Pin, ComplementaryCaptureCompare16bitInstance);
749pin_trait!(ExternalTriggerPin, GeneralPurpose2ChannelInstance);
750
751#[cfg(not(any(stm32l0, stm32l1)))]
752pin_trait!(Channel1ComplementaryPin, GeneralPurpose1ChannelComplementaryInstance);
753#[cfg(not(any(stm32l0, stm32l1)))]
754pin_trait!(Channel2ComplementaryPin, GeneralPurpose2ChannelComplementaryInstance);
755#[cfg(not(any(stm32l0, stm32l1)))]
756pin_trait!(Channel3ComplementaryPin, AdvancedControlInstance);
757#[cfg(not(any(stm32l0, stm32l1)))]
758pin_trait!(Channel4ComplementaryPin, AdvancedControlInstance);
759
760#[cfg(not(any(stm32l0, stm32l1)))]
761pin_trait!(BreakInputPin, GeneralPurpose1ChannelComplementaryInstance);
762#[cfg(not(any(stm32l0, stm32l1)))]
763pin_trait!(BreakInput2Pin, GeneralPurpose2ChannelComplementaryInstance);
764
765#[cfg(not(any(stm32l0, stm32l1)))]
766pin_trait!(BreakInputComparator1Pin, GeneralPurpose1ChannelComplementaryInstance);
767#[cfg(not(any(stm32l0, stm32l1)))]
768pin_trait!(BreakInputComparator2Pin, AdvancedControlInstance);
769
770#[cfg(not(any(stm32l0, stm32l1)))]
771pin_trait!(BreakInput2Comparator1Pin, AdvancedControlInstance);
772#[cfg(not(any(stm32l0, stm32l1)))]
773pin_trait!(BreakInput2Comparator2Pin, AdvancedControlInstance);
774 727
775#[allow(unused)] 728#[allow(unused)]
776macro_rules! impl_core_timer { 729macro_rules! impl_core_timer {
@@ -830,7 +783,7 @@ macro_rules! impl_2ch_timer {
830} 783}
831 784
832#[allow(unused)] 785#[allow(unused)]
833macro_rules! impl_gp_16bit_timer { 786macro_rules! impl_gp16_timer {
834 ($inst:ident) => { 787 ($inst:ident) => {
835 impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { 788 impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst {
836 fn regs_gp16() -> crate::pac::timer::TimGp16 { 789 fn regs_gp16() -> crate::pac::timer::TimGp16 {
@@ -841,7 +794,7 @@ macro_rules! impl_gp_16bit_timer {
841} 794}
842 795
843#[allow(unused)] 796#[allow(unused)]
844macro_rules! impl_gp_32bit_timer { 797macro_rules! impl_gp32_timer {
845 ($inst:ident) => { 798 ($inst:ident) => {
846 impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst { 799 impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst {
847 fn regs_gp32() -> crate::pac::timer::TimGp32 { 800 fn regs_gp32() -> crate::pac::timer::TimGp32 {
@@ -890,26 +843,30 @@ foreach_interrupt! {
890 impl_core_timer!($inst, $irq); 843 impl_core_timer!($inst, $irq);
891 impl_basic_no_cr2_timer!($inst); 844 impl_basic_no_cr2_timer!($inst);
892 impl_basic_timer!($inst); 845 impl_basic_timer!($inst);
893 impl CoreInstance for crate::peripherals::$inst {}
894 impl BasicNoCr2Instance for crate::peripherals::$inst{}
895 impl BasicInstance for crate::peripherals::$inst {} 846 impl BasicInstance for crate::peripherals::$inst {}
896 }; 847 };
897 848
898 ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => { 849 ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => {
899 impl_core_timer!($inst, $irq); 850 impl_core_timer!($inst, $irq);
851 impl_basic_no_cr2_timer!($inst);
852 impl_basic_timer!($inst);
900 impl_1ch_timer!($inst); 853 impl_1ch_timer!($inst);
901 impl CoreInstance for crate::peripherals::$inst {} 854 impl_2ch_timer!($inst);
902 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 855 impl_gp16_timer!($inst);
856 impl BasicInstance for crate::peripherals::$inst {}
857 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
903 }; 858 };
904 859
905 860
906 ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { 861 ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => {
907 impl_core_timer!($inst, $irq); 862 impl_core_timer!($inst, $irq);
863 impl_basic_no_cr2_timer!($inst);
864 impl_basic_timer!($inst);
908 impl_1ch_timer!($inst); 865 impl_1ch_timer!($inst);
909 impl_2ch_timer!($inst); 866 impl_2ch_timer!($inst);
910 impl CoreInstance for crate::peripherals::$inst {} 867 impl_gp16_timer!($inst);
911 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 868 impl BasicInstance for crate::peripherals::$inst {}
912 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} 869 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
913 }; 870 };
914 871
915 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { 872 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => {
@@ -918,13 +875,9 @@ foreach_interrupt! {
918 impl_basic_timer!($inst); 875 impl_basic_timer!($inst);
919 impl_1ch_timer!($inst); 876 impl_1ch_timer!($inst);
920 impl_2ch_timer!($inst); 877 impl_2ch_timer!($inst);
921 impl_gp_16bit_timer!($inst); 878 impl_gp16_timer!($inst);
922 impl CoreInstance for crate::peripherals::$inst {}
923 impl BasicNoCr2Instance for crate::peripherals::$inst{}
924 impl BasicInstance for crate::peripherals::$inst {} 879 impl BasicInstance for crate::peripherals::$inst {}
925 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 880 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
926 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {}
927 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
928 }; 881 };
929 882
930 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { 883 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => {
@@ -933,26 +886,26 @@ foreach_interrupt! {
933 impl_basic_timer!($inst); 886 impl_basic_timer!($inst);
934 impl_1ch_timer!($inst); 887 impl_1ch_timer!($inst);
935 impl_2ch_timer!($inst); 888 impl_2ch_timer!($inst);
936 impl_gp_16bit_timer!($inst); 889 impl_gp16_timer!($inst);
937 impl_gp_32bit_timer!($inst); 890 impl_gp32_timer!($inst);
938 impl CoreInstance for crate::peripherals::$inst {}
939 impl BasicNoCr2Instance for crate::peripherals::$inst{}
940 impl BasicInstance for crate::peripherals::$inst {} 891 impl BasicInstance for crate::peripherals::$inst {}
941 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 892 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
942 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} 893 impl CaptureCompare32bitInstance for crate::peripherals::$inst {}
943 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
944 impl GeneralPurpose32bitInstance for crate::peripherals::$inst {}
945 }; 894 };
946 895
947 ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => { 896 ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => {
948 impl_core_timer!($inst, $irq); 897 impl_core_timer!($inst, $irq);
949 impl_basic_no_cr2_timer!($inst); 898 impl_basic_no_cr2_timer!($inst);
899 impl_basic_timer!($inst);
950 impl_1ch_timer!($inst); 900 impl_1ch_timer!($inst);
901 impl_2ch_timer!($inst);
902 impl_gp16_timer!($inst);
951 impl_1ch_cmp_timer!($inst); 903 impl_1ch_cmp_timer!($inst);
952 impl CoreInstance for crate::peripherals::$inst {} 904 impl_2ch_cmp_timer!($inst);
953 impl BasicNoCr2Instance for crate::peripherals::$inst{} 905 impl_adv_timer!($inst);
954 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 906 impl BasicInstance for crate::peripherals::$inst {}
955 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} 907 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
908 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
956 }; 909 };
957 910
958 911
@@ -962,15 +915,13 @@ foreach_interrupt! {
962 impl_basic_timer!($inst); 915 impl_basic_timer!($inst);
963 impl_1ch_timer!($inst); 916 impl_1ch_timer!($inst);
964 impl_2ch_timer!($inst); 917 impl_2ch_timer!($inst);
918 impl_gp16_timer!($inst);
965 impl_1ch_cmp_timer!($inst); 919 impl_1ch_cmp_timer!($inst);
966 impl_2ch_cmp_timer!($inst); 920 impl_2ch_cmp_timer!($inst);
967 impl CoreInstance for crate::peripherals::$inst {} 921 impl_adv_timer!($inst);
968 impl BasicNoCr2Instance for crate::peripherals::$inst{}
969 impl BasicInstance for crate::peripherals::$inst {} 922 impl BasicInstance for crate::peripherals::$inst {}
970 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 923 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
971 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} 924 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
972 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {}
973 impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {}
974 }; 925 };
975 926
976 927
@@ -980,26 +931,20 @@ foreach_interrupt! {
980 impl_basic_timer!($inst); 931 impl_basic_timer!($inst);
981 impl_1ch_timer!($inst); 932 impl_1ch_timer!($inst);
982 impl_2ch_timer!($inst); 933 impl_2ch_timer!($inst);
934 impl_gp16_timer!($inst);
983 impl_1ch_cmp_timer!($inst); 935 impl_1ch_cmp_timer!($inst);
984 impl_gp_16bit_timer!($inst);
985 impl_2ch_cmp_timer!($inst); 936 impl_2ch_cmp_timer!($inst);
986 impl_adv_timer!($inst); 937 impl_adv_timer!($inst);
987 impl CoreInstance for crate::peripherals::$inst {}
988 impl BasicNoCr2Instance for crate::peripherals::$inst{}
989 impl BasicInstance for crate::peripherals::$inst {} 938 impl BasicInstance for crate::peripherals::$inst {}
990 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 939 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
991 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} 940 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
992 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
993 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {}
994 impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {}
995 impl AdvancedControlInstance for crate::peripherals::$inst {}
996 }; 941 };
997} 942}
998 943
999// Update Event trigger DMA for every timer 944// Update Event trigger DMA for every timer
1000dma_trait!(UpDma, BasicNoCr2Instance); 945dma_trait!(UpDma, BasicInstance);
1001 946
1002dma_trait!(Ch1Dma, GeneralPurpose1ChannelInstance); 947dma_trait!(Ch1Dma, CaptureCompare16bitInstance);
1003dma_trait!(Ch2Dma, GeneralPurpose2ChannelInstance); 948dma_trait!(Ch2Dma, CaptureCompare16bitInstance);
1004dma_trait!(Ch3Dma, GeneralPurpose16bitInstance); 949dma_trait!(Ch3Dma, CaptureCompare16bitInstance);
1005dma_trait!(Ch4Dma, GeneralPurpose16bitInstance); 950dma_trait!(Ch4Dma, CaptureCompare16bitInstance);
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs
index 7e56312bb..59efb72ba 100644
--- a/embassy-stm32/src/timer/qei.rs
+++ b/embassy-stm32/src/timer/qei.rs
@@ -30,7 +30,7 @@ pub struct QeiPin<'d, T, Channel> {
30 30
31macro_rules! channel_impl { 31macro_rules! channel_impl {
32 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 32 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
33 impl<'d, T: GeneralPurpose16bitInstance> QeiPin<'d, T, $channel> { 33 impl<'d, T: CaptureCompare16bitInstance> QeiPin<'d, T, $channel> {
34 #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] 34 #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")]
35 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { 35 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self {
36 into_ref!(pin); 36 into_ref!(pin);
@@ -57,7 +57,7 @@ pub struct Qei<'d, T> {
57 _inner: PeripheralRef<'d, T>, 57 _inner: PeripheralRef<'d, T>,
58} 58}
59 59
60impl<'d, T: GeneralPurpose16bitInstance> Qei<'d, T> { 60impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> {
61 /// Create a new quadrature decoder driver. 61 /// Create a new quadrature decoder driver.
62 pub fn new(tim: impl Peripheral<P = T> + 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { 62 pub fn new(tim: impl Peripheral<P = T> + 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self {
63 Self::new_inner(tim) 63 Self::new_inner(tim)
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index 088d02c97..1acba504e 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -1,7 +1,6 @@
1//! Simple PWM driver. 1//! Simple PWM driver.
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::ops::{Deref, DerefMut};
5 4
6use embassy_hal_internal::{into_ref, PeripheralRef}; 5use embassy_hal_internal::{into_ref, PeripheralRef};
7 6
@@ -31,7 +30,7 @@ pub struct PwmPin<'d, T, C> {
31 30
32macro_rules! channel_impl { 31macro_rules! channel_impl {
33 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 32 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
34 impl<'d, T: GeneralPurpose16bitInstance> PwmPin<'d, T, $channel> { 33 impl<'d, T: CaptureCompare16bitInstance> PwmPin<'d, T, $channel> {
35 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] 34 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
36 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { 35 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self {
37 into_ref!(pin); 36 into_ref!(pin);
@@ -60,7 +59,7 @@ pub struct SimplePwm<'d, T> {
60 inner: PeripheralRef<'d, T>, 59 inner: PeripheralRef<'d, T>,
61} 60}
62 61
63impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { 62impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
64 /// Create a new simple PWM driver. 63 /// Create a new simple PWM driver.
65 pub fn new( 64 pub fn new(
66 tim: impl Peripheral<P = T> + 'd, 65 tim: impl Peripheral<P = T> + 'd,
@@ -88,13 +87,9 @@ impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> {
88 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] 87 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4]
89 .iter() 88 .iter()
90 .for_each(|&channel| { 89 .for_each(|&channel| {
91 sealed::GeneralPurpose16bitInstance::set_output_compare_mode( 90 this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1);
92 this.inner.deref_mut(),
93 channel,
94 OutputCompareMode::PwmMode1,
95 );
96 91
97 sealed::GeneralPurpose16bitInstance::set_output_compare_preload(this.inner.deref_mut(), channel, true); 92 this.inner.set_output_compare_preload(channel, true);
98 }); 93 });
99 94
100 this 95 this
@@ -102,17 +97,17 @@ impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> {
102 97
103 /// Enable the given channel. 98 /// Enable the given channel.
104 pub fn enable(&mut self, channel: Channel) { 99 pub fn enable(&mut self, channel: Channel) {
105 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); 100 self.inner.enable_channel(channel, true);
106 } 101 }
107 102
108 /// Disable the given channel. 103 /// Disable the given channel.
109 pub fn disable(&mut self, channel: Channel) { 104 pub fn disable(&mut self, channel: Channel) {
110 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); 105 self.inner.enable_channel(channel, false);
111 } 106 }
112 107
113 /// Check whether given channel is enabled 108 /// Check whether given channel is enabled
114 pub fn is_enabled(&self, channel: Channel) -> bool { 109 pub fn is_enabled(&self, channel: Channel) -> bool {
115 sealed::GeneralPurpose16bitInstance::get_channel_enable_state(self.inner.deref(), channel) 110 self.inner.get_channel_enable_state(channel)
116 } 111 }
117 112
118 /// Set PWM frequency. 113 /// Set PWM frequency.
@@ -140,24 +135,24 @@ impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> {
140 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 135 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
141 pub fn set_duty(&mut self, channel: Channel, duty: u16) { 136 pub fn set_duty(&mut self, channel: Channel, duty: u16) {
142 assert!(duty <= self.get_max_duty()); 137 assert!(duty <= self.get_max_duty());
143 sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) 138 self.inner.set_compare_value(channel, duty)
144 } 139 }
145 140
146 /// Get the duty for a given channel. 141 /// Get the duty for a given channel.
147 /// 142 ///
148 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 143 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
149 pub fn get_duty(&self, channel: Channel) -> u16 { 144 pub fn get_duty(&self, channel: Channel) -> u16 {
150 sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) 145 self.inner.get_compare_value(channel)
151 } 146 }
152 147
153 /// Set the output polarity for a given channel. 148 /// Set the output polarity for a given channel.
154 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { 149 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
155 sealed::GeneralPurpose16bitInstance::set_output_polarity(self.inner.deref_mut(), channel, polarity); 150 self.inner.set_output_polarity(channel, polarity);
156 } 151 }
157 152
158 /// Set the output compare mode for a given channel. 153 /// Set the output compare mode for a given channel.
159 pub fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { 154 pub fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
160 sealed::GeneralPurpose16bitInstance::set_output_compare_mode(self.inner.deref_mut(), channel, mode); 155 self.inner.set_output_compare_mode(channel, mode);
161 } 156 }
162 157
163 /// Generate a sequence of PWM waveform 158 /// Generate a sequence of PWM waveform
@@ -232,7 +227,7 @@ impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> {
232 227
233macro_rules! impl_waveform_chx { 228macro_rules! impl_waveform_chx {
234 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { 229 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => {
235 impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> { 230 impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
236 /// Generate a sequence of PWM waveform 231 /// Generate a sequence of PWM waveform
237 /// 232 ///
238 /// Note: 233 /// Note:
@@ -319,17 +314,17 @@ impl_waveform_chx!(waveform_ch2, Ch2Dma, Ch2);
319impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3); 314impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3);
320impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4); 315impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4);
321 316
322impl<'d, T: GeneralPurpose16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { 317impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> {
323 type Channel = Channel; 318 type Channel = Channel;
324 type Time = Hertz; 319 type Time = Hertz;
325 type Duty = u16; 320 type Duty = u16;
326 321
327 fn disable(&mut self, channel: Self::Channel) { 322 fn disable(&mut self, channel: Self::Channel) {
328 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false); 323 self.inner.enable_channel(channel, false);
329 } 324 }
330 325
331 fn enable(&mut self, channel: Self::Channel) { 326 fn enable(&mut self, channel: Self::Channel) {
332 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true); 327 self.inner.enable_channel(channel, true);
333 } 328 }
334 329
335 fn get_period(&self) -> Self::Time { 330 fn get_period(&self) -> Self::Time {
@@ -337,7 +332,7 @@ impl<'d, T: GeneralPurpose16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d,
337 } 332 }
338 333
339 fn get_duty(&self, channel: Self::Channel) -> Self::Duty { 334 fn get_duty(&self, channel: Self::Channel) -> Self::Duty {
340 sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel) 335 self.inner.get_compare_value(channel)
341 } 336 }
342 337
343 fn get_max_duty(&self) -> Self::Duty { 338 fn get_max_duty(&self) -> Self::Duty {
@@ -346,7 +341,7 @@ impl<'d, T: GeneralPurpose16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d,
346 341
347 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { 342 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) {
348 assert!(duty <= self.get_max_duty()); 343 assert!(duty <= self.get_max_duty());
349 sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty) 344 self.inner.set_compare_value(channel, duty)
350 } 345 }
351 346
352 fn set_period<P>(&mut self, period: P) 347 fn set_period<P>(&mut self, period: P)
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index 0be3eccb7..cc508c3cf 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -56,11 +56,11 @@ async fn main(_spawner: Spawner) {
56 Timer::after_millis(300).await; 56 Timer::after_millis(300).await;
57 } 57 }
58} 58}
59pub struct SimplePwm32<'d, T: GeneralPurpose32bitInstance> { 59pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> {
60 inner: PeripheralRef<'d, T>, 60 inner: PeripheralRef<'d, T>,
61} 61}
62 62
63impl<'d, T: GeneralPurpose32bitInstance> SimplePwm32<'d, T> { 63impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
64 pub fn new( 64 pub fn new(
65 tim: impl Peripheral<P = T> + 'd, 65 tim: impl Peripheral<P = T> + 'd,
66 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, 66 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,