aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs10
-rw-r--r--embassy-stm32/src/timer/low_level.rs24
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs10
3 files changed, 20 insertions, 24 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index 9a56a41fb..90ba196fc 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -160,15 +160,17 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
160 160
161 /// Set PWM frequency. 161 /// Set PWM frequency.
162 /// 162 ///
163 /// Note: when you call this, the max duty value changes, so you will have to 163 /// Returns the applied ARR value which can be used to calculate CCR values.
164 /// call `set_duty` on all channels with the duty calculated based on the new max duty. 164 ///
165 pub fn set_frequency(&mut self, freq: Hertz) { 165 /// Note: that the frequency will not be applied in the timer until an update event
166 /// occurs. Reading the `max_duty` before the update event will return the old value
167 pub fn set_frequency(&mut self, freq: Hertz) -> u32 {
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
168 } else { 170 } else {
169 1u8 171 1u8
170 }; 172 };
171 self.inner.set_frequency_internal(freq * multiplier, 16); 173 self.inner.set_frequency_internal(freq * multiplier, 16)
172 } 174 }
173 175
174 /// Get max duty value. 176 /// Get max duty value.
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs
index 0122fe4f7..f6af8be8c 100644
--- a/embassy-stm32/src/timer/low_level.rs
+++ b/embassy-stm32/src/timer/low_level.rs
@@ -293,19 +293,17 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
293 /// the timer counter will wrap around at the same frequency as is being set. 293 /// the timer counter will wrap around at the same frequency as is being set.
294 /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved 294 /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved
295 /// because it needs to count up and down. 295 /// because it needs to count up and down.
296 pub fn set_frequency(&self, frequency: Hertz) { 296 pub fn set_frequency(&self, frequency: Hertz) -> u32 {
297 match T::BITS { 297 match T::BITS {
298 TimerBits::Bits16 => { 298 TimerBits::Bits16 => self.set_frequency_internal(frequency, 16),
299 self.set_frequency_internal(frequency, 16);
300 }
301 #[cfg(not(stm32l0))] 299 #[cfg(not(stm32l0))]
302 TimerBits::Bits32 => { 300 TimerBits::Bits32 => self.set_frequency_internal(frequency, 32),
303 self.set_frequency_internal(frequency, 32);
304 }
305 } 301 }
306 } 302 }
307 303
308 pub(crate) fn set_frequency_internal(&self, frequency: Hertz, max_divide_by_bits: u8) { 304 /// Calculate ARR based on desired frequency
305 /// Returns actual value written to the register as u32
306 pub(crate) fn set_frequency_internal(&self, frequency: Hertz, max_divide_by_bits: u8) -> u32 {
309 let f = frequency.0; 307 let f = frequency.0;
310 assert!(f > 0); 308 assert!(f > 0);
311 let timer_f = T::frequency().0; 309 let timer_f = T::frequency().0;
@@ -322,10 +320,7 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
322 let regs = self.regs_core(); 320 let regs = self.regs_core();
323 regs.psc().write_value(psc); 321 regs.psc().write_value(psc);
324 regs.arr().write(|r| r.set_arr(arr)); 322 regs.arr().write(|r| r.set_arr(arr));
325 323 arr as u32
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 } 324 }
330 #[cfg(not(stm32l0))] 325 #[cfg(not(stm32l0))]
331 TimerBits::Bits32 => { 326 TimerBits::Bits32 => {
@@ -335,10 +330,7 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
335 let regs = self.regs_gp32_unchecked(); 330 let regs = self.regs_gp32_unchecked();
336 regs.psc().write_value(psc); 331 regs.psc().write_value(psc);
337 regs.arr().write_value(arr); 332 regs.arr().write_value(arr);
338 333 arr
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 } 334 }
343 } 335 }
344 } 336 }
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index c338b0fd4..01996c969 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -285,16 +285,18 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
285 285
286 /// Set PWM frequency. 286 /// Set PWM frequency.
287 /// 287 ///
288 /// Note: when you call this, the max duty value changes, so you will have to 288 /// Returns the applied ARR value which can be used to calculate CCR values.
289 /// call `set_duty` on all channels with the duty calculated based on the new max duty. 289 ///
290 pub fn set_frequency(&mut self, freq: Hertz) { 290 /// Note: that the frequency will not be applied in the timer until an update event
291 /// occurs. Reading the `max_duty` before the update event will return the old value
292 pub fn set_frequency(&mut self, freq: Hertz) -> u32 {
291 // TODO: prevent ARR = u16::MAX? 293 // TODO: prevent ARR = u16::MAX?
292 let multiplier = if self.inner.get_counting_mode().is_center_aligned() { 294 let multiplier = if self.inner.get_counting_mode().is_center_aligned() {
293 2u8 295 2u8
294 } else { 296 } else {
295 1u8 297 1u8
296 }; 298 };
297 self.inner.set_frequency_internal(freq * multiplier, 16); 299 self.inner.set_frequency_internal(freq * multiplier, 16)
298 } 300 }
299 301
300 /// Get max duty value. 302 /// Get max duty value.