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_stm32::bind_interrupts;
|
||||
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::wdg::IndependentWatchdog;
|
||||
use embassy_time::{Duration, Timer};
|
||||
|
||||
use static_cell::StaticCell;
|
||||
@@ -25,52 +27,34 @@ bind_interrupts!(struct Irqs {
|
||||
});
|
||||
|
||||
unsafe extern "C" {
|
||||
fn HAL_Init();
|
||||
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;
|
||||
|
||||
#[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]
|
||||
async fn main(spawner: Spawner) {
|
||||
info!("boot");
|
||||
let p = embassy_stm32::init(Default::default());
|
||||
let mut led = Output::new(p.PB0, Level::Low, Speed::Low);
|
||||
let mut config = Config::default();
|
||||
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");
|
||||
|
||||
// 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
|
||||
let mut cfg = Config::default();
|
||||
let mut cfg = UsartConfig::default();
|
||||
cfg.baudrate = BAUD;
|
||||
static TX_BUF: StaticCell<[u8; 256]> = StaticCell::new();
|
||||
static RX_BUF: StaticCell<[u8; 256]> = StaticCell::new();
|
||||
@@ -87,42 +71,32 @@ async fn main(spawner: Spawner) {
|
||||
spawner.spawn(uart_task(uart, &PIPE_HW_TX, &PIPE_HW_RX).unwrap());
|
||||
// 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();
|
||||
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");
|
||||
// MAIN LOOP
|
||||
info!("tick start");
|
||||
led.set_high();
|
||||
info!("LED IS HIGH");
|
||||
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();
|
||||
Timer::after(Duration::from_millis(10)).await;
|
||||
|
||||
unsafe {
|
||||
HAL_IWDG_Init(addr_of_mut!(IWDG_HANDLE) as *mut ());
|
||||
info!("Standby...");
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
}
|
||||
info!("Iwdg 2 init");
|
||||
|
||||
loop {
|
||||
info!("tick start");
|
||||
led.set_high();
|
||||
info!("LED IS HIGH");
|
||||
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");
|
||||
|
||||
unsafe {
|
||||
info!("Standby...");
|
||||
led.set_low();
|
||||
HAL_IWDG_Refresh(addr_of_mut!(IWDG_HANDLE) as *mut ());
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
}
|
||||
|
||||
yield_now().await;
|
||||
cortex_m::asm::wfi();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user