diff --git a/semestralka_2_uart/src/bin/main.rs b/semestralka_2_uart/src/bin/main.rs index 5e35704..bc124c4 100644 --- a/semestralka_2_uart/src/bin/main.rs +++ b/semestralka_2_uart/src/bin/main.rs @@ -60,8 +60,10 @@ async fn main(spawner: Spawner) { Timer::after(Duration::from_millis(10)).await; info!("ready for uart"); + let mut iwdg = Some(p.IWDG); + loop { let cmd = CMD_CH.receive().await; - execute_low_power(cmd); + execute_low_power(cmd, &mut iwdg).await; } } diff --git a/semestralka_2_uart/src/hw_uart_pc/init.rs b/semestralka_2_uart/src/hw_uart_pc/init.rs index e61556f..d1c1136 100644 --- a/semestralka_2_uart/src/hw_uart_pc/init.rs +++ b/semestralka_2_uart/src/hw_uart_pc/init.rs @@ -49,19 +49,28 @@ pub static CMD_CH: Channel = Channel::n #[embassy_executor::task] pub async fn uart_cmd_task() { - let _ = PIPE_HW_TX.write( - b"\r\n\ - Modes:\r\n\ - [1] Standby + 8 KB SRAM2 retention\r\n\ - [2] Standby + full SRAM2 retention\r\n\ - [3] Standby minimal\r\n\ - [4] Shutdown\r\n\ - [5] Stop mode (0-3)\r\n\ - " - ).await; + async fn print_menu() { + while PIPE_HW_TX.len() > 0 { + embassy_time::Timer::after(embassy_time::Duration::from_millis(2)).await; + } + let _ = PIPE_HW_TX.write(b"\x1B[2J\x1B[H").await; + let _ = PIPE_HW_TX.write( + b"\r\n\ + Modes:\r\n\ + [1] Standby + 8 KB SRAM2 retention\r\n\ + [2] Standby + full SRAM2 retention\r\n\ + [3] Standby minimal\r\n\ + [4] Shutdown\r\n\ + [5] Stop mode (0-3)\r\n\ + " + ).await; + } + + print_menu().await; let mut b = [0u8; 2]; loop { + b.fill(0); let n = PIPE_HW_RX.read(&mut b).await; if n == 0 { continue; } @@ -71,29 +80,30 @@ pub async fn uart_cmd_task() { b'3' => CMD_CH.send(LowPowerCmd::Standby).await, b'4' => CMD_CH.send(LowPowerCmd::Shutdown).await, b'5' => { - // Expect 2 digits: e.g. b'5' + '13' = Stop1 WfeNoEventClear - let _ = PIPE_HW_TX.write(b"Enter Stop mode number (0-3): ").await; - let _ = PIPE_HW_RX.read(&mut b[1..2]).await; - let stop_mode = match b[1] { + let _ = PIPE_HW_TX.write(b"Enter Stop mode number (1-3): ").await; + b.fill(0); + let n = PIPE_HW_RX.read(&mut b).await; + if n == 0 { print_menu().await; continue; } + let stop_mode = match b[0] { b'1' => StopMode::Stop1, b'2' => StopMode::Stop2, - _ => StopMode::Stop3, + b'3' => StopMode::Stop3, + _ => { print_menu().await; continue; } }; let _ = PIPE_HW_TX.write(b"Enter entry method (1=WFI,2=WFE,3=WFE no clear): ").await; - let n = PIPE_HW_RX.read(&mut b[1..2]).await; - if n > 0 { - let entry = match b[1] { - b'1' => StopEntry::Wfi, - b'2' => StopEntry::Wfe, - _ => StopEntry::WfeNoEventClear, - }; - CMD_CH.send(LowPowerCmd::StopMode(StopModeConfig { mode: stop_mode, entry })).await; - } - } - _ => { - let _ = PIPE_HW_TX.write(b"Unknown command\r\n").await; + b.fill(0); + let n = PIPE_HW_RX.read(&mut b).await; + if n == 0 { print_menu().await; continue; } + let entry = match b[0] { + b'1' => StopEntry::Wfi, + b'2' => StopEntry::Wfe, + b'3' => StopEntry::WfeNoEventClear, + _ => { print_menu().await; continue; } + }; + CMD_CH.send(LowPowerCmd::StopMode(StopModeConfig { mode: stop_mode, entry })).await; } + _ => { print_menu().await; continue; } } } } diff --git a/semestralka_2_uart/src/sleep/handler.rs b/semestralka_2_uart/src/sleep/handler.rs index 8a3b360..f955435 100644 --- a/semestralka_2_uart/src/sleep/handler.rs +++ b/semestralka_2_uart/src/sleep/handler.rs @@ -1,22 +1,42 @@ +// src/sleep/handler.rs + +use embassy_time::{Duration, Timer}; +use embassy_stm32::peripherals; +use embassy_stm32::Peri; + use crate::sleep::stop::StopEntry; use crate::sleep::stop::*; +use crate::wakeup::iwdg::init_watchdog_reset; use crate::hw_uart_pc::init::{LowPowerCmd, StopMode, StopModeConfig}; use defmt::info; -pub fn execute_low_power(cmd: LowPowerCmd) -> ! { +pub async fn execute_low_power( + cmd: LowPowerCmd, + iwdg: &mut Option> +) -> ! { + Timer::after(Duration::from_millis(10)).await; + match cmd { LowPowerCmd::Standby8k => { info!("Entering Standby with 8KB SRAM2 retention"); - // call your existing standby function here + if let Some(wdg) = iwdg.take() { + init_watchdog_reset(wdg).await; + } super::standby::enter_standby_with_sram2_8kb(); } LowPowerCmd::StandbyFull => { info!("Entering Standby with full SRAM2 retention"); + if let Some(wdg) = iwdg.take() { + init_watchdog_reset(wdg).await; + } super::standby::enter_standby_with_sram2_full(); } LowPowerCmd::Standby => { info!("Entering minimal Standby"); + if let Some(wdg) = iwdg.take() { + init_watchdog_reset(wdg).await; + } super::standby::enter_standby(); } LowPowerCmd::Shutdown => { @@ -25,6 +45,9 @@ pub fn execute_low_power(cmd: LowPowerCmd) -> ! { } LowPowerCmd::StopMode(StopModeConfig { mode, entry }) => { info!("Entering {:?} with {:?}", mode, entry); + if let Some(wdg) = iwdg.take() { + init_watchdog_reset(wdg).await; + } match mode { StopMode::Stop1 => enter_stop1(entry), StopMode::Stop2 => enter_stop2(entry), diff --git a/semestralka_2_uart/src/wakeup/iwdg.rs b/semestralka_2_uart/src/wakeup/iwdg.rs index 704eb7d..53c6479 100644 --- a/semestralka_2_uart/src/wakeup/iwdg.rs +++ b/semestralka_2_uart/src/wakeup/iwdg.rs @@ -42,7 +42,7 @@ pub fn clear_wakeup_flags() { /// /// # Timing /// - Timeout value is configured in `WATCHDOG_TIMEOUT_US` from config.rs -pub async fn init_watchdog_reset(iwdg: Peri<'_, peripherals::IWDG>) { +pub async fn init_watchdog_reset(iwdg: Peri<'static, peripherals::IWDG>) { info!("Initializing watchdog after watchdog wake..."); let mut watchdog = IndependentWatchdog::new(iwdg, WATCHDOG_TIMEOUT_US); watchdog.unleash();