Skip to content

Commit

Permalink
Support power off request by board during init
Browse files Browse the repository at this point in the history
  • Loading branch information
surban committed Aug 30, 2023
1 parent 47488f2 commit 4874a92
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 4 deletions.
7 changes: 6 additions & 1 deletion openemc-bootloader/src/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::num::NonZeroU32;

use openemc_shared::{BootInfo, ResetStatus};

use crate::{i2c_reg_slave::I2CRegTransaction, BoardInitResult};
use crate::{i2c_reg_slave::I2CRegTransaction, util::enter_standby, BoardInitResult};

/// Board-specific functionality.
pub trait Board {
Expand Down Expand Up @@ -65,4 +65,9 @@ pub trait Board {
fn timeout_ticks(&mut self) -> Option<NonZeroU32> {
Some(defmt::unwrap!(NonZeroU32::new(4_200_000_000)))
}

/// Shutdown the system and go to sleep.
fn power_off(&mut self) -> ! {
enter_standby();
}
}
21 changes: 20 additions & 1 deletion openemc-bootloader/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ pub enum BoardInitResult {
StartBootloader,
/// Perform factory reset.
FactoryReset,
/// Power off the board.
PowerOff,
}

use boards::Chosen as ThisBoard;
Expand Down Expand Up @@ -163,7 +165,7 @@ fn main() -> ! {
backup::write(BACKUP_REG_BOOT_REASON, BootReason::SurpriseInBootloader as _);

// Start watchdog.
if boot_reason != BootReason::PowerOff as _ {
if boot_reason != BootReason::PowerOff as _ && boot_reason == BootReason::PowerOffBootloader as _ {
watchdog::start();
}

Expand Down Expand Up @@ -196,12 +198,29 @@ fn main() -> ! {
);
defmt::info!("");

// Check for shutdown request.
if boot_reason == BootReason::PowerOffBootloader as _ {
defmt::info!("power off in bootloader");
backup::write(BACKUP_REG_BOOT_REASON, BootReason::PowerOn as _);
board.power_off();
}

// Initialize board.
defmt::info!("board init");
watchdog::pet();
let board_init = board.init(boot_reason, reset_status);
defmt::info!("board init result: {:?}", board_init);

// Shutdown if requested by board.
if board_init == BoardInitResult::PowerOff {
defmt::info!("power off requested by board");
backup::write(BACKUP_REG_BOOT_REASON, BootReason::PowerOffBootloader as _);
backup::disable();

delay_ms(10);
SCB::sys_reset();
}

// Perform factory reset if requested by board.
if board_init == BoardInitResult::FactoryReset {
defmt::info!("factory reset");
Expand Down
14 changes: 12 additions & 2 deletions openemc-firmware/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ pub enum PowerMode {
Full,
/// Power only components required for charging.
Charging,
/// Shutdown.
Off,
}

/// I2C register slave that may have remapped pins.
Expand Down Expand Up @@ -364,7 +366,7 @@ mod app {
|| bi.boot_reason == BootReason::Restart as _
{
// Make sure system is powered off for at least one second.
defmt::info!("Board off delay");
defmt::info!("board off delay");
delay.delay(1u32.secs());
}
if bi.boot_reason == BootReason::PowerOff as _ {
Expand All @@ -390,7 +392,14 @@ mod app {
defmt::info!("RTC ready: {}", rtc.is_ready());
unwrap!(print_rtc_info::spawn());

// Initializes board.
// Power off if requested.
if power_mode == PowerMode::Off {
defmt::info!("power off requested by board");
delay.delay(10u32.millis());
boot::power_off(&mut bkp);
}

// Power on board.
defmt::info!("board power on in mode {:?}", power_mode);
board.set_power_led(power_mode == PowerMode::Full);
board.power_on(&mut delay);
Expand Down Expand Up @@ -499,6 +508,7 @@ mod app {
Some(slave)
}
PowerMode::Charging => None,
PowerMode::Off => None,
};

// Drive charging LED.
Expand Down
3 changes: 3 additions & 0 deletions openemc-shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ pub enum BootReason {
///
/// This prevents automatic start of user program.
StartBootloader = 0xb014,
/// Power off system and go to standby mode when entering bootloader.
PowerOffBootloader = 0xb015,
/// Boot caused by factory reset.
///
/// This clears the backup domain and prevents automatic start of user program.
Expand All @@ -233,6 +235,7 @@ impl BootReason {
v if v == Self::Restart as _ => "restart",
v if v == Self::Reset as _ => "reset",
v if v == Self::StartBootloader as _ => "start boot loader",
v if v == Self::PowerOffBootloader as _ => "power off in boot loader",
v if v == Self::FactoryReset as _ => "factory reset",
v if v == Self::WatchdogTimeout as _ => "watchdog timeout",
_ => "",
Expand Down

0 comments on commit 4874a92

Please sign in to comment.