aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/timer
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-15 14:53:06 -0600
committerxoviat <[email protected]>2025-11-15 14:53:06 -0600
commitbbec014a270706a1ea92ca8160eb55d9fd1599b7 (patch)
tree0ee155ac4727d8c6397e08470954d2693d2488e3 /embassy-stm32/src/timer
parent11d753c8715b03ea4fbcad939a0537c54b45704f (diff)
parent37ee00ec3e423d81c5a5dbeb3481c94c1311e079 (diff)
Merge branch 'timer_update_management' of github.com:WattStep/embassy into time
Diffstat (limited to 'embassy-stm32/src/timer')
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs10
-rw-r--r--embassy-stm32/src/timer/input_capture.rs1
-rw-r--r--embassy-stm32/src/timer/low_level.rs18
-rw-r--r--embassy-stm32/src/timer/pwm_input.rs1
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs10
5 files changed, 25 insertions, 15 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index 76cbbe91d..6d4c70dff 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -77,8 +77,6 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
77 77
78 this.inner.set_counting_mode(counting_mode); 78 this.inner.set_counting_mode(counting_mode);
79 this.set_frequency(freq); 79 this.set_frequency(freq);
80 this.inner.start();
81
82 this.inner.enable_outputs(); 80 this.inner.enable_outputs();
83 81
84 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] 82 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4]
@@ -89,6 +87,10 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
89 }); 87 });
90 this.inner.set_autoreload_preload(true); 88 this.inner.set_autoreload_preload(true);
91 89
90 // Generate update event so pre-load registers are written to the shadow registers
91 this.inner.generate_update_event();
92 this.inner.start();
93
92 this 94 this
93 } 95 }
94 96
@@ -160,8 +162,8 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
160 162
161 /// Set PWM frequency. 163 /// Set PWM frequency.
162 /// 164 ///
163 /// Note: when you call this, the max duty value changes, so you will have to 165 /// Note: that the frequency will not be applied in the timer until an update event
164 /// call `set_duty` on all channels with the duty calculated based on the new max duty. 166 /// occurs.
165 pub fn set_frequency(&mut self, freq: Hertz) { 167 pub fn set_frequency(&mut self, freq: Hertz) {
166 let multiplier = if self.inner.get_counting_mode().is_center_aligned() { 168 let multiplier = if self.inner.get_counting_mode().is_center_aligned() {
167 2u8 169 2u8
diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs
index 2a4ec2db0..9cf0f8c34 100644
--- a/embassy-stm32/src/timer/input_capture.rs
+++ b/embassy-stm32/src/timer/input_capture.rs
@@ -60,6 +60,7 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
60 this.inner.set_counting_mode(counting_mode); 60 this.inner.set_counting_mode(counting_mode);
61 this.inner.set_tick_freq(freq); 61 this.inner.set_tick_freq(freq);
62 this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details 62 this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details
63 this.inner.generate_update_event();
63 this.inner.start(); 64 this.inner.start();
64 65
65 // enable NVIC interrupt 66 // enable NVIC interrupt
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs
index c574277e7..439b7f020 100644
--- a/embassy-stm32/src/timer/low_level.rs
+++ b/embassy-stm32/src/timer/low_level.rs
@@ -272,6 +272,16 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
272 self.regs_core().cr1().modify(|r| r.set_cen(true)); 272 self.regs_core().cr1().modify(|r| r.set_cen(true));
273 } 273 }
274 274
275 /// Generate timer update event from software.
276 ///
277 /// Set URS to avoid generating interrupt or DMA request. This update event is only
278 /// used to load value from pre-load registers.
279 pub fn generate_update_event(&self) {
280 self.regs_core().cr1().modify(|r| r.set_urs(vals::Urs::COUNTER_ONLY));
281 self.regs_core().egr().write(|r| r.set_ug(true));
282 self.regs_core().cr1().modify(|r| r.set_urs(vals::Urs::ANY_EVENT));
283 }
284
275 /// Stop the timer. 285 /// Stop the timer.
276 pub fn stop(&self) { 286 pub fn stop(&self) {
277 self.regs_core().cr1().modify(|r| r.set_cen(false)); 287 self.regs_core().cr1().modify(|r| r.set_cen(false));
@@ -322,10 +332,6 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
322 let regs = self.regs_core(); 332 let regs = self.regs_core();
323 regs.psc().write_value(psc); 333 regs.psc().write_value(psc);
324 regs.arr().write(|r| r.set_arr(arr)); 334 regs.arr().write(|r| r.set_arr(arr));
325
326 regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTER_ONLY));
327 regs.egr().write(|r| r.set_ug(true));
328 regs.cr1().modify(|r| r.set_urs(vals::Urs::ANY_EVENT));
329 } 335 }
330 #[cfg(not(stm32l0))] 336 #[cfg(not(stm32l0))]
331 TimerBits::Bits32 => { 337 TimerBits::Bits32 => {
@@ -335,10 +341,6 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
335 let regs = self.regs_gp32_unchecked(); 341 let regs = self.regs_gp32_unchecked();
336 regs.psc().write_value(psc); 342 regs.psc().write_value(psc);
337 regs.arr().write_value(arr); 343 regs.arr().write_value(arr);
338
339 regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTER_ONLY));
340 regs.egr().write(|r| r.set_ug(true));
341 regs.cr1().modify(|r| r.set_urs(vals::Urs::ANY_EVENT));
342 } 344 }
343 } 345 }
344 } 346 }
diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs
index da8a79b09..057ab011a 100644
--- a/embassy-stm32/src/timer/pwm_input.rs
+++ b/embassy-stm32/src/timer/pwm_input.rs
@@ -47,6 +47,7 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
47 inner.set_counting_mode(CountingMode::EdgeAlignedUp); 47 inner.set_counting_mode(CountingMode::EdgeAlignedUp);
48 inner.set_tick_freq(freq); 48 inner.set_tick_freq(freq);
49 inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details 49 inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details
50 inner.generate_update_event();
50 inner.start(); 51 inner.start();
51 52
52 // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.6 53 // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.6
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index 19a0b38d1..6c9ef17e0 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -198,7 +198,6 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
198 this.inner.set_counting_mode(counting_mode); 198 this.inner.set_counting_mode(counting_mode);
199 this.set_frequency(freq); 199 this.set_frequency(freq);
200 this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details 200 this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details
201 this.inner.start();
202 201
203 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] 202 [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4]
204 .iter() 203 .iter()
@@ -207,6 +206,11 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
207 206
208 this.inner.set_output_compare_preload(channel, true); 207 this.inner.set_output_compare_preload(channel, true);
209 }); 208 });
209 this.inner.set_autoreload_preload(true);
210
211 // Generate update event so pre-load registers are written to the shadow registers
212 this.inner.generate_update_event();
213 this.inner.start();
210 214
211 this 215 this
212 } 216 }
@@ -285,8 +289,8 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
285 289
286 /// Set PWM frequency. 290 /// Set PWM frequency.
287 /// 291 ///
288 /// Note: when you call this, the max duty value changes, so you will have to 292 /// Note: that the frequency will not be applied in the timer until an update event
289 /// call `set_duty` on all channels with the duty calculated based on the new max duty. 293 /// occurs.
290 pub fn set_frequency(&mut self, freq: Hertz) { 294 pub fn set_frequency(&mut self, freq: Hertz) {
291 // TODO: prevent ARR = u16::MAX? 295 // TODO: prevent ARR = u16::MAX?
292 let multiplier = if self.inner.get_counting_mode().is_center_aligned() { 296 let multiplier = if self.inner.get_counting_mode().is_center_aligned() {