diff options
| author | Matous Hybl <[email protected]> | 2022-11-09 14:10:46 +0100 |
|---|---|---|
| committer | Matous Hybl <[email protected]> | 2022-11-10 15:56:28 +0100 |
| commit | cbc97758e391d981d497bf37fe63b5a35913c115 (patch) | |
| tree | 842e130fe0cc9ba25a5630547b6de25da913f104 | |
| parent | 059610a8de49ff2d38311f343d3d1a6f8d90a720 (diff) | |
stm32: Fix watchdog division by zero for 256 prescaler, add watchdog example for H7
| -rw-r--r-- | embassy-stm32/src/wdg/mod.rs | 8 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/wdg.rs | 24 |
2 files changed, 28 insertions, 4 deletions
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs index 85176eefc..92b9a5ca8 100644 --- a/embassy-stm32/src/wdg/mod.rs +++ b/embassy-stm32/src/wdg/mod.rs | |||
| @@ -13,12 +13,12 @@ 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: u8) -> u32 { | 16 | const fn max_timeout(prescaler: u16) -> u32 { |
| 17 | 1_000_000 * MAX_RL as u32 / (LSI_FREQ.0 / prescaler as u32) | 17 | 1_000_000 * MAX_RL 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: u8, 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 |
| 23 | } | 23 | } |
| 24 | 24 | ||
| @@ -33,12 +33,12 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> { | |||
| 33 | // 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. |
| 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 = 2u8.pow(*psc_power); | 36 | let psc = 2u16.pow(*psc_power); |
| 37 | timeout_us <= max_timeout(psc) | 37 | timeout_us <= max_timeout(psc) |
| 38 | })); | 38 | })); |
| 39 | 39 | ||
| 40 | // Prescaler value | 40 | // Prescaler value |
| 41 | let psc = 2u8.pow(psc_power); | 41 | let psc = 2u16.pow(psc_power); |
| 42 | 42 | ||
| 43 | // Convert prescaler power to PR register value | 43 | // Convert prescaler power to PR register value |
| 44 | let pr = psc_power as u8 - 2; | 44 | let pr = psc_power as u8 - 2; |
diff --git a/examples/stm32h7/src/bin/wdg.rs b/examples/stm32h7/src/bin/wdg.rs new file mode 100644 index 000000000..2b0301aad --- /dev/null +++ b/examples/stm32h7/src/bin/wdg.rs | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::wdg::IndependentWatchdog; | ||
| 8 | use embassy_time::{Duration, Timer}; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::main] | ||
| 12 | async fn main(_spawner: Spawner) { | ||
| 13 | let p = embassy_stm32::init(Default::default()); | ||
| 14 | info!("Hello World!"); | ||
| 15 | |||
| 16 | let mut wdg = IndependentWatchdog::new(p.IWDG1, 20_000_000); | ||
| 17 | |||
| 18 | unsafe { wdg.unleash() }; | ||
| 19 | |||
| 20 | loop { | ||
| 21 | Timer::after(Duration::from_secs(1)).await; | ||
| 22 | unsafe { wdg.pet() }; | ||
| 23 | } | ||
| 24 | } | ||
