stop3 working properly well
This commit is contained in:
@@ -13,6 +13,7 @@ use dma_gpio::config::BAUD;
|
|||||||
use dma_gpio::wakeup::iwdg::{clear_wakeup_flags, init_watchdog_reset};
|
use dma_gpio::wakeup::iwdg::{clear_wakeup_flags, init_watchdog_reset};
|
||||||
use dma_gpio::sleep::shutdown;
|
use dma_gpio::sleep::shutdown;
|
||||||
use dma_gpio::sleep::standby;
|
use dma_gpio::sleep::standby;
|
||||||
|
use dma_gpio::sleep::stop3;
|
||||||
use dma_gpio::hw_uart_pc::init::{init_hw_uart_to_pc, LowPowerCmd, CMD_CH};
|
use dma_gpio::hw_uart_pc::init::{init_hw_uart_to_pc, LowPowerCmd, CMD_CH};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
@@ -45,7 +46,10 @@ async fn main(spawner: Spawner) {
|
|||||||
[1] Standby + 8 KB SRAM2 retention\n\
|
[1] Standby + 8 KB SRAM2 retention\n\
|
||||||
[2] Standby + full SRAM2 retention\n\
|
[2] Standby + full SRAM2 retention\n\
|
||||||
[3] Standby — minimal power, SRAM2 lost\n\
|
[3] Standby — minimal power, SRAM2 lost\n\
|
||||||
[4] Shutdown — lowest power, full reset on wake",
|
[4] Shutdown — lowest power, full reset on wake\n\
|
||||||
|
[5] STOP3 mode with WFI\n\
|
||||||
|
[6] STOP3 mode with WFE\n\
|
||||||
|
[7] STOP3 mode with WFE (no event clear)",
|
||||||
BAUD, WATCHDOG_TIMEOUT_US / 1_000_000
|
BAUD, WATCHDOG_TIMEOUT_US / 1_000_000
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -82,6 +86,21 @@ async fn main(spawner: Spawner) {
|
|||||||
Timer::after(Duration::from_millis(10)).await;
|
Timer::after(Duration::from_millis(10)).await;
|
||||||
shutdown::enter_shutdown();
|
shutdown::enter_shutdown();
|
||||||
}
|
}
|
||||||
|
LowPowerCmd::Stop3Wfi => {
|
||||||
|
init_watchdog_reset(p.IWDG).await;
|
||||||
|
Timer::after(Duration::from_millis(10)).await;
|
||||||
|
stop3::enter_stop3(stop3::StopEntry::Wfi);
|
||||||
|
}
|
||||||
|
LowPowerCmd::Stop3Wfe => {
|
||||||
|
init_watchdog_reset(p.IWDG).await;
|
||||||
|
Timer::after(Duration::from_millis(10)).await;
|
||||||
|
stop3::enter_stop3(stop3::StopEntry::Wfe);
|
||||||
|
}
|
||||||
|
LowPowerCmd::Stop3WfeNoClear => {
|
||||||
|
init_watchdog_reset(p.IWDG).await;
|
||||||
|
Timer::after(Duration::from_millis(10)).await;
|
||||||
|
stop3::enter_stop3(stop3::StopEntry::WfeNoEventClear);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ pub enum LowPowerCmd {
|
|||||||
StandbyFull, // 2
|
StandbyFull, // 2
|
||||||
Standby, // 3
|
Standby, // 3
|
||||||
Shutdown, // 4
|
Shutdown, // 4
|
||||||
|
Stop3Wfi,
|
||||||
|
Stop3Wfe,
|
||||||
|
Stop3WfeNoClear,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static CMD_CH: Channel<CriticalSectionRawMutex, LowPowerCmd, 1> = Channel::new();
|
pub static CMD_CH: Channel<CriticalSectionRawMutex, LowPowerCmd, 1> = Channel::new();
|
||||||
@@ -35,7 +38,7 @@ pub static CMD_CH: Channel<CriticalSectionRawMutex, LowPowerCmd, 1> = Channel::n
|
|||||||
pub async fn uart_cmd_task() {
|
pub async fn uart_cmd_task() {
|
||||||
// Prompt once
|
// Prompt once
|
||||||
let _ = PIPE_HW_TX
|
let _ = PIPE_HW_TX
|
||||||
.write(b"Modes: 1=SB8, 2=SBfull, 3=SB, 4=SD\r\n")
|
.write(b"Modes: 1=SB8, 2=SBfull, 3=SB, 4=SD, 5=STOP3(WFI), 6=STOP3(WFE), 7=STOP3(WFE no clear)\r\n")
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let mut b = [0u8; 1];
|
let mut b = [0u8; 1];
|
||||||
@@ -61,8 +64,22 @@ pub async fn uart_cmd_task() {
|
|||||||
let _ = PIPE_HW_TX.write(b"ACK 4: shutdown\r\n").await;
|
let _ = PIPE_HW_TX.write(b"ACK 4: shutdown\r\n").await;
|
||||||
CMD_CH.send(LowPowerCmd::Shutdown).await;
|
CMD_CH.send(LowPowerCmd::Shutdown).await;
|
||||||
}
|
}
|
||||||
|
b'5' => {
|
||||||
|
let _ = PIPE_HW_TX.write(b"ACK 5: STOP3 with WFI\r\n").await;
|
||||||
|
CMD_CH.send(LowPowerCmd::Stop3Wfi).await;
|
||||||
|
}
|
||||||
|
b'6' => {
|
||||||
|
let _ = PIPE_HW_TX.write(b"ACK 6: STOP3 with WFE\r\n").await;
|
||||||
|
CMD_CH.send(LowPowerCmd::Stop3Wfe).await;
|
||||||
|
}
|
||||||
|
b'7' => {
|
||||||
|
let _ = PIPE_HW_TX.write(b"ACK 7: STOP3 with WFE (no event clear)\r\n").await;
|
||||||
|
CMD_CH.send(LowPowerCmd::Stop3WfeNoClear).await;
|
||||||
|
}
|
||||||
b'\r' | b'\n' | b' ' => {}
|
b'\r' | b'\n' | b' ' => {}
|
||||||
_ => { let _ = PIPE_HW_TX.write(b"ERR: use 1|2|3|4\r\n").await; }
|
_ => {
|
||||||
|
let _ = PIPE_HW_TX.write(b"ERR: use 1|2|3|4|5|6|7\r\n").await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
yield_now().await;
|
yield_now().await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
pub mod standby;
|
pub mod standby;
|
||||||
pub mod shutdown;
|
pub mod shutdown;
|
||||||
|
pub mod stop3;
|
||||||
|
|||||||
39
semestralka_2_uart/src/sleep/stop3.rs
Normal file
39
semestralka_2_uart/src/sleep/stop3.rs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// src/sleep/stop3.rs
|
||||||
|
|
||||||
|
// #define PWR_STOPENTRY_WFI (0x01U) //*!< Wait For Interruption instruction to enter Stop mode */
|
||||||
|
// #define PWR_STOPENTRY_WFE (0x02U) //*!< Wait For Event instruction to enter Stop mode */
|
||||||
|
// #define PWR_STOPENTRY_WFE_NO_EVT_CLEAR (0x03U)
|
||||||
|
|
||||||
|
/// How to enter STOP3 mode
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum StopEntry {
|
||||||
|
Wfi,
|
||||||
|
Wfe,
|
||||||
|
WfeNoEventClear,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<StopEntry> for u8 {
|
||||||
|
fn from(value: StopEntry) -> Self {
|
||||||
|
match value {
|
||||||
|
StopEntry::Wfi => 0x01,
|
||||||
|
StopEntry::Wfe => 0x02,
|
||||||
|
StopEntry::WfeNoEventClear => 0x03,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn enter_stop3(stop_entry: StopEntry) -> ! {
|
||||||
|
unsafe extern "C" {
|
||||||
|
fn HAL_PWREx_EnterSTOP3Mode(stop_entry: u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
HAL_PWREx_EnterSTOP3Mode(stop_entry.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
cortex_m::asm::udf(); //panic
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example usage:
|
||||||
|
// enter_stop3(StopEntry::Wfi);
|
||||||
|
// enter_stop3(StopEntry::Wfe);
|
||||||
|
// enter_stop3(StopEntry::WfeNoEventClear);
|
||||||
Reference in New Issue
Block a user