Skip to content

Commit

Permalink
power on: minimum required battery voltage
Browse files Browse the repository at this point in the history
Allow requiring minimum battery voltage to allow
system power on. Also, if a power-on reset
occurs with charger attached, assume that it
was due to undervoltage and force charging mode.
  • Loading branch information
surban committed Jun 18, 2024
1 parent e130ea6 commit 81896a6
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
7 changes: 5 additions & 2 deletions openemc-firmware/src/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,12 @@ pub trait Board {
/// Battery voltage in mV that triggers immediate low voltage shutdown.
const CRITICAL_LOW_BATTERY_VOLTAGE: Option<u32> = None;

/// Minimum battery voltage in mV that is required for system power on.
const MIN_POWER_ON_BATTERY_VOLTAGE: Option<u32> = None;

/// Time to charge battery before attempting to power on, if it is below
/// [`CRITICAL_LOW_BATTERY_VOLTAGE`](Self::CRITICAL_LOW_BATTERY_VOLTAGE).
const CRITICAL_LOW_BATTERY_CHARGING_TIME: Duration = Duration::minutes(5);
/// [`MIN_POWER_ON_BATTERY_VOLTAGE`](Self::MIN_POWER_ON_BATTERY_VOLTAGE).
const LOW_BATTERY_CHARGING_TIME: Duration = Duration::minutes(5);

/// Battery voltage in mV that is used for switching charging LED from blinking to steady.
const CHARGING_LED_END_VOLTAGE: u32 = 10000;
Expand Down
48 changes: 30 additions & 18 deletions openemc-firmware/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,8 @@ mod app {
}
defmt::info!("charger: {}", charger_attached);

// Check that battery voltage is sufficient.
// Check that system power on is allowed by battery state.
let mut prohibit_power_on = false;
if let (Some(bq25713), Some(i2c2)) = (&mut bq25713, &mut i2c2) {
let _ = bq25713.periodic(i2c2, board.check_bq25713_chrg_ok());

Expand All @@ -593,27 +594,38 @@ mod app {

if let Some(v_bat) = v_bat {
defmt::info!("battery: {} mV", v_bat);
match ThisBoard::CRITICAL_LOW_BATTERY_VOLTAGE {
Some(min) if v_bat < min && board.power_mode().is_full() => {
defmt::warn!("Battery is under critical low battery voltage of {} V", min);

if charger_attached {
defmt::warn!("Switching to charging mode");
board.set_power_mode(PowerMode::Charging);
defmt::unwrap!(power_restart::spawn_after(
ThisBoard::CRITICAL_LOW_BATTERY_CHARGING_TIME,
BootReason::Restart,
));
defmt::unwrap!(undervoltage_power_off::spawn(false));
} else {
defmt::warn!("Switching off");
board.set_power_mode(PowerMode::Off);
defmt::unwrap!(undervoltage_power_off::spawn(true));
}
match ThisBoard::MIN_POWER_ON_BATTERY_VOLTAGE {
Some(min) if v_bat < min => {
defmt::warn!("Battery is under minimum power on voltage of {} V", min);
prohibit_power_on = true;
}
_ => (),
}
}

if bi.reset_status.is_power_on() && charger_attached {
defmt::warn!("Power on reset detected with charger attached, likely due to undervoltage");
prohibit_power_on = true;
}
}

// Prevent system power on if required.
if prohibit_power_on && board.power_mode().is_full() {
defmt::warn!("System power on is prohibited");

if charger_attached {
defmt::warn!("Switching to charging mode");
board.set_power_mode(PowerMode::Charging);
defmt::unwrap!(power_restart::spawn_after(
ThisBoard::LOW_BATTERY_CHARGING_TIME,
BootReason::Restart,
));
defmt::unwrap!(undervoltage_power_off::spawn(false));
} else {
defmt::warn!("Switching off");
board.set_power_mode(PowerMode::Off);
defmt::unwrap!(undervoltage_power_off::spawn(true));
}
}
blink_charging!(board, delay, watchman, 10);

Expand Down

0 comments on commit 81896a6

Please sign in to comment.