Skip to content

Commit 667789f

Browse files
committed
STUSB4500: prohibit reset when battery is low
Prohibit reset for 1 minute when battery is very low. This should avoid a power loss during start of charging.
1 parent 0b15412 commit 667789f

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

openemc-firmware/src/main.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ mod app {
544544
blink_charging!(board, delay, watchman, 8);
545545

546546
// Initialize power supplies.
547-
let stusb4500 = match ThisBoard::STUSB4500_I2C_ADDR {
547+
let mut stusb4500 = match ThisBoard::STUSB4500_I2C_ADDR {
548548
Some(addr) => {
549549
// Verify and possibily reprogram NVM of STUSB4500.
550550
let mut reprogrammed = false;
@@ -622,6 +622,14 @@ mod app {
622622
}
623623
}
624624

625+
// Avoid losing charger momentarily while battery is very low.
626+
match &mut stusb4500 {
627+
Some(stusb4500) if prohibit_power_on => {
628+
stusb4500.prohibit_reset_until(monotonics::now() + 60u32.secs());
629+
}
630+
_ => (),
631+
}
632+
625633
// Prevent system power on if required.
626634
if prohibit_power_on && board.power_mode().is_full() {
627635
defmt::warn!("System power on is prohibited");

openemc-firmware/src/supply/stusb4500/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ pub struct StUsb4500<I2C> {
138138
best_pdo_requested: bool,
139139
report: PowerSupply,
140140
started: Instant,
141+
reset_prohibited_until: Option<Instant>,
142+
reset_queued: bool,
141143
_i2c: PhantomData<I2C>,
142144
}
143145

@@ -200,6 +202,8 @@ where
200202
best_pdo_requested: false,
201203
report: Default::default(),
202204
started: monotonics::now(),
205+
reset_prohibited_until: None,
206+
reset_queued: false,
203207
_i2c: PhantomData,
204208
}
205209
}
@@ -217,6 +221,8 @@ where
217221

218222
defmt::info!("STUSB4500 pin reset");
219223
self.reset = ResetState::PinResetHigh(monotonics::now());
224+
self.reset_prohibited_until = None;
225+
self.reset_queued = false;
220226
}
221227

222228
/// Initiates a register reset.
@@ -227,9 +233,13 @@ where
227233

228234
if power_on {
229235
defmt::info!("Skipping STUSB4500 register reset due to power on or pin reset");
236+
} else if self.reset_prohibited_until.map(|until| until >= monotonics::now()).unwrap_or_default() {
237+
defmt::info!("Queueing STUSB4500 register reset because it is currently prohibited");
238+
self.reset_queued = true;
230239
} else {
231240
defmt::info!("STUSB4500 register reset");
232241
self.write(i2c, REG_RESET, &[1])?;
242+
self.reset_queued = false;
233243
}
234244

235245
self.read(i2c, REG_ALERT_STATUS_1, 12)?;
@@ -628,6 +638,15 @@ where
628638

629639
defmt::trace!("STUSB4500 periodic");
630640

641+
// Perform queued reset, if necessary.
642+
if !self.reset_prohibited_until.map(|until| until >= monotonics::now()).unwrap_or_default()
643+
&& self.reset_queued
644+
{
645+
defmt::info!("Executing queued STUSB4500 register reset");
646+
self.reset_prohibited_until = None;
647+
self.start_register_reset(i2c, false)?;
648+
}
649+
631650
// Read monitoring status.
632651
self.update_monitoring_status(i2c)?;
633652
self.update_hw_fault_status(i2c)?;
@@ -805,6 +824,12 @@ where
805824
self.reset = ResetState::None;
806825
self.start_pin_reset();
807826
}
827+
828+
/// Prohibits register reset until the specified time.
829+
pub fn prohibit_reset_until(&mut self, until: Instant) {
830+
defmt::info!("STUSB4500 reset prohibited");
831+
self.reset_prohibited_until = Some(until);
832+
}
808833
}
809834

810835
// Register definitions.

0 commit comments

Comments
 (0)