stm32: Fix watchdog division by zero for 256 prescaler, add watchdog example for H7

This commit is contained in:
Matous Hybl 2022-11-09 14:10:46 +01:00
parent 059610a8de
commit cbc97758e3
2 changed files with 28 additions and 4 deletions

View file

@ -13,12 +13,12 @@ pub struct IndependentWatchdog<'d, T: Instance> {
const MAX_RL: u16 = 0xFFF; const MAX_RL: u16 = 0xFFF;
/// Calculates maximum watchdog timeout in us (RL = 0xFFF) for a given prescaler /// Calculates maximum watchdog timeout in us (RL = 0xFFF) for a given prescaler
const fn max_timeout(prescaler: u8) -> u32 { const fn max_timeout(prescaler: u16) -> u32 {
1_000_000 * MAX_RL as u32 / (LSI_FREQ.0 / prescaler as u32) 1_000_000 * MAX_RL as u32 / (LSI_FREQ.0 / prescaler as u32)
} }
/// Calculates watchdog reload value for the given prescaler and desired timeout /// Calculates watchdog reload value for the given prescaler and desired timeout
const fn reload_value(prescaler: u8, timeout_us: u32) -> u16 { const fn reload_value(prescaler: u16, timeout_us: u32) -> u16 {
(timeout_us / prescaler as u32 * LSI_FREQ.0 / 1_000_000) as u16 (timeout_us / prescaler as u32 * LSI_FREQ.0 / 1_000_000) as u16
} }
@ -33,12 +33,12 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> {
// Find lowest prescaler value, which makes watchdog period longer or equal to timeout. // Find lowest prescaler value, which makes watchdog period longer or equal to timeout.
// This iterates from 4 (2^2) to 256 (2^8). // This iterates from 4 (2^2) to 256 (2^8).
let psc_power = unwrap!((2..=8).find(|psc_power| { let psc_power = unwrap!((2..=8).find(|psc_power| {
let psc = 2u8.pow(*psc_power); let psc = 2u16.pow(*psc_power);
timeout_us <= max_timeout(psc) timeout_us <= max_timeout(psc)
})); }));
// Prescaler value // Prescaler value
let psc = 2u8.pow(psc_power); let psc = 2u16.pow(psc_power);
// Convert prescaler power to PR register value // Convert prescaler power to PR register value
let pr = psc_power as u8 - 2; let pr = psc_power as u8 - 2;

View file

@ -0,0 +1,24 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::wdg::IndependentWatchdog;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let mut wdg = IndependentWatchdog::new(p.IWDG1, 20_000_000);
unsafe { wdg.unleash() };
loop {
Timer::after(Duration::from_secs(1)).await;
unsafe { wdg.pet() };
}
}