aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/timer
diff options
context:
space:
mode:
authoreZio Pan <[email protected]>2024-02-01 17:10:47 +0800
committerDario Nieuwenhuis <[email protected]>2024-02-10 00:00:43 +0100
commitd538829f2f3542c78ee9eb218c0b5c982acfb46b (patch)
tree317e50ed33a5c69cec040f6a56768e58659f50f2 /embassy-stm32/src/timer
parent53bf0332e9e862fa5c09a1e9ab9a6d7116219ed7 (diff)
add methods with macro
Diffstat (limited to 'embassy-stm32/src/timer')
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs52
-rw-r--r--embassy-stm32/src/timer/mod.rs488
-rw-r--r--embassy-stm32/src/timer/qei.rs4
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs40
4 files changed, 279 insertions, 305 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index 0470e3048..b9cd044c9 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -1,6 +1,7 @@
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};
4 5
5use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
6use stm32_metapac::timer::vals::Ckd; 7use stm32_metapac::timer::vals::Ckd;
@@ -23,7 +24,7 @@ pub struct ComplementaryPwmPin<'d, T, C> {
23 24
24macro_rules! complementary_channel_impl { 25macro_rules! complementary_channel_impl {
25 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 26 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
26 impl<'d, T: CaptureCompare16bitInstance> ComplementaryPwmPin<'d, T, $channel> { 27 impl<'d, T: AdvancedControlInstance> ComplementaryPwmPin<'d, T, $channel> {
27 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] 28 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")]
28 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { 29 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self {
29 into_ref!(pin); 30 into_ref!(pin);
@@ -52,7 +53,7 @@ pub struct ComplementaryPwm<'d, T> {
52 inner: PeripheralRef<'d, T>, 53 inner: PeripheralRef<'d, T>,
53} 54}
54 55
55impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { 56impl<'d, T: AdvancedControlInstance> ComplementaryPwm<'d, T> {
56 /// Create a new complementary PWM driver. 57 /// Create a new complementary PWM driver.
57 #[allow(clippy::too_many_arguments)] 58 #[allow(clippy::too_many_arguments)]
58 pub fn new( 59 pub fn new(
@@ -84,27 +85,30 @@ impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstan
84 85
85 this.inner.enable_outputs(); 86 this.inner.enable_outputs();
86 87
87 this.inner 88 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4]
88 .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1); 89 .iter()
89 this.inner 90 .for_each(|&channel| {
90 .set_output_compare_mode(Channel::Ch2, OutputCompareMode::PwmMode1); 91 sealed::GeneralPurpose16bitInstance::set_output_compare_mode(
91 this.inner 92 this.inner.deref_mut(),
92 .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1); 93 channel,
93 this.inner 94 OutputCompareMode::PwmMode1,
94 .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1); 95 );
96 sealed::GeneralPurpose16bitInstance::set_output_compare_preload(this.inner.deref_mut(), channel, true);
97 });
98
95 this 99 this
96 } 100 }
97 101
98 /// Enable the given channel. 102 /// Enable the given channel.
99 pub fn enable(&mut self, channel: Channel) { 103 pub fn enable(&mut self, channel: Channel) {
100 self.inner.enable_channel(channel, true); 104 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true);
101 self.inner.enable_complementary_channel(channel, true); 105 sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, true);
102 } 106 }
103 107
104 /// Disable the given channel. 108 /// Disable the given channel.
105 pub fn disable(&mut self, channel: Channel) { 109 pub fn disable(&mut self, channel: Channel) {
106 self.inner.enable_complementary_channel(channel, false); 110 sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, false);
107 self.inner.enable_channel(channel, false); 111 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false);
108 } 112 }
109 113
110 /// Set PWM frequency. 114 /// Set PWM frequency.
@@ -132,13 +136,13 @@ impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstan
132 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 136 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
133 pub fn set_duty(&mut self, channel: Channel, duty: u16) { 137 pub fn set_duty(&mut self, channel: Channel, duty: u16) {
134 assert!(duty <= self.get_max_duty()); 138 assert!(duty <= self.get_max_duty());
135 self.inner.set_compare_value(channel, duty) 139 sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty)
136 } 140 }
137 141
138 /// Set the output polarity for a given channel. 142 /// Set the output polarity for a given channel.
139 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { 143 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
140 self.inner.set_output_polarity(channel, polarity); 144 sealed::GeneralPurpose16bitInstance::set_output_polarity(self.inner.deref_mut(), channel, polarity);
141 self.inner.set_complementary_output_polarity(channel, polarity); 145 sealed::AdvancedControlInstance::set_complementary_output_polarity(self.inner.deref_mut(), channel, polarity);
142 } 146 }
143 147
144 /// Set the dead time as a proportion of max_duty 148 /// Set the dead time as a proportion of max_duty
@@ -150,19 +154,19 @@ impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstan
150 } 154 }
151} 155}
152 156
153impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { 157impl<'d, T: AdvancedControlInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> {
154 type Channel = Channel; 158 type Channel = Channel;
155 type Time = Hertz; 159 type Time = Hertz;
156 type Duty = u16; 160 type Duty = u16;
157 161
158 fn disable(&mut self, channel: Self::Channel) { 162 fn disable(&mut self, channel: Self::Channel) {
159 self.inner.enable_complementary_channel(channel, false); 163 sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, false);
160 self.inner.enable_channel(channel, false); 164 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false);
161 } 165 }
162 166
163 fn enable(&mut self, channel: Self::Channel) { 167 fn enable(&mut self, channel: Self::Channel) {
164 self.inner.enable_channel(channel, true); 168 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true);
165 self.inner.enable_complementary_channel(channel, true); 169 sealed::AdvancedControlInstance::enable_complementary_channel(self.inner.deref_mut(), channel, true);
166 } 170 }
167 171
168 fn get_period(&self) -> Self::Time { 172 fn get_period(&self) -> Self::Time {
@@ -170,7 +174,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for C
170 } 174 }
171 175
172 fn get_duty(&self, channel: Self::Channel) -> Self::Duty { 176 fn get_duty(&self, channel: Self::Channel) -> Self::Duty {
173 self.inner.get_compare_value(channel) 177 sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel)
174 } 178 }
175 179
176 fn get_max_duty(&self) -> Self::Duty { 180 fn get_max_duty(&self) -> Self::Duty {
@@ -179,7 +183,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for C
179 183
180 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { 184 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) {
181 assert!(duty <= self.get_max_duty()); 185 assert!(duty <= self.get_max_duty());
182 self.inner.set_compare_value(channel, duty) 186 sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty)
183 } 187 }
184 188
185 fn set_period<P>(&mut self, period: P) 189 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 f66b4d094..2f5d5770a 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -2,8 +2,6 @@
2 2
3// Timer inheritance 3// Timer inheritance
4// 4//
5// CaptureCompare16bitInstance ComplementaryCaptureCompare16bitInstance
6// v v
7// Core -------------------------> 1CH -------------------------> 1CH_CMP 5// Core -------------------------> 1CH -------------------------> 1CH_CMP
8// | | ^ | 6// | | ^ |
9// +--> Basic_NoCr2 --> Basic +--> 2CH --> GP16 --> GP32 | +--> 2CH_CMP --> ADV 7// +--> Basic_NoCr2 --> Basic +--> 2CH --> GP16 --> GP32 | +--> 2CH_CMP --> ADV
@@ -33,6 +31,156 @@ pub mod low_level {
33pub(crate) mod sealed { 31pub(crate) mod sealed {
34 use super::*; 32 use super::*;
35 33
34 macro_rules! add_capture_compare_common_methods {
35 ($regs:ident) => {
36 /// Set input capture filter.
37 fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) {
38 let raw_channel = channel.index();
39 Self::$regs()
40 .ccmr_input(raw_channel / 2)
41 .modify(|r| r.set_icf(raw_channel % 2, icf));
42 }
43
44 /// Clear input interrupt.
45 fn clear_input_interrupt(&mut self, channel: Channel) {
46 Self::$regs().sr().modify(|r| r.set_ccif(channel.index(), false));
47 }
48
49 /// Enable input interrupt.
50 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) {
51 Self::$regs()
52 .dier()
53 .modify(|r| r.set_ccie(channel.index(), enable));
54 }
55
56 /// Set input capture prescaler.
57 fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) {
58 let raw_channel = channel.index();
59 Self::$regs()
60 .ccmr_input(raw_channel / 2)
61 .modify(|r| r.set_icpsc(raw_channel % 2, factor));
62 }
63
64 /// Set input TI selection.
65 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) {
66 let raw_channel = channel.index();
67 Self::$regs()
68 .ccmr_input(raw_channel / 2)
69 .modify(|r| r.set_ccs(raw_channel % 2, tisel.into()));
70 }
71
72 /// Set input capture mode.
73 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) {
74 Self::$regs().ccer().modify(|r| match mode {
75 InputCaptureMode::Rising => {
76 r.set_ccnp(channel.index(), false);
77 r.set_ccp(channel.index(), false);
78 }
79 InputCaptureMode::Falling => {
80 r.set_ccnp(channel.index(), false);
81 r.set_ccp(channel.index(), true);
82 }
83 InputCaptureMode::BothEdges => {
84 r.set_ccnp(channel.index(), true);
85 r.set_ccp(channel.index(), true);
86 }
87 });
88 }
89
90 /// Set output compare mode.
91 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
92 let r = Self::$regs();
93 let raw_channel: usize = channel.index();
94 r.ccmr_output(raw_channel / 2)
95 .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
96 }
97
98 /// Set output polarity.
99 fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
100 Self::$regs()
101 .ccer()
102 .modify(|w| w.set_ccp(channel.index(), polarity.into()));
103 }
104
105 /// Enable/disable a channel.
106 fn enable_channel(&mut self, channel: Channel, enable: bool) {
107 Self::$regs()
108 .ccer()
109 .modify(|w| w.set_cce(channel.index(), enable));
110 }
111
112 /// Get enable/disable state of a channel
113 fn get_channel_enable_state(&self, channel: Channel) -> bool {
114 Self::$regs().ccer().read().cce(channel.index())
115 }
116
117 /// Set compare value for a channel.
118 fn set_compare_value(&mut self, channel: Channel, value: u16) {
119 Self::$regs().ccr(channel.index()).modify(|w| w.set_ccr(value));
120 }
121
122 /// Get capture value for a channel.
123 fn get_capture_value(&mut self, channel: Channel) -> u16 {
124 Self::$regs().ccr(channel.index()).read().ccr()
125 }
126
127 /// Get compare value for a channel.
128 fn get_compare_value(&self, channel: Channel) -> u16 {
129 Self::$regs().ccr(channel.index()).read().ccr()
130 }
131
132 /// Set output compare preload.
133 fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) {
134 let channel_index = channel.index();
135 Self::regs_1ch()
136 .ccmr_output(channel_index / 2)
137 .modify(|w| w.set_ocpe(channel_index % 2, preload));
138 }
139 };
140 }
141
142 macro_rules! add_capture_compare_dma_methods {
143 ($regs:ident) => {
144 /// Get capture compare DMA selection
145 fn get_cc_dma_selection(&self) -> super::vals::Ccds {
146 Self::$regs().cr2().read().ccds()
147 }
148
149 /// Set capture compare DMA selection
150 fn set_cc_dma_selection(&mut self, ccds: super::vals::Ccds) {
151 Self::$regs().cr2().modify(|w| w.set_ccds(ccds))
152 }
153
154 /// Get capture compare DMA enable state
155 fn get_cc_dma_enable_state(&self, channel: Channel) -> bool {
156 Self::$regs().dier().read().ccde(channel.index())
157 }
158
159 /// Set capture compare DMA enable state
160 fn set_cc_dma_enable_state(&mut self, channel: Channel, ccde: bool) {
161 Self::$regs().dier().modify(|w| w.set_ccde(channel.index(), ccde))
162 }
163 };
164 }
165
166 macro_rules! add_complementary_capture_compare_methods {
167 ($regs:ident) => {
168 /// Set complementary output polarity.
169 fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
170 Self::$regs()
171 .ccer()
172 .modify(|w| w.set_ccnp(channel.index(), polarity.into()));
173 }
174
175 /// Enable/disable a complementary channel.
176 fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) {
177 Self::$regs()
178 .ccer()
179 .modify(|w| w.set_ccne(channel.index(), enable));
180 }
181 };
182 }
183
36 /// Virtual Core 16-bit timer instance. 184 /// Virtual Core 16-bit timer instance.
37 pub trait CoreInstance: RccPeripheral { 185 pub trait CoreInstance: RccPeripheral {
38 /// Interrupt for this timer. 186 /// Interrupt for this timer.
@@ -171,6 +319,13 @@ pub(crate) mod sealed {
171 fn set_clock_division(&mut self, ckd: vals::Ckd) { 319 fn set_clock_division(&mut self, ckd: vals::Ckd) {
172 Self::regs_1ch().cr1().modify(|r| r.set_ckd(ckd)); 320 Self::regs_1ch().cr1().modify(|r| r.set_ckd(ckd));
173 } 321 }
322
323 /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC.
324 fn get_max_compare_value(&self) -> u16 {
325 Self::regs_1ch().arr().read().arr()
326 }
327
328 add_capture_compare_common_methods!(regs_1ch);
174 } 329 }
175 330
176 /// Gneral-purpose 1 channel 16-bit timer instance. 331 /// Gneral-purpose 1 channel 16-bit timer instance.
@@ -182,6 +337,8 @@ pub(crate) mod sealed {
182 /// for a given set of capabilities, and having it transparently work with 337 /// for a given set of capabilities, and having it transparently work with
183 /// more capable timers. 338 /// more capable timers.
184 fn regs_2ch() -> crate::pac::timer::Tim2ch; 339 fn regs_2ch() -> crate::pac::timer::Tim2ch;
340
341 add_capture_compare_common_methods!(regs_2ch);
185 } 342 }
186 343
187 /// Gneral-purpose 16-bit timer instance. 344 /// Gneral-purpose 16-bit timer instance.
@@ -212,6 +369,9 @@ pub(crate) mod sealed {
212 let cr1 = Self::regs_gp16().cr1().read(); 369 let cr1 = Self::regs_gp16().cr1().read();
213 (cr1.cms(), cr1.dir()).into() 370 (cr1.cms(), cr1.dir()).into()
214 } 371 }
372
373 add_capture_compare_common_methods!(regs_gp16);
374 add_capture_compare_dma_methods!(regs_gp16);
215 } 375 }
216 376
217 /// Gneral-purpose 32-bit timer instance. 377 /// Gneral-purpose 32-bit timer instance.
@@ -252,6 +412,26 @@ pub(crate) mod sealed {
252 412
253 timer_f / arr / (psc + 1) 413 timer_f / arr / (psc + 1)
254 } 414 }
415
416 /// Set comapre value for a channel.
417 fn set_compare_value(&mut self, channel: Channel, value: u32) {
418 Self::regs_gp32().ccr(channel.index()).modify(|w| w.set_ccr(value));
419 }
420
421 /// Get capture value for a channel.
422 fn get_capture_value(&mut self, channel: Channel) -> u32 {
423 Self::regs_gp32().ccr(channel.index()).read().ccr()
424 }
425
426 /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC.
427 fn get_max_compare_value(&self) -> u32 {
428 Self::regs_gp32().arr().read().arr()
429 }
430
431 /// Get compare value for a channel.
432 fn get_compare_value(&self, channel: Channel) -> u32 {
433 Self::regs_gp32().ccr(channel.index()).read().ccr()
434 }
255 } 435 }
256 436
257 /// Gneral-purpose 1 channel with one complementary 16-bit timer instance. 437 /// Gneral-purpose 1 channel with one complementary 16-bit timer instance.
@@ -264,15 +444,27 @@ pub(crate) mod sealed {
264 /// more capable timers. 444 /// more capable timers.
265 fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp; 445 fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp;
266 446
447 /// Set clock divider for the dead time.
448 fn set_dead_time_clock_division(&mut self, value: vals::Ckd) {
449 Self::regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value));
450 }
451
452 /// Set dead time, as a fraction of the max duty value.
453 fn set_dead_time_value(&mut self, value: u8) {
454 Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value));
455 }
456
267 /// Enable timer outputs. 457 /// Enable timer outputs.
268 fn enable_outputs(&mut self) { 458 fn enable_outputs(&mut self) {
269 Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); 459 Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true));
270 } 460 }
461
462 add_complementary_capture_compare_methods!(regs_1ch_cmp);
271 } 463 }
272 464
273 /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. 465 /// Gneral-purpose 2 channel with one complementary 16-bit timer instance.
274 pub trait GeneralPurpose2ChannelComplementaryInstance: 466 pub trait GeneralPurpose2ChannelComplementaryInstance:
275 BasicInstance + GeneralPurpose1ChannelComplementaryInstance 467 BasicInstance + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance
276 { 468 {
277 /// Get access to the general purpose 2 channel with one complementary 16bit timer registers. 469 /// Get access to the general purpose 2 channel with one complementary 16bit timer registers.
278 /// 470 ///
@@ -281,6 +473,8 @@ pub(crate) mod sealed {
281 /// for a given set of capabilities, and having it transparently work with 473 /// for a given set of capabilities, and having it transparently work with
282 /// more capable timers. 474 /// more capable timers.
283 fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp; 475 fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp;
476
477 add_complementary_capture_compare_methods!(regs_2ch_cmp);
284 } 478 }
285 479
286 /// Advanced control timer instance. 480 /// Advanced control timer instance.
@@ -289,186 +483,8 @@ pub(crate) mod sealed {
289 { 483 {
290 /// Get access to the advanced timer registers. 484 /// Get access to the advanced timer registers.
291 fn regs_advanced() -> crate::pac::timer::TimAdv; 485 fn regs_advanced() -> crate::pac::timer::TimAdv;
292 }
293
294 /// Capture/Compare 16-bit timer instance.
295 pub trait CaptureCompare16bitInstance: GeneralPurpose1ChannelInstance {
296 /// Set input capture filter.
297 fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) {
298 let raw_channel = channel.index();
299 Self::regs_1ch()
300 .ccmr_input(raw_channel / 2)
301 .modify(|r| r.set_icf(raw_channel % 2, icf));
302 }
303
304 /// Clear input interrupt.
305 fn clear_input_interrupt(&mut self, channel: Channel) {
306 Self::regs_1ch().sr().modify(|r| r.set_ccif(channel.index(), false));
307 }
308
309 /// Enable input interrupt.
310 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) {
311 Self::regs_1ch().dier().modify(|r| r.set_ccie(channel.index(), enable));
312 }
313
314 /// Set input capture prescaler.
315 fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) {
316 let raw_channel = channel.index();
317 Self::regs_1ch()
318 .ccmr_input(raw_channel / 2)
319 .modify(|r| r.set_icpsc(raw_channel % 2, factor));
320 }
321
322 /// Set input TI selection.
323 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) {
324 let raw_channel = channel.index();
325 Self::regs_1ch()
326 .ccmr_input(raw_channel / 2)
327 .modify(|r| r.set_ccs(raw_channel % 2, tisel.into()));
328 }
329
330 /// Set input capture mode.
331 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) {
332 Self::regs_1ch().ccer().modify(|r| match mode {
333 InputCaptureMode::Rising => {
334 r.set_ccnp(channel.index(), false);
335 r.set_ccp(channel.index(), false);
336 }
337 InputCaptureMode::Falling => {
338 r.set_ccnp(channel.index(), false);
339 r.set_ccp(channel.index(), true);
340 }
341 InputCaptureMode::BothEdges => {
342 r.set_ccnp(channel.index(), true);
343 r.set_ccp(channel.index(), true);
344 }
345 });
346 }
347
348 /// Set output compare mode.
349 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
350 let r = Self::regs_1ch();
351 let raw_channel: usize = channel.index();
352 r.ccmr_output(raw_channel / 2)
353 .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
354 }
355
356 /// Set output polarity.
357 fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
358 Self::regs_1ch()
359 .ccer()
360 .modify(|w| w.set_ccp(channel.index(), polarity.into()));
361 }
362
363 /// Enable/disable a channel.
364 fn enable_channel(&mut self, channel: Channel, enable: bool) {
365 Self::regs_1ch().ccer().modify(|w| w.set_cce(channel.index(), enable));
366 }
367
368 /// Get enable/disable state of a channel
369 fn get_channel_enable_state(&self, channel: Channel) -> bool {
370 Self::regs_1ch().ccer().read().cce(channel.index())
371 }
372
373 /// Set compare value for a channel.
374 fn set_compare_value(&mut self, channel: Channel, value: u16) {
375 Self::regs_1ch().ccr(channel.index()).modify(|w| w.set_ccr(value));
376 }
377
378 /// Get capture value for a channel.
379 fn get_capture_value(&mut self, channel: Channel) -> u16 {
380 Self::regs_1ch().ccr(channel.index()).read().ccr()
381 }
382
383 /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC.
384 fn get_max_compare_value(&self) -> u16 {
385 Self::regs_1ch().arr().read().arr()
386 }
387
388 /// Get compare value for a channel.
389 fn get_compare_value(&self, channel: Channel) -> u16 {
390 Self::regs_1ch().ccr(channel.index()).read().ccr()
391 }
392
393 /// Set output compare preload.
394 fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) {
395 let channel_index = channel.index();
396 Self::regs_1ch()
397 .ccmr_output(channel_index / 2)
398 .modify(|w| w.set_ocpe(channel_index % 2, preload));
399 }
400
401 /// Get capture compare DMA selection
402 fn get_cc_dma_selection(&self) -> super::vals::Ccds {
403 Self::regs_gp16().cr2().read().ccds()
404 }
405
406 /// Set capture compare DMA selection
407 fn set_cc_dma_selection(&mut self, ccds: super::vals::Ccds) {
408 Self::regs_gp16().cr2().modify(|w| w.set_ccds(ccds))
409 }
410
411 /// Get capture compare DMA enable state
412 fn get_cc_dma_enable_state(&self, channel: Channel) -> bool {
413 Self::regs_gp16().dier().read().ccde(channel.index())
414 }
415
416 /// Set capture compare DMA enable state
417 fn set_cc_dma_enable_state(&mut self, channel: Channel, ccde: bool) {
418 Self::regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde))
419 }
420 }
421
422 /// Capture/Compare 16-bit timer instance with complementary pin support.
423 pub trait ComplementaryCaptureCompare16bitInstance:
424 CaptureCompare16bitInstance + GeneralPurpose1ChannelComplementaryInstance
425 {
426 /// Set complementary output polarity.
427 fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
428 Self::regs_1ch_cmp()
429 .ccer()
430 .modify(|w| w.set_ccnp(channel.index(), polarity.into()));
431 }
432
433 /// Set clock divider for the dead time.
434 fn set_dead_time_clock_division(&mut self, value: vals::Ckd) {
435 Self::regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value));
436 }
437
438 /// Set dead time, as a fraction of the max duty value.
439 fn set_dead_time_value(&mut self, value: u8) {
440 Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value));
441 }
442
443 /// Enable/disable a complementary channel.
444 fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) {
445 Self::regs_1ch_cmp()
446 .ccer()
447 .modify(|w| w.set_ccne(channel.index(), enable));
448 }
449 }
450
451 /// Capture/Compare 32-bit timer instance.
452 pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance + CaptureCompare16bitInstance {
453 /// Set comapre value for a channel.
454 fn set_compare_value(&mut self, channel: Channel, value: u32) {
455 Self::regs_gp32().ccr(channel.index()).modify(|w| w.set_ccr(value));
456 }
457
458 /// Get capture value for a channel.
459 fn get_capture_value(&mut self, channel: Channel) -> u32 {
460 Self::regs_gp32().ccr(channel.index()).read().ccr()
461 }
462
463 /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC.
464 fn get_max_compare_value(&self) -> u32 {
465 Self::regs_gp32().arr().read().arr()
466 }
467 486
468 /// Get compare value for a channel. 487 add_complementary_capture_compare_methods!(regs_advanced);
469 fn get_compare_value(&self, channel: Channel) -> u32 {
470 Self::regs_gp32().ccr(channel.index()).read().ccr()
471 }
472 } 488 }
473} 489}
474 490
@@ -699,6 +715,7 @@ pub trait GeneralPurpose1ChannelComplementaryInstance:
699pub trait GeneralPurpose2ChannelComplementaryInstance: 715pub trait GeneralPurpose2ChannelComplementaryInstance:
700 sealed::GeneralPurpose2ChannelComplementaryInstance 716 sealed::GeneralPurpose2ChannelComplementaryInstance
701 + BasicInstance 717 + BasicInstance
718 + GeneralPurpose2ChannelInstance
702 + GeneralPurpose1ChannelComplementaryInstance 719 + GeneralPurpose1ChannelComplementaryInstance
703 + 'static 720 + 'static
704{ 721{
@@ -710,42 +727,30 @@ pub trait AdvancedControlInstance:
710{ 727{
711} 728}
712 729
713/// Capture/Compare 16-bit timer instance. 730pin_trait!(Channel1Pin, GeneralPurpose1ChannelInstance);
714pub trait CaptureCompare16bitInstance: 731pin_trait!(Channel2Pin, GeneralPurpose2ChannelInstance);
715 sealed::CaptureCompare16bitInstance + GeneralPurpose1ChannelInstance + 'static 732pin_trait!(Channel3Pin, GeneralPurpose16bitInstance);
716{ 733pin_trait!(Channel4Pin, GeneralPurpose16bitInstance);
717}
718 734
719/// Capture/Compare 16-bit timer instance with complementary pin support. 735#[cfg(not(stm32l0))]
720pub trait ComplementaryCaptureCompare16bitInstance: 736pin_trait!(ExternalTriggerPin, GeneralPurpose16bitInstance);
721 sealed::ComplementaryCaptureCompare16bitInstance
722 + CaptureCompare16bitInstance
723 + GeneralPurpose1ChannelComplementaryInstance
724 + 'static
725{
726}
727 737
728/// Capture/Compare 32-bit timer instance. 738#[cfg(stm32l0)]
729pub trait CaptureCompare32bitInstance: 739pin_trait!(ExternalTriggerPin, GeneralPurpose2ChannelInstance);
730 sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + GeneralPurpose32bitInstance + 'static 740
731{ 741pin_trait!(Channel1ComplementaryPin, GeneralPurpose1ChannelComplementaryInstance);
732} 742pin_trait!(Channel2ComplementaryPin, GeneralPurpose2ChannelComplementaryInstance);
743pin_trait!(Channel3ComplementaryPin, AdvancedControlInstance);
744pin_trait!(Channel4ComplementaryPin, AdvancedControlInstance);
745
746pin_trait!(BreakInputPin, GeneralPurpose1ChannelComplementaryInstance);
747pin_trait!(BreakInput2Pin, GeneralPurpose2ChannelComplementaryInstance);
733 748
734pin_trait!(Channel1Pin, CaptureCompare16bitInstance); 749pin_trait!(BreakInputComparator1Pin, GeneralPurpose1ChannelComplementaryInstance);
735pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance); 750pin_trait!(BreakInputComparator2Pin, AdvancedControlInstance);
736pin_trait!(Channel2Pin, CaptureCompare16bitInstance); 751
737pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance); 752pin_trait!(BreakInput2Comparator1Pin, AdvancedControlInstance);
738pin_trait!(Channel3Pin, CaptureCompare16bitInstance); 753pin_trait!(BreakInput2Comparator2Pin, AdvancedControlInstance);
739pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance);
740pin_trait!(Channel4Pin, CaptureCompare16bitInstance);
741pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance);
742pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance);
743pin_trait!(BreakInputPin, CaptureCompare16bitInstance);
744pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance);
745pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance);
746pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
747pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
748pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
749 754
750#[allow(unused)] 755#[allow(unused)]
751macro_rules! impl_core_timer { 756macro_rules! impl_core_timer {
@@ -859,27 +864,6 @@ macro_rules! impl_adv_timer {
859 }; 864 };
860} 865}
861 866
862#[allow(unused)]
863macro_rules! impl_compare_capable_16bit {
864 ($inst:ident) => {
865 impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {}
866 };
867}
868
869#[allow(unused)]
870macro_rules! impl_compare_capable_32bit {
871 ($inst:ident) => {
872 impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {}
873 };
874}
875
876#[allow(unused)]
877macro_rules! impl_compare_capable_complementary_16bit {
878 ($inst:ident) => {
879 impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
880 };
881}
882
883foreach_interrupt! { 867foreach_interrupt! {
884 868
885 ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { 869 ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => {
@@ -894,21 +878,17 @@ foreach_interrupt! {
894 ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => { 878 ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => {
895 impl_core_timer!($inst, $irq); 879 impl_core_timer!($inst, $irq);
896 impl_1ch_timer!($inst); 880 impl_1ch_timer!($inst);
897 impl_compare_capable_16bit!($inst);
898 impl CoreInstance for crate::peripherals::$inst {} 881 impl CoreInstance for crate::peripherals::$inst {}
899 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 882 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {}
900 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
901 }; 883 };
902 884
903 885
904 ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { 886 ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => {
905 impl_core_timer!($inst, $irq); 887 impl_core_timer!($inst, $irq);
906 impl_1ch_timer!($inst); 888 impl_1ch_timer!($inst);
907 impl_compare_capable_16bit!($inst);
908 impl_2ch_timer!($inst); 889 impl_2ch_timer!($inst);
909 impl CoreInstance for crate::peripherals::$inst {} 890 impl CoreInstance for crate::peripherals::$inst {}
910 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 891 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {}
911 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
912 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} 892 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {}
913 }; 893 };
914 894
@@ -917,14 +897,12 @@ foreach_interrupt! {
917 impl_basic_no_cr2_timer!($inst); 897 impl_basic_no_cr2_timer!($inst);
918 impl_basic_timer!($inst); 898 impl_basic_timer!($inst);
919 impl_1ch_timer!($inst); 899 impl_1ch_timer!($inst);
920 impl_compare_capable_16bit!($inst);
921 impl_2ch_timer!($inst); 900 impl_2ch_timer!($inst);
922 impl_gp_16bit_timer!($inst); 901 impl_gp_16bit_timer!($inst);
923 impl CoreInstance for crate::peripherals::$inst {} 902 impl CoreInstance for crate::peripherals::$inst {}
924 impl BasicNoCr2Instance for crate::peripherals::$inst{} 903 impl BasicNoCr2Instance for crate::peripherals::$inst{}
925 impl BasicInstance for crate::peripherals::$inst {} 904 impl BasicInstance for crate::peripherals::$inst {}
926 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 905 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {}
927 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
928 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} 906 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {}
929 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} 907 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
930 }; 908 };
@@ -934,8 +912,6 @@ foreach_interrupt! {
934 impl_basic_no_cr2_timer!($inst); 912 impl_basic_no_cr2_timer!($inst);
935 impl_basic_timer!($inst); 913 impl_basic_timer!($inst);
936 impl_1ch_timer!($inst); 914 impl_1ch_timer!($inst);
937 impl_compare_capable_16bit!($inst);
938 impl_compare_capable_32bit!($inst);
939 impl_2ch_timer!($inst); 915 impl_2ch_timer!($inst);
940 impl_gp_16bit_timer!($inst); 916 impl_gp_16bit_timer!($inst);
941 impl_gp_32bit_timer!($inst); 917 impl_gp_32bit_timer!($inst);
@@ -943,8 +919,6 @@ foreach_interrupt! {
943 impl BasicNoCr2Instance for crate::peripherals::$inst{} 919 impl BasicNoCr2Instance for crate::peripherals::$inst{}
944 impl BasicInstance for crate::peripherals::$inst {} 920 impl BasicInstance for crate::peripherals::$inst {}
945 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 921 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {}
946 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
947 impl CaptureCompare32bitInstance for crate::peripherals::$inst {}
948 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} 922 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {}
949 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} 923 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
950 impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} 924 impl GeneralPurpose32bitInstance for crate::peripherals::$inst {}
@@ -954,15 +928,11 @@ foreach_interrupt! {
954 impl_core_timer!($inst, $irq); 928 impl_core_timer!($inst, $irq);
955 impl_basic_no_cr2_timer!($inst); 929 impl_basic_no_cr2_timer!($inst);
956 impl_1ch_timer!($inst); 930 impl_1ch_timer!($inst);
957 impl_compare_capable_16bit!($inst);
958 impl_1ch_cmp_timer!($inst); 931 impl_1ch_cmp_timer!($inst);
959 impl_compare_capable_complementary_16bit!($inst);
960 impl CoreInstance for crate::peripherals::$inst {} 932 impl CoreInstance for crate::peripherals::$inst {}
961 impl BasicNoCr2Instance for crate::peripherals::$inst{} 933 impl BasicNoCr2Instance for crate::peripherals::$inst{}
962 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 934 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {}
963 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
964 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} 935 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {}
965 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
966 }; 936 };
967 937
968 938
@@ -971,17 +941,15 @@ foreach_interrupt! {
971 impl_basic_no_cr2_timer!($inst); 941 impl_basic_no_cr2_timer!($inst);
972 impl_basic_timer!($inst); 942 impl_basic_timer!($inst);
973 impl_1ch_timer!($inst); 943 impl_1ch_timer!($inst);
974 impl_compare_capable_16bit!($inst); 944 impl_2ch_timer!($inst);
975 impl_1ch_cmp_timer!($inst); 945 impl_1ch_cmp_timer!($inst);
976 impl_compare_capable_complementary_16bit!($inst);
977 impl_2ch_cmp_timer!($inst); 946 impl_2ch_cmp_timer!($inst);
978 impl CoreInstance for crate::peripherals::$inst {} 947 impl CoreInstance for crate::peripherals::$inst {}
979 impl BasicNoCr2Instance for crate::peripherals::$inst{} 948 impl BasicNoCr2Instance for crate::peripherals::$inst{}
980 impl BasicInstance for crate::peripherals::$inst {} 949 impl BasicInstance for crate::peripherals::$inst {}
981 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 950 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {}
982 impl CaptureCompare16bitInstance for crate::peripherals::$inst {} 951 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {}
983 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} 952 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {}
984 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
985 impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} 953 impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {}
986 }; 954 };
987 955
@@ -992,10 +960,8 @@ foreach_interrupt! {
992 impl_basic_timer!($inst); 960 impl_basic_timer!($inst);
993 impl_1ch_timer!($inst); 961 impl_1ch_timer!($inst);
994 impl_2ch_timer!($inst); 962 impl_2ch_timer!($inst);
995 impl_compare_capable_16bit!($inst);
996 impl_1ch_cmp_timer!($inst); 963 impl_1ch_cmp_timer!($inst);
997 impl_gp_16bit_timer!($inst); 964 impl_gp_16bit_timer!($inst);
998 impl_compare_capable_complementary_16bit!($inst);
999 impl_2ch_cmp_timer!($inst); 965 impl_2ch_cmp_timer!($inst);
1000 impl_adv_timer!($inst); 966 impl_adv_timer!($inst);
1001 impl CoreInstance for crate::peripherals::$inst {} 967 impl CoreInstance for crate::peripherals::$inst {}
@@ -1004,9 +970,7 @@ foreach_interrupt! {
1004 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} 970 impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {}
1005 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} 971 impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {}
1006 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} 972 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
1007 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
1008 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} 973 impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {}
1009 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
1010 impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} 974 impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {}
1011 impl AdvancedControlInstance for crate::peripherals::$inst {} 975 impl AdvancedControlInstance for crate::peripherals::$inst {}
1012 }; 976 };
@@ -1015,7 +979,7 @@ foreach_interrupt! {
1015// Update Event trigger DMA for every timer 979// Update Event trigger DMA for every timer
1016dma_trait!(UpDma, BasicNoCr2Instance); 980dma_trait!(UpDma, BasicNoCr2Instance);
1017 981
1018dma_trait!(Ch1Dma, CaptureCompare16bitInstance); 982dma_trait!(Ch1Dma, GeneralPurpose1ChannelInstance);
1019dma_trait!(Ch2Dma, CaptureCompare16bitInstance); 983dma_trait!(Ch2Dma, GeneralPurpose2ChannelInstance);
1020dma_trait!(Ch3Dma, CaptureCompare16bitInstance); 984dma_trait!(Ch3Dma, GeneralPurpose16bitInstance);
1021dma_trait!(Ch4Dma, CaptureCompare16bitInstance); 985dma_trait!(Ch4Dma, GeneralPurpose16bitInstance);
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs
index 75e5ab12a..7e56312bb 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: CaptureCompare16bitInstance> QeiPin<'d, T, $channel> { 33 impl<'d, T: GeneralPurpose16bitInstance> 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 + CaptureCompare16bitInstance> Qei<'d, T> { 60impl<'d, T: GeneralPurpose16bitInstance> 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 1c665d456..088d02c97 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -1,6 +1,7 @@
1//! Simple PWM driver. 1//! Simple PWM driver.
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::ops::{Deref, DerefMut};
4 5
5use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
6 7
@@ -30,7 +31,7 @@ pub struct PwmPin<'d, T, C> {
30 31
31macro_rules! channel_impl { 32macro_rules! channel_impl {
32 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 33 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
33 impl<'d, T: CaptureCompare16bitInstance> PwmPin<'d, T, $channel> { 34 impl<'d, T: GeneralPurpose16bitInstance> PwmPin<'d, T, $channel> {
34 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] 35 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
35 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { 36 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self {
36 into_ref!(pin); 37 into_ref!(pin);
@@ -59,7 +60,7 @@ pub struct SimplePwm<'d, T> {
59 inner: PeripheralRef<'d, T>, 60 inner: PeripheralRef<'d, T>,
60} 61}
61 62
62impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm<'d, T> { 63impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> {
63 /// Create a new simple PWM driver. 64 /// Create a new simple PWM driver.
64 pub fn new( 65 pub fn new(
65 tim: impl Peripheral<P = T> + 'd, 66 tim: impl Peripheral<P = T> + 'd,
@@ -87,8 +88,13 @@ impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm
87 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] 88 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4]
88 .iter() 89 .iter()
89 .for_each(|&channel| { 90 .for_each(|&channel| {
90 this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); 91 sealed::GeneralPurpose16bitInstance::set_output_compare_mode(
91 this.inner.set_output_compare_preload(channel, true) 92 this.inner.deref_mut(),
93 channel,
94 OutputCompareMode::PwmMode1,
95 );
96
97 sealed::GeneralPurpose16bitInstance::set_output_compare_preload(this.inner.deref_mut(), channel, true);
92 }); 98 });
93 99
94 this 100 this
@@ -96,17 +102,17 @@ impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm
96 102
97 /// Enable the given channel. 103 /// Enable the given channel.
98 pub fn enable(&mut self, channel: Channel) { 104 pub fn enable(&mut self, channel: Channel) {
99 self.inner.enable_channel(channel, true); 105 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true);
100 } 106 }
101 107
102 /// Disable the given channel. 108 /// Disable the given channel.
103 pub fn disable(&mut self, channel: Channel) { 109 pub fn disable(&mut self, channel: Channel) {
104 self.inner.enable_channel(channel, false); 110 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false);
105 } 111 }
106 112
107 /// Check whether given channel is enabled 113 /// Check whether given channel is enabled
108 pub fn is_enabled(&self, channel: Channel) -> bool { 114 pub fn is_enabled(&self, channel: Channel) -> bool {
109 self.inner.get_channel_enable_state(channel) 115 sealed::GeneralPurpose16bitInstance::get_channel_enable_state(self.inner.deref(), channel)
110 } 116 }
111 117
112 /// Set PWM frequency. 118 /// Set PWM frequency.
@@ -134,24 +140,24 @@ impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm
134 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 140 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
135 pub fn set_duty(&mut self, channel: Channel, duty: u16) { 141 pub fn set_duty(&mut self, channel: Channel, duty: u16) {
136 assert!(duty <= self.get_max_duty()); 142 assert!(duty <= self.get_max_duty());
137 self.inner.set_compare_value(channel, duty) 143 sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty)
138 } 144 }
139 145
140 /// Get the duty for a given channel. 146 /// Get the duty for a given channel.
141 /// 147 ///
142 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 148 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
143 pub fn get_duty(&self, channel: Channel) -> u16 { 149 pub fn get_duty(&self, channel: Channel) -> u16 {
144 self.inner.get_compare_value(channel) 150 sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel)
145 } 151 }
146 152
147 /// Set the output polarity for a given channel. 153 /// Set the output polarity for a given channel.
148 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { 154 pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
149 self.inner.set_output_polarity(channel, polarity); 155 sealed::GeneralPurpose16bitInstance::set_output_polarity(self.inner.deref_mut(), channel, polarity);
150 } 156 }
151 157
152 /// Set the output compare mode for a given channel. 158 /// Set the output compare mode for a given channel.
153 pub fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { 159 pub fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
154 self.inner.set_output_compare_mode(channel, mode); 160 sealed::GeneralPurpose16bitInstance::set_output_compare_mode(self.inner.deref_mut(), channel, mode);
155 } 161 }
156 162
157 /// Generate a sequence of PWM waveform 163 /// Generate a sequence of PWM waveform
@@ -226,7 +232,7 @@ impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm
226 232
227macro_rules! impl_waveform_chx { 233macro_rules! impl_waveform_chx {
228 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { 234 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => {
229 impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { 235 impl<'d, T: GeneralPurpose16bitInstance> SimplePwm<'d, T> {
230 /// Generate a sequence of PWM waveform 236 /// Generate a sequence of PWM waveform
231 /// 237 ///
232 /// Note: 238 /// Note:
@@ -313,17 +319,17 @@ impl_waveform_chx!(waveform_ch2, Ch2Dma, Ch2);
313impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3); 319impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3);
314impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4); 320impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4);
315 321
316impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { 322impl<'d, T: GeneralPurpose16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> {
317 type Channel = Channel; 323 type Channel = Channel;
318 type Time = Hertz; 324 type Time = Hertz;
319 type Duty = u16; 325 type Duty = u16;
320 326
321 fn disable(&mut self, channel: Self::Channel) { 327 fn disable(&mut self, channel: Self::Channel) {
322 self.inner.enable_channel(channel, false); 328 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, false);
323 } 329 }
324 330
325 fn enable(&mut self, channel: Self::Channel) { 331 fn enable(&mut self, channel: Self::Channel) {
326 self.inner.enable_channel(channel, true); 332 sealed::GeneralPurpose16bitInstance::enable_channel(self.inner.deref_mut(), channel, true);
327 } 333 }
328 334
329 fn get_period(&self) -> Self::Time { 335 fn get_period(&self) -> Self::Time {
@@ -331,7 +337,7 @@ impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d,
331 } 337 }
332 338
333 fn get_duty(&self, channel: Self::Channel) -> Self::Duty { 339 fn get_duty(&self, channel: Self::Channel) -> Self::Duty {
334 self.inner.get_compare_value(channel) 340 sealed::GeneralPurpose16bitInstance::get_compare_value(self.inner.deref(), channel)
335 } 341 }
336 342
337 fn get_max_duty(&self) -> Self::Duty { 343 fn get_max_duty(&self) -> Self::Duty {
@@ -340,7 +346,7 @@ impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d,
340 346
341 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { 347 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) {
342 assert!(duty <= self.get_max_duty()); 348 assert!(duty <= self.get_max_duty());
343 self.inner.set_compare_value(channel, duty) 349 sealed::GeneralPurpose16bitInstance::set_compare_value(self.inner.deref_mut(), channel, duty)
344 } 350 }
345 351
346 fn set_period<P>(&mut self, period: P) 352 fn set_period<P>(&mut self, period: P)