// 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::sleep::standby;

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...");
    standby::disable_sram2_full_retention();

    // 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;
}
