aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-12-01 09:03:10 -0600
committerxoviat <[email protected]>2025-12-01 09:03:10 -0600
commita1236b13c3d5fad687ae931a041ae463ac0612bb (patch)
treec6328049f0f308e7c767b99f416279d679c65439
parent6638d4c85e00b624c3b30591f48af255548c4cc0 (diff)
timer: clamp compare value before dma
-rw-r--r--embassy-stm32/src/dma/word.rs4
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs4
-rw-r--r--embassy-stm32/src/timer/low_level.rs12
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs5
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
36macro_rules! impl_word { 40macro_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