aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Miller <[email protected]>2024-09-06 13:29:54 -0500
committerGrant Miller <[email protected]>2024-09-06 13:29:54 -0500
commitcfc76cec711447300e2d957439a32d6ad418a58c (patch)
tree35ed5afb8c766f65b61f2ebd58b063e37ee4e9a1
parentf7f062e0a3f303dfc4f976907b2555f2cfb48621 (diff)
Match embedded-hal api
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs105
1 files changed, 72 insertions, 33 deletions
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index 7179a7a59..23c727731 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -81,23 +81,45 @@ impl<'d, T: GeneralInstance4Channel> SimplePwmChannel<'d, T> {
81 /// Get max duty value. 81 /// Get max duty value.
82 /// 82 ///
83 /// This value depends on the configured frequency and the timer's clock rate from RCC. 83 /// This value depends on the configured frequency and the timer's clock rate from RCC.
84 pub fn get_max_duty(&self) -> u32 { 84 pub fn max_duty_cycle(&self) -> u16 {
85 self.timer.get_max_compare_value() + 1 85 unwrap!(self.timer.get_max_compare_value().checked_add(1))
86 } 86 }
87 87
88 /// Set the duty for a given channel. 88 /// Set the duty for a given channel.
89 /// 89 ///
90 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 90 /// The value ranges from 0 for 0% duty, to [`max_duty_cycle`](Self::max_duty_cycle) for 100% duty, both included.
91 pub fn set_duty(&mut self, duty: u32) { 91 pub fn set_duty_cycle(&mut self, duty: u16) {
92 assert!(duty <= self.get_max_duty()); 92 assert!(duty <= (*self).max_duty_cycle());
93 self.timer.set_compare_value(self.channel, duty) 93 self.timer.set_compare_value(self.channel, duty.into())
94 }
95
96 fn set_duty_cycle_fully_off(&mut self) {
97 self.set_duty_cycle(0);
98 }
99
100 fn set_duty_cycle_fully_on(&mut self) {
101 self.set_duty_cycle((*self).max_duty_cycle());
102 }
103
104 fn set_duty_cycle_fraction(&mut self, num: u16, denom: u16) {
105 assert!(denom != 0);
106 assert!(num <= denom);
107 let duty = u32::from(num) * u32::from(self.max_duty_cycle()) / u32::from(denom);
108
109 // This is safe because we know that `num <= denom`, so `duty <= self.max_duty_cycle()` (u16)
110 #[allow(clippy::cast_possible_truncation)]
111 self.set_duty_cycle(duty as u16);
112 }
113
114 fn set_duty_cycle_percent(&mut self, percent: u8) {
115 self.set_duty_cycle_fraction(u16::from(percent), 100)
94 } 116 }
95 117
96 /// Get the duty for a given channel. 118 /// Get the duty for a given channel.
97 /// 119 ///
98 /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. 120 /// The value ranges from 0 for 0% duty, to [`max_duty_cycle`](Self::max_duty_cycle) for 100% duty, both included.
99 pub fn get_duty(&self) -> u32 { 121 pub fn get_duty(&self) -> u16 {
100 self.timer.get_compare_value(self.channel) 122 unwrap!(self.timer.get_compare_value(self.channel).try_into())
101 } 123 }
102 124
103 /// Set the output polarity for a given channel. 125 /// Set the output polarity for a given channel.
@@ -123,25 +145,6 @@ pub struct SimplePwmChannels<'d, T: GeneralInstance4Channel> {
123 pub ch4: SimplePwmChannel<'d, T>, 145 pub ch4: SimplePwmChannel<'d, T>,
124} 146}
125 147
126impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> {
127 type Error = core::convert::Infallible;
128}
129
130impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::SetDutyCycle for SimplePwmChannel<'d, T> {
131 fn max_duty_cycle(&self) -> u16 {
132 // TODO: panics if CCR is 0xFFFF
133 // TODO: rename get_max_duty to max_duty_cycle
134 unwrap!(self.get_max_duty().try_into())
135 }
136
137 fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
138 self.set_duty(duty.into());
139 Ok(())
140 }
141
142 // TODO: default methods?
143}
144
145/// Simple PWM driver. 148/// Simple PWM driver.
146pub struct SimplePwm<'d, T: GeneralInstance4Channel> { 149pub struct SimplePwm<'d, T: GeneralInstance4Channel> {
147 inner: Timer<'d, T>, 150 inner: Timer<'d, T>,
@@ -253,6 +256,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
253 /// Note: when you call this, the max duty value changes, so you will have to 256 /// Note: when you call this, the max duty value changes, so you will have to
254 /// call `set_duty` on all channels with the duty calculated based on the new max duty. 257 /// call `set_duty` on all channels with the duty calculated based on the new max duty.
255 pub fn set_frequency(&mut self, freq: Hertz) { 258 pub fn set_frequency(&mut self, freq: Hertz) {
259 // TODO: prevent ARR = u16::MAX?
256 let multiplier = if self.inner.get_counting_mode().is_center_aligned() { 260 let multiplier = if self.inner.get_counting_mode().is_center_aligned() {
257 2u8 261 2u8
258 } else { 262 } else {
@@ -264,8 +268,8 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
264 /// Get max duty value. 268 /// Get max duty value.
265 /// 269 ///
266 /// This value depends on the configured frequency and the timer's clock rate from RCC. 270 /// This value depends on the configured frequency and the timer's clock rate from RCC.
267 pub fn get_max_duty(&self) -> u32 { 271 pub fn max_duty_cycle(&self) -> u16 {
268 self.inner.get_max_compare_value() + 1 272 unwrap!(self.inner.get_max_compare_value().checked_add(1))
269 } 273 }
270 274
271 /// Generate a sequence of PWM waveform 275 /// Generate a sequence of PWM waveform
@@ -323,7 +327,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
323 self.channel(channel).disable(); 327 self.channel(channel).disable();
324 } 328 }
325 329
326 self.channel(channel).set_duty(original_duty_state); 330 self.channel(channel).set_duty_cycle(original_duty_state);
327 331
328 // Since DMA is closed before timer update event trigger DMA is turn off, 332 // Since DMA is closed before timer update event trigger DMA is turn off,
329 // this can almost always trigger a DMA FIFO error. 333 // this can almost always trigger a DMA FIFO error.
@@ -399,7 +403,7 @@ macro_rules! impl_waveform_chx {
399 self.channel(cc_channel).disable(); 403 self.channel(cc_channel).disable();
400 } 404 }
401 405
402 self.channel(cc_channel).set_duty(original_duty_state); 406 self.channel(cc_channel).set_duty_cycle(original_duty_state);
403 407
404 // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off, 408 // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off,
405 // this can almost always trigger a DMA FIFO error. 409 // this can almost always trigger a DMA FIFO error.
@@ -423,6 +427,41 @@ impl_waveform_chx!(waveform_ch2, Ch2Dma, Ch2);
423impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3); 427impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3);
424impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4); 428impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4);
425 429
430impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> {
431 type Error = core::convert::Infallible;
432}
433
434impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::SetDutyCycle for SimplePwmChannel<'d, T> {
435 fn max_duty_cycle(&self) -> u16 {
436 self.max_duty_cycle()
437 }
438
439 fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
440 self.set_duty_cycle(duty);
441 Ok(())
442 }
443
444 fn set_duty_cycle_fully_off(&mut self) -> Result<(), Self::Error> {
445 self.set_duty_cycle_fully_off();
446 Ok(())
447 }
448
449 fn set_duty_cycle_fully_on(&mut self) -> Result<(), Self::Error> {
450 self.set_duty_cycle_fully_on();
451 Ok(())
452 }
453
454 fn set_duty_cycle_fraction(&mut self, num: u16, denom: u16) -> Result<(), Self::Error> {
455 self.set_duty_cycle_fraction(num, denom);
456 Ok(())
457 }
458
459 fn set_duty_cycle_percent(&mut self, percent: u8) -> Result<(), Self::Error> {
460 self.set_duty_cycle_percent(percent);
461 Ok(())
462 }
463}
464
426impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> { 465impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> {
427 type Channel = Channel; 466 type Channel = Channel;
428 type Time = Hertz; 467 type Time = Hertz;
@@ -449,7 +488,7 @@ impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> {
449 } 488 }
450 489
451 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { 490 fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) {
452 assert!(duty <= self.get_max_duty()); 491 assert!(duty <= self.max_duty_cycle() as u32);
453 self.inner.set_compare_value(channel, duty) 492 self.inner.set_compare_value(channel, duty)
454 } 493 }
455 494