aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/wdg/mod.rs40
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> {
13const MAX_RL: u16 = 0xFFF; 13const 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
16const fn max_timeout(prescaler: u16) -> u32 { 16const 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
21const fn reload_value(prescaler: u16, timeout_us: u32) -> u16 { 21const 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
25impl<'d, T: Instance> IndependentWatchdog<'d, T> { 25impl<'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)]
100mod 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}