diff options
| author | xoviat <[email protected]> | 2025-12-01 09:03:10 -0600 |
|---|---|---|
| committer | xoviat <[email protected]> | 2025-12-01 09:03:10 -0600 |
| commit | a1236b13c3d5fad687ae931a041ae463ac0612bb (patch) | |
| tree | c6328049f0f308e7c767b99f416279d679c65439 | |
| parent | 6638d4c85e00b624c3b30591f48af255548c4cc0 (diff) | |
timer: clamp compare value before dma
| -rw-r--r-- | embassy-stm32/src/dma/word.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/low_level.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 5 |
4 files changed, 21 insertions, 4 deletions
diff --git a/embassy-stm32/src/dma/word.rs b/embassy-stm32/src/dma/word.rs index fb1bde860..5c3bb8f7f 100644 --- a/embassy-stm32/src/dma/word.rs +++ b/embassy-stm32/src/dma/word.rs | |||
| @@ -31,6 +31,10 @@ pub trait Word: SealedWord + Default + Copy + 'static { | |||
| 31 | fn size() -> WordSize; | 31 | fn size() -> WordSize; |
| 32 | /// Amount of bits of this word size. | 32 | /// Amount of bits of this word size. |
| 33 | fn bits() -> usize; | 33 | fn bits() -> usize; |
| 34 | /// Maximum value of this type. | ||
| 35 | fn max() -> usize { | ||
| 36 | (1 << Self::bits()) - 1 | ||
| 37 | } | ||
| 34 | } | 38 | } |
| 35 | 39 | ||
| 36 | macro_rules! impl_word { | 40 | macro_rules! impl_word { |
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index b9434d37b..4d04af685 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -228,7 +228,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { | |||
| 228 | duty: &[W], | 228 | duty: &[W], |
| 229 | ) { | 229 | ) { |
| 230 | self.inner.enable_channel(channel, true); | 230 | self.inner.enable_channel(channel, true); |
| 231 | self.inner.set_compare_value(channel, 0.into()); | 231 | self.inner.clamp_compare_value::<W>(channel); |
| 232 | self.inner.enable_update_dma(true); | 232 | self.inner.enable_update_dma(true); |
| 233 | self.inner.setup_update_dma(dma, channel, duty).await; | 233 | self.inner.setup_update_dma(dma, channel, duty).await; |
| 234 | self.inner.enable_update_dma(false); | 234 | self.inner.enable_update_dma(false); |
| @@ -276,7 +276,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { | |||
| 276 | .filter(|ch| ch.index() <= ending_channel.index()) | 276 | .filter(|ch| ch.index() <= ending_channel.index()) |
| 277 | .for_each(|ch| { | 277 | .for_each(|ch| { |
| 278 | self.inner.enable_channel(*ch, true); | 278 | self.inner.enable_channel(*ch, true); |
| 279 | self.inner.set_compare_value(*ch, 0.into()); | 279 | self.inner.clamp_compare_value::<W>(*ch); |
| 280 | }); | 280 | }); |
| 281 | self.inner.enable_update_dma(true); | 281 | self.inner.enable_update_dma(true); |
| 282 | self.inner | 282 | self.inner |
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index 1af66aec1..6a70d2a40 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs | |||
| @@ -627,6 +627,18 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 627 | return unwrap!(self.regs_gp32_unchecked().ccr(channel.index()).read().ccr().try_into()); | 627 | return unwrap!(self.regs_gp32_unchecked().ccr(channel.index()).read().ccr().try_into()); |
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | pub(crate) fn clamp_compare_value<W: Word>(&mut self, channel: Channel) { | ||
| 631 | self.set_compare_value( | ||
| 632 | channel, | ||
| 633 | unwrap!( | ||
| 634 | self.get_compare_value(channel) | ||
| 635 | .into() | ||
| 636 | .clamp(0, W::max() as u32) | ||
| 637 | .try_into() | ||
| 638 | ), | ||
| 639 | ); | ||
| 640 | } | ||
| 641 | |||
| 630 | /// Setup a ring buffer for the channel | 642 | /// Setup a ring buffer for the channel |
| 631 | pub fn setup_ring_buffer<'a, W: Word + Into<T::Word>>( | 643 | pub fn setup_ring_buffer<'a, W: Word + Into<T::Word>>( |
| 632 | &mut self, | 644 | &mut self, |
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 3f37ffcd9..f4b84670f 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -179,6 +179,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwmChannel<'d, T> { | |||
| 179 | ) -> RingBufferedPwmChannel<'d, T, W> { | 179 | ) -> RingBufferedPwmChannel<'d, T, W> { |
| 180 | assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); | 180 | assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); |
| 181 | 181 | ||
| 182 | self.timer.clamp_compare_value::<W>(self.channel); | ||
| 182 | self.timer.enable_update_dma(true); | 183 | self.timer.enable_update_dma(true); |
| 183 | 184 | ||
| 184 | RingBufferedPwmChannel::new( | 185 | RingBufferedPwmChannel::new( |
| @@ -352,7 +353,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 352 | duty: &[W], | 353 | duty: &[W], |
| 353 | ) { | 354 | ) { |
| 354 | self.inner.enable_channel(channel, true); | 355 | self.inner.enable_channel(channel, true); |
| 355 | self.inner.set_compare_value(channel, 0.into()); | 356 | self.inner.clamp_compare_value::<W>(channel); |
| 356 | self.inner.enable_update_dma(true); | 357 | self.inner.enable_update_dma(true); |
| 357 | self.inner.setup_update_dma(dma, channel, duty).await; | 358 | self.inner.setup_update_dma(dma, channel, duty).await; |
| 358 | self.inner.enable_update_dma(false); | 359 | self.inner.enable_update_dma(false); |
| @@ -400,7 +401,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 400 | .filter(|ch| ch.index() <= ending_channel.index()) | 401 | .filter(|ch| ch.index() <= ending_channel.index()) |
| 401 | .for_each(|ch| { | 402 | .for_each(|ch| { |
| 402 | self.inner.enable_channel(*ch, true); | 403 | self.inner.enable_channel(*ch, true); |
| 403 | self.inner.set_compare_value(*ch, 0.into()); | 404 | self.inner.clamp_compare_value::<W>(*ch); |
| 404 | }); | 405 | }); |
| 405 | self.inner.enable_update_dma(true); | 406 | self.inner.enable_update_dma(true); |
| 406 | self.inner | 407 | self.inner |
