// src/wakeup/iwdg.rs use defmt::info; use embassy_stm32::peripherals; use embassy_stm32::wdg::IndependentWatchdog; use embassy_stm32::Peri; use embassy_time::{Duration, Timer}; use embassy_stm32::pac; use crate::config::WATCHDOG_TIMEOUT_US; /// Clears system reset and standby flags after wakeup. /// /// Call early in startup to: /// - Clear reset flags by setting `RMVF` in `RCC_CSR`. /// - If `SBF` in `PWR_SR` is set (woke from Standby), clear it. /// /// # Registers /// - `RCC_CSR` — Reset and Clock Control / Status /// - `PWR_SR` — Power Control / Status pub fn clear_wakeup_flags() { info!("Clearing wakeup flags..."); // Clear reset flags // let rcc = unsafe { &*pac::RCC::ptr() }; let rcc = pac::RCC; rcc.csr().write(|w| w.set_rmvf(true)); // Check and clear Standby wakeup flag // let pwr = unsafe { &*pac::PWR::ptr() }; let pwr = pac::PWR; if pwr.sr().read().sbf() { info!("Woke from Standby mode"); pwr.sr().write(|w| w.set_sbf(true)); } } /// Initializes the Independent Watchdog (IWDG) timer. /// Wakeup source: Can wake the system from Standby mode on timeout /// /// # Timing /// - Timeout value is configured in `WATCHDOG_TIMEOUT_US` from config.rs pub async fn init_watchdog(iwdg: Peri<'_, peripherals::IWDG>) { info!("Initializing watchdog after watchdog wake..."); let mut watchdog = IndependentWatchdog::new(iwdg, WATCHDOG_TIMEOUT_US); watchdog.unleash(); Timer::after(Duration::from_millis(10)).await; }