diff options
| -rw-r--r-- | embassy-stm32/src/wdg/mod.rs | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs index 92b9a5ca8..18ebf97d8 100644 --- a/embassy-stm32/src/wdg/mod.rs +++ b/embassy-stm32/src/wdg/mod.rs | |||
| @@ -13,13 +13,13 @@ pub struct IndependentWatchdog<'d, T: Instance> { | |||
| 13 | const MAX_RL: u16 = 0xFFF; | 13 | const MAX_RL: u16 = 0xFFF; |
| 14 | 14 | ||
| 15 | /// Calculates maximum watchdog timeout in us (RL = 0xFFF) for a given prescaler | 15 | /// Calculates maximum watchdog timeout in us (RL = 0xFFF) for a given prescaler |
| 16 | const fn max_timeout(prescaler: u16) -> u32 { | 16 | const fn get_timeout_us(prescaler: u16, reload_value: u16) -> u32 { |
| 17 | 1_000_000 * MAX_RL as u32 / (LSI_FREQ.0 / prescaler as u32) | 17 | 1_000_000 * (reload_value + 1) as u32 / (LSI_FREQ.0 / prescaler as u32) |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | /// Calculates watchdog reload value for the given prescaler and desired timeout | 20 | /// Calculates watchdog reload value for the given prescaler and desired timeout |
| 21 | const fn reload_value(prescaler: u16, timeout_us: u32) -> u16 { | 21 | const fn reload_value(prescaler: u16, timeout_us: u32) -> u16 { |
| 22 | (timeout_us / prescaler as u32 * LSI_FREQ.0 / 1_000_000) as u16 | 22 | (timeout_us / prescaler as u32 * LSI_FREQ.0 / 1_000_000) as u16 - 1 |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | impl<'d, T: Instance> IndependentWatchdog<'d, T> { | 25 | impl<'d, T: Instance> IndependentWatchdog<'d, T> { |
| @@ -34,7 +34,7 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> { | |||
| 34 | // This iterates from 4 (2^2) to 256 (2^8). | 34 | // This iterates from 4 (2^2) to 256 (2^8). |
| 35 | let psc_power = unwrap!((2..=8).find(|psc_power| { | 35 | let psc_power = unwrap!((2..=8).find(|psc_power| { |
| 36 | let psc = 2u16.pow(*psc_power); | 36 | let psc = 2u16.pow(*psc_power); |
| 37 | timeout_us <= max_timeout(psc) | 37 | timeout_us <= get_timeout_us(psc, MAX_RL) |
| 38 | })); | 38 | })); |
| 39 | 39 | ||
| 40 | // Prescaler value | 40 | // Prescaler value |
| @@ -54,6 +54,14 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> { | |||
| 54 | wdg.rlr().write(|w| w.set_rl(rl)); | 54 | wdg.rlr().write(|w| w.set_rl(rl)); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | trace!( | ||
| 58 | "Watchdog configured with {}us timeout, desired was {}us (PR={}, RL={})", | ||
| 59 | get_timeout_us(psc, rl), | ||
| 60 | timeout_us, | ||
| 61 | pr, | ||
| 62 | rl | ||
| 63 | ); | ||
| 64 | |||
| 57 | IndependentWatchdog { | 65 | IndependentWatchdog { |
| 58 | wdg: PhantomData::default(), | 66 | wdg: PhantomData::default(), |
| 59 | } | 67 | } |
| @@ -87,3 +95,27 @@ foreach_peripheral!( | |||
| 87 | impl Instance for crate::peripherals::$inst {} | 95 | impl Instance for crate::peripherals::$inst {} |
| 88 | }; | 96 | }; |
| 89 | ); | 97 | ); |
| 98 | |||
| 99 | #[cfg(test)] | ||
| 100 | mod tests { | ||
| 101 | use super::*; | ||
| 102 | |||
| 103 | #[test] | ||
| 104 | fn can_compute_timeout_us() { | ||
| 105 | assert_eq!(125, get_timeout_us(4, 0)); | ||
| 106 | assert_eq!(512_000, get_timeout_us(4, MAX_RL)); | ||
| 107 | |||
| 108 | assert_eq!(8_000, get_timeout_us(256, 0)); | ||
| 109 | assert_eq!(32768_000, get_timeout_us(256, MAX_RL)); | ||
| 110 | |||
| 111 | assert_eq!(8000_000, get_timeout_us(64, 3999)); | ||
| 112 | } | ||
| 113 | |||
| 114 | #[test] | ||
| 115 | fn can_compute_reload_value() { | ||
| 116 | assert_eq!(0xFFF, reload_value(4, 512_000)); | ||
| 117 | assert_eq!(0xFFF, reload_value(256, 32768_000)); | ||
| 118 | |||
| 119 | assert_eq!(3999, reload_value(64, 8000_000)); | ||
| 120 | } | ||
| 121 | } | ||
