aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchemicstry <[email protected]>2022-07-11 00:00:33 +0300
committerchemicstry <[email protected]>2022-07-11 00:00:33 +0300
commitd7d1e46a5fb115b0993d4ac37c0152b1dd5f78c3 (patch)
treedb4e083ec2bc45ad09893dce4c1312b9aadf9fd0
parent3bf1e1d4aaefeeed9836060ea62b9d064e4fbe58 (diff)
Use u32 instead of Duration for IWDG
-rw-r--r--embassy-stm32/src/wdg/mod.rs21
-rw-r--r--examples/stm32f4/src/bin/wdt.rs2
2 files changed, 13 insertions, 10 deletions
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs
index 7f63de217..c4b2609b1 100644
--- a/embassy-stm32/src/wdg/mod.rs
+++ b/embassy-stm32/src/wdg/mod.rs
@@ -1,6 +1,5 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy::time::Duration;
4use embassy_hal_common::{unborrow, Unborrow}; 3use embassy_hal_common::{unborrow, Unborrow};
5use stm32_metapac::iwdg::vals::{Key, Pr}; 4use stm32_metapac::iwdg::vals::{Key, Pr};
6 5
@@ -13,25 +12,29 @@ pub struct IndependentWatchdog<'d, T: Instance> {
13// 12-bit counter 12// 12-bit counter
14const MAX_RL: u16 = 0xFFF; 13const MAX_RL: u16 = 0xFFF;
15 14
16/// Calculates maximum watchdog timeout (RL = 0xFFF) for a given prescaler 15/// Calculates maximum watchdog timeout in us (RL = 0xFFF) for a given prescaler
17const fn max_timeout(prescaler: u8) -> Duration { 16const fn max_timeout(prescaler: u8) -> u32 {
18 Duration::from_micros(1_000_000 / (LSI_FREQ.0 / prescaler as u32) as u64 * MAX_RL as u64) 17 1_000_000 * MAX_RL as u32 / (LSI_FREQ.0 / prescaler as u32)
19} 18}
20 19
21/// Calculates watchdog reload value for the given prescaler and desired timeout 20/// Calculates watchdog reload value for the given prescaler and desired timeout
22const fn reload_value(prescaler: u8, timeout: Duration) -> u16 { 21const fn reload_value(prescaler: u8, timeout_us: u32) -> u16 {
23 ((LSI_FREQ.0 / prescaler as u32) as u64 * timeout.as_micros() / 1_000_000) as u16 22 (timeout_us / prescaler as u32 * LSI_FREQ.0 / 1_000_000) as u16
24} 23}
25 24
26impl<'d, T: Instance> IndependentWatchdog<'d, T> { 25impl<'d, T: Instance> IndependentWatchdog<'d, T> {
27 pub fn new(_instance: impl Unborrow<Target = T> + 'd, timeout: Duration) -> Self { 26 /// Creates an IWDG (Independent Watchdog) instance with a given timeout value in microseconds.
27 ///
28 /// [Self] has to be started with [Self::unleash()].
29 /// Once timer expires, MCU will be reset. To prevent this, timer must be reloaded by repeatedly calling [Self::pet()] within timeout interval.
30 pub fn new(_instance: impl Unborrow<Target = T> + 'd, timeout_us: u32) -> Self {
28 unborrow!(_instance); 31 unborrow!(_instance);
29 32
30 // Find lowest prescaler value, which makes watchdog period longer or equal to timeout. 33 // Find lowest prescaler value, which makes watchdog period longer or equal to timeout.
31 // This iterates from 4 (2^2) to 256 (2^8). 34 // This iterates from 4 (2^2) to 256 (2^8).
32 let psc_power = unwrap!((2..=8).find(|psc_power| { 35 let psc_power = unwrap!((2..=8).find(|psc_power| {
33 let psc = 2u8.pow(*psc_power); 36 let psc = 2u8.pow(*psc_power);
34 timeout <= max_timeout(psc) 37 timeout_us <= max_timeout(psc)
35 })); 38 }));
36 39
37 // Prescaler value 40 // Prescaler value
@@ -42,7 +45,7 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> {
42 assert!(pr <= 0b110); 45 assert!(pr <= 0b110);
43 46
44 // Reload value 47 // Reload value
45 let rl = reload_value(psc, timeout); 48 let rl = reload_value(psc, timeout_us);
46 49
47 let wdg = T::regs(); 50 let wdg = T::regs();
48 unsafe { 51 unsafe {
diff --git a/examples/stm32f4/src/bin/wdt.rs b/examples/stm32f4/src/bin/wdt.rs
index a23cfe9c0..bfc487c31 100644
--- a/examples/stm32f4/src/bin/wdt.rs
+++ b/examples/stm32f4/src/bin/wdt.rs
@@ -16,7 +16,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
16 16
17 let mut led = Output::new(p.PB7, Level::High, Speed::Low); 17 let mut led = Output::new(p.PB7, Level::High, Speed::Low);
18 18
19 let mut wdt = IndependentWatchdog::new(p.IWDG, Duration::from_secs(1)); 19 let mut wdt = IndependentWatchdog::new(p.IWDG, 1_000_000);
20 unsafe { 20 unsafe {
21 wdt.unleash(); 21 wdt.unleash();
22 } 22 }