Skip to content

Commit 9d21215

Browse files
bors[bot]Stephen D
andauthored
Merge #555
555: Reset timer CNT register when PWM period is changed r=burrbull a=scd31 When changing the period of a PWM timer repeatedly, it will sporadically stop working. This is because the CNT register isn't being reset. Minimum reproducible example: ```rust #![no_main] #![no_std] // use panic_halt as _; use panic_semihosting as _; use cortex_m_rt::entry; use stm32f4xx_hal as hal; use crate::hal::{pac, prelude::*, timer::Channel}; #[entry] fn main() -> ! { let dp = pac::Peripherals::take().unwrap(); let buzzer = dp.GPIOA.split().pa0.into_alternate(); // Set up the system clock. We want to run at 48MHz for this one. let rcc = dp.RCC.constrain(); let clocks = rcc.cfgr.use_hse(25.MHz()).sysclk(48.MHz()).freeze(); let mut pwm = dp.TIM5.pwm_hz(buzzer, 1000.Hz(), &clocks); pwm.set_duty(Channel::C1, pwm.get_max_duty() / 2); pwm.enable(Channel::C1); let mut delay = dp.TIM1.delay_us(&clocks); loop { pwm.set_period(1000.Hz()); pwm.set_duty(Channel::C1, pwm.get_max_duty() / 2); pwm.configure(&clocks); delay.delay_ms(1000_u32); pwm.set_period(2000.Hz()); pwm.set_duty(Channel::C1, pwm.get_max_duty() / 2); pwm.configure(&clocks); delay.delay(1.secs()); } } ``` Before this PR, this would work for a few cycles before the signal disappears. It would occasionally reappear every few minutes. After this PR, the code is consistently outputting a signal that alternates between 1 and 2 KHz. Co-authored-by: Stephen D <[email protected]>
2 parents 057751d + 1a21ce6 commit 9d21215

File tree

3 files changed

+9
-0
lines changed

3 files changed

+9
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3636
- use register.modify instead of register.write to start PWM [#501]
3737
- add missing generic param for Spi::release implementation.
3838
- build rtic-usb-cdc-echo example [#554]
39+
- reset timer cnt register when changing pwm period [#555]
3940

4041
### Added
4142

@@ -77,6 +78,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
7778
[#552]: https://github.com/stm32-rs/stm32f4xx-hal/pull/552
7879
[#553]: https://github.com/stm32-rs/stm32f4xx-hal/pull/553
7980
[#554]: https://github.com/stm32-rs/stm32f4xx-hal/pull/554
81+
[#555]: https://github.com/stm32-rs/stm32f4xx-hal/pull/555
8082

8183
## [v0.13.2] - 2022-05-16
8284

src/timer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ mod sealed {
254254
fn start_one_pulse(&mut self);
255255
fn start_no_update(&mut self);
256256
fn cr1_reset(&mut self);
257+
fn cnt_reset(&mut self);
257258
}
258259

259260
pub trait WithPwm: General {
@@ -381,6 +382,10 @@ macro_rules! hal {
381382
fn cr1_reset(&mut self) {
382383
self.cr1.reset();
383384
}
385+
#[inline(always)]
386+
fn cnt_reset(&mut self) {
387+
self.cnt.reset();
388+
}
384389
}
385390

386391
$(with_dmar!($TIM, $memsize);)?

src/timer/pwm.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ where
310310
let (psc, arr) = compute_arr_presc(period.raw(), clk.raw());
311311
self.tim.set_prescaler(psc);
312312
self.tim.set_auto_reload(arr).unwrap();
313+
self.tim.cnt_reset();
313314
}
314315
}
315316

@@ -444,5 +445,6 @@ where
444445

445446
pub fn set_period(&mut self, period: TimerDurationU32<FREQ>) {
446447
self.tim.set_auto_reload(period.ticks() - 1).unwrap();
448+
self.tim.cnt_reset();
447449
}
448450
}

0 commit comments

Comments
 (0)