diff options
| author | xoviat <[email protected]> | 2023-09-22 15:35:20 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-09-22 15:35:20 -0500 |
| commit | c849620cd6bfc1aec6999109e818a91cb061a578 (patch) | |
| tree | addf758db8c58fd00f34d92f95695c5bbafce3f3 | |
| parent | f1488864ebee3daebdc2cc6ed3ccdf7014fa67b2 (diff) | |
stm32/lp: clamp requested_duration to avoid overflow
| -rw-r--r-- | embassy-stm32/src/rtc/v2.rs | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index d139f2f47..05b85ef46 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -71,21 +71,27 @@ impl super::Rtc { | |||
| 71 | ) { | 71 | ) { |
| 72 | use embassy_time::{Duration, TICK_HZ}; | 72 | use embassy_time::{Duration, TICK_HZ}; |
| 73 | 73 | ||
| 74 | // Panic if the rcc mod knows we're not using low-power rtc | ||
| 74 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] | 75 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] |
| 75 | unsafe { crate::rcc::get_freqs() }.rtc.unwrap(); | 76 | unsafe { crate::rcc::get_freqs() }.rtc.unwrap(); |
| 76 | 77 | ||
| 78 | /* | ||
| 79 | If the requested duration is u64::MAX, don't even set the alarm | ||
| 80 | |||
| 81 | Otherwise clamp the requested duration to u32::MAX so that we can do math | ||
| 82 | */ | ||
| 83 | if requested_duration.as_ticks() == u64::MAX { | ||
| 84 | return; | ||
| 85 | } | ||
| 86 | |||
| 87 | let requested_duration = requested_duration.as_ticks().clamp(0, u32::MAX as u64); | ||
| 77 | let rtc_hz = Self::frequency().0 as u64; | 88 | let rtc_hz = Self::frequency().0 as u64; |
| 78 | let rtc_ticks = requested_duration.as_ticks() * rtc_hz / TICK_HZ; | 89 | let rtc_ticks = requested_duration * rtc_hz / TICK_HZ; |
| 79 | let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32); | 90 | let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32); |
| 80 | 91 | ||
| 81 | // adjust the rtc ticks to the prescaler and subtract one rtc tick | 92 | // adjust the rtc ticks to the prescaler and subtract one rtc tick |
| 82 | let rtc_ticks = rtc_ticks / prescaler as u64; | 93 | let rtc_ticks = rtc_ticks / prescaler as u64; |
| 83 | let rtc_ticks = if rtc_ticks >= u16::MAX as u64 { | 94 | let rtc_ticks = rtc_ticks.clamp(0, (u16::MAX - 1) as u64).saturating_sub(1) as u16; |
| 84 | u16::MAX - 1 | ||
| 85 | } else { | ||
| 86 | rtc_ticks as u16 | ||
| 87 | } | ||
| 88 | .saturating_sub(1); | ||
| 89 | 95 | ||
| 90 | self.write(false, |regs| { | 96 | self.write(false, |regs| { |
| 91 | regs.cr().modify(|w| w.set_wute(false)); | 97 | regs.cr().modify(|w| w.set_wute(false)); |
