standby from C HAL is working
This commit is contained in:
@@ -9,8 +9,10 @@ use embassy_executor::Spawner;
|
|||||||
use embassy_futures::yield_now;
|
use embassy_futures::yield_now;
|
||||||
use embassy_stm32::bind_interrupts;
|
use embassy_stm32::bind_interrupts;
|
||||||
use embassy_stm32::peripherals;
|
use embassy_stm32::peripherals;
|
||||||
use embassy_stm32::usart::{BufferedUart, Config, BufferedInterruptHandler};
|
use embassy_stm32::Config;
|
||||||
|
use embassy_stm32::usart::{BufferedUart, Config as UsartConfig, BufferedInterruptHandler};
|
||||||
use embassy_stm32::gpio::{Output, Level, Speed};
|
use embassy_stm32::gpio::{Output, Level, Speed};
|
||||||
|
use embassy_stm32::wdg::IndependentWatchdog;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
|
|
||||||
use static_cell::StaticCell;
|
use static_cell::StaticCell;
|
||||||
@@ -25,52 +27,34 @@ bind_interrupts!(struct Irqs {
|
|||||||
});
|
});
|
||||||
|
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
fn HAL_Init();
|
|
||||||
fn HAL_PWR_EnterSTANDBYMode();
|
fn HAL_PWR_EnterSTANDBYMode();
|
||||||
fn HAL_IWDG_Init(handle: *mut ());
|
|
||||||
fn HAL_IWDG_Refresh(handle: *mut ());
|
|
||||||
fn __HAL_PWR_GET_FLAG(flag: u32) -> u32;
|
|
||||||
fn __HAL_PWR_CLEAR_FLAG(flag: u32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PWR_FLAG_SBF: u32 = 1 << 1;
|
const PWR_FLAG_SBF: u32 = 1 << 1;
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct IWDG_InitTypeDef {
|
|
||||||
prescaler: u32,
|
|
||||||
reload: u32,
|
|
||||||
window: u32,
|
|
||||||
ewi: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct IWDG_HandleTypeDef {
|
|
||||||
instance: *mut u32,
|
|
||||||
init: IWDG_InitTypeDef,
|
|
||||||
}
|
|
||||||
|
|
||||||
const IWDG_PRESCALER_256: u32 = 0x06; // prescaler divider
|
|
||||||
const IWDG_BASE: u32 = 0x4000_3000; // IWDG base address (STM32U5)
|
|
||||||
|
|
||||||
static mut IWDG_HANDLE: IWDG_HandleTypeDef = IWDG_HandleTypeDef {
|
|
||||||
instance: IWDG_BASE as *mut u32,
|
|
||||||
init: IWDG_InitTypeDef {
|
|
||||||
prescaler: IWDG_PRESCALER_256,
|
|
||||||
reload: 125, // ~1s timeout with 32kHz LSI
|
|
||||||
window: 0xFFF, // disabled window
|
|
||||||
ewi: 0, // no early wake-up interrupt
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
info!("boot");
|
info!("boot");
|
||||||
let p = embassy_stm32::init(Default::default());
|
let mut config = Config::default();
|
||||||
let mut led = Output::new(p.PB0, Level::Low, Speed::Low);
|
config.enable_debug_during_sleep = true;
|
||||||
|
let p = embassy_stm32::init(config);
|
||||||
|
let mut led = Output::new(p.PA3, Level::Low, Speed::Low);
|
||||||
|
let _led_ground = Output::new(p.PB0, Level::Low, Speed::Low);
|
||||||
info!("init m8");
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
// HARDWARE UART to the PC
|
// HARDWARE UART to the PC
|
||||||
let mut cfg = Config::default();
|
let mut cfg = UsartConfig::default();
|
||||||
cfg.baudrate = BAUD;
|
cfg.baudrate = BAUD;
|
||||||
static TX_BUF: StaticCell<[u8; 256]> = StaticCell::new();
|
static TX_BUF: StaticCell<[u8; 256]> = StaticCell::new();
|
||||||
static RX_BUF: StaticCell<[u8; 256]> = StaticCell::new();
|
static RX_BUF: StaticCell<[u8; 256]> = StaticCell::new();
|
||||||
@@ -87,25 +71,11 @@ async fn main(spawner: Spawner) {
|
|||||||
spawner.spawn(uart_task(uart, &PIPE_HW_TX, &PIPE_HW_RX).unwrap());
|
spawner.spawn(uart_task(uart, &PIPE_HW_TX, &PIPE_HW_RX).unwrap());
|
||||||
// END OF HARDWARE UART to the PC
|
// END OF HARDWARE UART to the PC
|
||||||
|
|
||||||
let pwr = pac::PWR;
|
let dbg = pac::DBGMCU;
|
||||||
|
let cr = dbg.cr().read();
|
||||||
|
info!("DBGMCU CR: dbg_stop={}, dbg_standby={}", cr.dbg_stop(), cr.dbg_standby());
|
||||||
|
|
||||||
let from_standby = pwr.sr().read().sbf();
|
// MAIN LOOP
|
||||||
if from_standby {
|
|
||||||
info!("Wake from Standby");
|
|
||||||
pwr.sr().write(|w| w.set_sbf(true));
|
|
||||||
}
|
|
||||||
let rcc = pac::RCC;
|
|
||||||
let csr = rcc.csr().read();
|
|
||||||
if csr.iwdgrstf() {
|
|
||||||
info!("Reset source: IWDG");
|
|
||||||
}
|
|
||||||
rcc.csr().write(|w| w.set_rmvf(true)); // clear reset flags
|
|
||||||
info!("Iwdg 1 init");
|
|
||||||
unsafe {
|
|
||||||
HAL_IWDG_Init(addr_of_mut!(IWDG_HANDLE) as *mut ());
|
|
||||||
}
|
|
||||||
info!("Iwdg 2 init");
|
|
||||||
loop {
|
|
||||||
info!("tick start");
|
info!("tick start");
|
||||||
led.set_high();
|
led.set_high();
|
||||||
info!("LED IS HIGH");
|
info!("LED IS HIGH");
|
||||||
@@ -116,13 +86,17 @@ async fn main(spawner: Spawner) {
|
|||||||
led.set_high();
|
led.set_high();
|
||||||
info!("LED IS HIGH");
|
info!("LED IS HIGH");
|
||||||
|
|
||||||
|
info!("Iwdg init");
|
||||||
|
let mut watchdog = IndependentWatchdog::new(p.IWDG, 2_000_000); // 2 seconds
|
||||||
|
watchdog.unleash();
|
||||||
|
Timer::after(Duration::from_millis(10)).await;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
info!("Standby...");
|
info!("Standby...");
|
||||||
led.set_low();
|
|
||||||
HAL_IWDG_Refresh(addr_of_mut!(IWDG_HANDLE) as *mut ());
|
|
||||||
HAL_PWR_EnterSTANDBYMode();
|
HAL_PWR_EnterSTANDBYMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
yield_now().await;
|
loop {
|
||||||
|
cortex_m::asm::wfi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user