diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-12-02 22:50:09 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-12-02 22:50:09 +0000 |
| commit | db9ad1c30cdd3e07d4b41eb4bd136e01d6125ff3 (patch) | |
| tree | 39aeac6f88ccdfb0c9cc3402f9b9caccea47179f /embassy-stm32/src/timer | |
| parent | bc5e0d60b3861ca23b09dbd7fda703a47d3d60d2 (diff) | |
| parent | 3402e76f9876d58d271501102e2d80c9b2c389b3 (diff) | |
Merge pull request #3549 from aurelj/stm32_pwm_32bits_timer
stm32/timer: avoid max_compare_value >= u16::MAX
Diffstat (limited to 'embassy-stm32/src/timer')
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/low_level.rs | 24 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 2 |
3 files changed, 18 insertions, 10 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 46ccbf3df..02c01e900 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -116,7 +116,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { | |||
| 116 | } else { | 116 | } else { |
| 117 | 1u8 | 117 | 1u8 |
| 118 | }; | 118 | }; |
| 119 | self.inner.set_frequency(freq * multiplier); | 119 | self.inner.set_frequency_internal(freq * multiplier, 16); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | /// Get max duty value. | 122 | /// Get max duty value. |
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index 3136ea4e9..7360d6aef 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs | |||
| @@ -242,16 +242,28 @@ impl<'d, T: CoreInstance> Timer<'d, T> { | |||
| 242 | /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved | 242 | /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved |
| 243 | /// because it needs to count up and down. | 243 | /// because it needs to count up and down. |
| 244 | pub fn set_frequency(&self, frequency: Hertz) { | 244 | pub fn set_frequency(&self, frequency: Hertz) { |
| 245 | match T::BITS { | ||
| 246 | TimerBits::Bits16 => { | ||
| 247 | self.set_frequency_internal(frequency, 16); | ||
| 248 | } | ||
| 249 | #[cfg(not(stm32l0))] | ||
| 250 | TimerBits::Bits32 => { | ||
| 251 | self.set_frequency_internal(frequency, 32); | ||
| 252 | } | ||
| 253 | } | ||
| 254 | } | ||
| 255 | |||
| 256 | pub(crate) fn set_frequency_internal(&self, frequency: Hertz, max_divide_by_bits: u8) { | ||
| 245 | let f = frequency.0; | 257 | let f = frequency.0; |
| 246 | assert!(f > 0); | 258 | assert!(f > 0); |
| 247 | let timer_f = T::frequency().0; | 259 | let timer_f = T::frequency().0; |
| 248 | 260 | ||
| 261 | let pclk_ticks_per_timer_period = (timer_f / f) as u64; | ||
| 262 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << max_divide_by_bits)).try_into()); | ||
| 263 | let divide_by = pclk_ticks_per_timer_period / (u64::from(psc) + 1); | ||
| 264 | |||
| 249 | match T::BITS { | 265 | match T::BITS { |
| 250 | TimerBits::Bits16 => { | 266 | TimerBits::Bits16 => { |
| 251 | let pclk_ticks_per_timer_period = timer_f / f; | ||
| 252 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 16)).try_into()); | ||
| 253 | let divide_by = pclk_ticks_per_timer_period / (u32::from(psc) + 1); | ||
| 254 | |||
| 255 | // the timer counts `0..=arr`, we want it to count `0..divide_by` | 267 | // the timer counts `0..=arr`, we want it to count `0..divide_by` |
| 256 | let arr = unwrap!(u16::try_from(divide_by - 1)); | 268 | let arr = unwrap!(u16::try_from(divide_by - 1)); |
| 257 | 269 | ||
| @@ -265,10 +277,6 @@ impl<'d, T: CoreInstance> Timer<'d, T> { | |||
| 265 | } | 277 | } |
| 266 | #[cfg(not(stm32l0))] | 278 | #[cfg(not(stm32l0))] |
| 267 | TimerBits::Bits32 => { | 279 | TimerBits::Bits32 => { |
| 268 | let pclk_ticks_per_timer_period = (timer_f / f) as u64; | ||
| 269 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 32)).try_into()); | ||
| 270 | let divide_by = pclk_ticks_per_timer_period / (u64::from(psc) + 1); | ||
| 271 | |||
| 272 | // the timer counts `0..=arr`, we want it to count `0..divide_by` | 280 | // the timer counts `0..=arr`, we want it to count `0..divide_by` |
| 273 | let arr: u32 = unwrap!(u32::try_from(divide_by - 1)); | 281 | let arr: u32 = unwrap!(u32::try_from(divide_by - 1)); |
| 274 | 282 | ||
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 9e4a09095..56fb1871e 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -278,7 +278,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 278 | } else { | 278 | } else { |
| 279 | 1u8 | 279 | 1u8 |
| 280 | }; | 280 | }; |
| 281 | self.inner.set_frequency(freq * multiplier); | 281 | self.inner.set_frequency_internal(freq * multiplier, 16); |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | /// Get max duty value. | 284 | /// Get max duty value. |
