From 33543099c2d843208942180ee6a6345ce72043e7 Mon Sep 17 00:00:00 2001 From: Priec Date: Wed, 3 Dec 2025 16:52:30 +0100 Subject: [PATCH] split the wakeup now, properly working --- semestralka_2/src/bin/main.rs | 33 ++++++++---------------------- semestralka_2/src/config.rs | 2 ++ semestralka_2/src/sleep/standby.rs | 12 +++++++++++ semestralka_2/src/wakeup/iwdg.rs | 31 ++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/semestralka_2/src/bin/main.rs b/semestralka_2/src/bin/main.rs index 65ba86c..eb6fdd9 100644 --- a/semestralka_2/src/bin/main.rs +++ b/semestralka_2/src/bin/main.rs @@ -3,7 +3,6 @@ #![no_main] use defmt::*; -use core::ptr::addr_of_mut; use embassy_stm32::pac; use embassy_executor::Spawner; use embassy_futures::yield_now; @@ -12,7 +11,6 @@ use embassy_stm32::peripherals; use embassy_stm32::Config; use embassy_stm32::usart::{BufferedUart, Config as UsartConfig, BufferedInterruptHandler}; use embassy_stm32::gpio::{Output, Level, Speed}; -use embassy_stm32::wdg::IndependentWatchdog; use embassy_time::{Duration, Timer}; use static_cell::StaticCell; @@ -20,6 +18,7 @@ use dma_gpio::config::{ BAUD, PIPE_HW_RX, PIPE_HW_TX, }; use dma_gpio::hw_uart_pc::{driver::uart_task, usart1}; +use dma_gpio::wakeup::iwdg::{clear_wakeup_flags, init_watchdog}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -30,8 +29,6 @@ unsafe extern "C" { fn HAL_PWR_EnterSTANDBYMode(); } -const PWR_FLAG_SBF: u32 = 1 << 1; - #[embassy_executor::main] async fn main(spawner: Spawner) { info!("boot"); @@ -40,16 +37,10 @@ async fn main(spawner: Spawner) { let _led_ground = Output::new(p.PB0, Level::Low, Speed::Low); info!("init m8"); - // Clearing after the wakeup - let rcc = pac::RCC; - rcc.csr().write(|w| w.set_rmvf(true)); - - // Check wake source - let pwr = pac::PWR; - if pwr.sr().read().sbf() { - info!("Woke from Standby via watchdog"); - pwr.sr().write(|w| w.set_sbf(true)); - } + clear_wakeup_flags(); + + led.set_high(); + info!("LED ON (MCU awake)"); // HARDWARE UART to the PC let mut cfg = UsartConfig::default(); @@ -74,19 +65,10 @@ async fn main(spawner: Spawner) { info!("DBGMCU CR: dbg_stop={}, dbg_standby={}", cr.dbg_stop(), cr.dbg_standby()); // MAIN LOOP - info!("tick start"); - led.set_high(); - info!("LED IS HIGH"); + info!("Preparing for standby..."); Timer::after(Duration::from_millis(500)).await; - led.set_low(); - info!("LED IS LOW"); - Timer::after(Duration::from_millis(500)).await; - led.set_high(); - info!("LED IS HIGH"); - info!("Iwdg init"); - let mut watchdog = IndependentWatchdog::new(p.IWDG, 2_000_000); // 2 seconds - watchdog.unleash(); + init_watchdog(p.IWDG).await; Timer::after(Duration::from_millis(10)).await; unsafe { @@ -96,5 +78,6 @@ async fn main(spawner: Spawner) { loop { cortex_m::asm::wfi(); + yield_now().await; } } diff --git a/semestralka_2/src/config.rs b/semestralka_2/src/config.rs index 1334716..13ff5f8 100644 --- a/semestralka_2/src/config.rs +++ b/semestralka_2/src/config.rs @@ -6,5 +6,7 @@ pub const BAUD: u32 = 9_600; pub const PIPE_HW_TX_SIZE: usize = 1024; pub const PIPE_HW_RX_SIZE: usize = 1024; +pub const WATCHDOG_TIMEOUT_US: u32 = 2_000_000; // 2 seconds + pub static PIPE_HW_TX: Pipe = Pipe::new(); pub static PIPE_HW_RX: Pipe = Pipe::new(); diff --git a/semestralka_2/src/sleep/standby.rs b/semestralka_2/src/sleep/standby.rs index 421dfa3..f1374f8 100644 --- a/semestralka_2/src/sleep/standby.rs +++ b/semestralka_2/src/sleep/standby.rs @@ -1 +1,13 @@ // src/sleep/standby.rs + +pub fn enter_standby() -> ! { + unsafe extern "C" { + fn HAL_PWR_EnterSTANDBYMode(); + } + + unsafe { + HAL_PWR_EnterSTANDBYMode(); + } + + cortex_m::asm::udf(); // never happen marker +} diff --git a/semestralka_2/src/wakeup/iwdg.rs b/semestralka_2/src/wakeup/iwdg.rs index d6a2266..977d7af 100644 --- a/semestralka_2/src/wakeup/iwdg.rs +++ b/semestralka_2/src/wakeup/iwdg.rs @@ -1,3 +1,34 @@ // 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; + +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)); + } +} + +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; +}