Skip to content

Commit a1236b1

Browse files
committed
timer: clamp compare value before dma
1 parent 6638d4c commit a1236b1

File tree

4 files changed

+21
-4
lines changed

4 files changed

+21
-4
lines changed

embassy-stm32/src/dma/word.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ pub trait Word: SealedWord + Default + Copy + 'static {
3131
fn size() -> WordSize;
3232
/// Amount of bits of this word size.
3333
fn bits() -> usize;
34+
/// Maximum value of this type.
35+
fn max() -> usize {
36+
(1 << Self::bits()) - 1
37+
}
3438
}
3539

3640
macro_rules! impl_word {

embassy-stm32/src/timer/complementary_pwm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
228228
duty: &[W],
229229
) {
230230
self.inner.enable_channel(channel, true);
231-
self.inner.set_compare_value(channel, 0.into());
231+
self.inner.clamp_compare_value::<W>(channel);
232232
self.inner.enable_update_dma(true);
233233
self.inner.setup_update_dma(dma, channel, duty).await;
234234
self.inner.enable_update_dma(false);
@@ -276,7 +276,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
276276
.filter(|ch| ch.index() <= ending_channel.index())
277277
.for_each(|ch| {
278278
self.inner.enable_channel(*ch, true);
279-
self.inner.set_compare_value(*ch, 0.into());
279+
self.inner.clamp_compare_value::<W>(*ch);
280280
});
281281
self.inner.enable_update_dma(true);
282282
self.inner

embassy-stm32/src/timer/low_level.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,18 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
627627
return unwrap!(self.regs_gp32_unchecked().ccr(channel.index()).read().ccr().try_into());
628628
}
629629

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+
630642
/// Setup a ring buffer for the channel
631643
pub fn setup_ring_buffer<'a, W: Word + Into<T::Word>>(
632644
&mut self,

embassy-stm32/src/timer/simple_pwm.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwmChannel<'d, T> {
179179
) -> RingBufferedPwmChannel<'d, T, W> {
180180
assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
181181

182+
self.timer.clamp_compare_value::<W>(self.channel);
182183
self.timer.enable_update_dma(true);
183184

184185
RingBufferedPwmChannel::new(
@@ -352,7 +353,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
352353
duty: &[W],
353354
) {
354355
self.inner.enable_channel(channel, true);
355-
self.inner.set_compare_value(channel, 0.into());
356+
self.inner.clamp_compare_value::<W>(channel);
356357
self.inner.enable_update_dma(true);
357358
self.inner.setup_update_dma(dma, channel, duty).await;
358359
self.inner.enable_update_dma(false);
@@ -400,7 +401,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
400401
.filter(|ch| ch.index() <= ending_channel.index())
401402
.for_each(|ch| {
402403
self.inner.enable_channel(*ch, true);
403-
self.inner.set_compare_value(*ch, 0.into());
404+
self.inner.clamp_compare_value::<W>(*ch);
404405
});
405406
self.inner.enable_update_dma(true);
406407
self.inner

0 commit comments

Comments
 (0)