mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-26 18:02:35 +00:00
feat(core): store fuel gauge covariance into backup ram [no changelog]
This commit is contained in:
parent
ac65d1f59d
commit
f050136abb
@ -148,7 +148,7 @@ backup_ram_status_t backup_ram_erase_unused(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
backup_ram_status_t backup_ram_store_power_manager_data(
|
backup_ram_status_t backup_ram_store_power_manager_data(
|
||||||
const backup_ram_power_manager_data_t *pm_data) {
|
const backup_ram_power_manager_data_t *pm_data) {
|
||||||
backup_ram_driver_t *drv = &backup_ram_driver;
|
backup_ram_driver_t *drv = &backup_ram_driver;
|
||||||
|
|
||||||
if (!drv->initialized) {
|
if (!drv->initialized) {
|
||||||
|
@ -44,7 +44,8 @@ typedef enum {
|
|||||||
* after power loss.
|
* after power loss.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float soc; // Captured state of charge <0, 1>
|
float soc; // Captured fuel gauge state of charge <0, 1>
|
||||||
|
float P; // Captured fuel gauge covariance
|
||||||
bool bat_critical;
|
bool bat_critical;
|
||||||
// Captures RTC time at which SOC was captured
|
// Captures RTC time at which SOC was captured
|
||||||
uint32_t last_capture_timestamp;
|
uint32_t last_capture_timestamp;
|
||||||
|
@ -27,11 +27,11 @@ void fuel_gauge_init(fuel_gauge_state_t* state, float R, float Q,
|
|||||||
state->Q = Q;
|
state->Q = Q;
|
||||||
state->R_aggressive = R_aggressive;
|
state->R_aggressive = R_aggressive;
|
||||||
state->Q_aggressive = Q_aggressive;
|
state->Q_aggressive = Q_aggressive;
|
||||||
state->P = P_init;
|
|
||||||
|
|
||||||
// Initialize state
|
// Initialize state
|
||||||
state->soc = 0.0f;
|
state->soc = 0.0f;
|
||||||
state->soc_latched = 0.0f;
|
state->soc_latched = 0.0f;
|
||||||
|
state->P = P_init; // Initial error covariance
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuel_gauge_reset(fuel_gauge_state_t* state) {
|
void fuel_gauge_reset(fuel_gauge_state_t* state) {
|
||||||
@ -40,10 +40,11 @@ void fuel_gauge_reset(fuel_gauge_state_t* state) {
|
|||||||
state->soc_latched = 0.0f;
|
state->soc_latched = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuel_gauge_set_soc(fuel_gauge_state_t* state, float soc) {
|
void fuel_gauge_set_soc(fuel_gauge_state_t* state, float soc, float P) {
|
||||||
// Set SOC directly
|
// Set SOC directly
|
||||||
state->soc = soc;
|
state->soc = soc;
|
||||||
state->soc_latched = soc;
|
state->soc_latched = soc;
|
||||||
|
state->P = P; // Set error covariance
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuel_gauge_initial_guess(fuel_gauge_state_t* state, float voltage_V,
|
void fuel_gauge_initial_guess(fuel_gauge_state_t* state, float voltage_V,
|
||||||
|
@ -59,7 +59,7 @@ void fuel_gauge_reset(fuel_gauge_state_t* state);
|
|||||||
* @param state Pointer to EKF state structure
|
* @param state Pointer to EKF state structure
|
||||||
* @param soc State of charge (0.0 to 1.0)
|
* @param soc State of charge (0.0 to 1.0)
|
||||||
*/
|
*/
|
||||||
void fuel_gauge_set_soc(fuel_gauge_state_t* state, float soc);
|
void fuel_gauge_set_soc(fuel_gauge_state_t* state, float soc, float P);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make initial SOC guess based on OCV
|
* Make initial SOC guess based on OCV
|
||||||
|
@ -101,7 +101,7 @@ pm_status_t pm_turn_on(void);
|
|||||||
pm_status_t pm_get_report(pm_report_t* report);
|
pm_status_t pm_get_report(pm_report_t* report);
|
||||||
pm_status_t pm_charging_enable(void);
|
pm_status_t pm_charging_enable(void);
|
||||||
pm_status_t pm_charging_disable(void);
|
pm_status_t pm_charging_disable(void);
|
||||||
pm_status_t pm_store_data_to_backup_ram(void);
|
pm_status_t pm_store_data_to_backup_ram();
|
||||||
pm_status_t pm_wait_until_active(uint32_t timeout_ms);
|
pm_status_t pm_wait_until_active(uint32_t timeout_ms);
|
||||||
pm_status_t pm_wakeup_flags_set(pm_wakeup_flags_t flags);
|
pm_status_t pm_wakeup_flags_set(pm_wakeup_flags_t flags);
|
||||||
pm_status_t pm_wakeup_flags_reset(void);
|
pm_status_t pm_wakeup_flags_reset(void);
|
||||||
|
@ -77,7 +77,7 @@ pm_status_t pm_init(bool inherit_state) {
|
|||||||
backup_ram_read_power_manager_data(&pm_recovery_data);
|
backup_ram_read_power_manager_data(&pm_recovery_data);
|
||||||
|
|
||||||
if (status == BACKUP_RAM_OK) {
|
if (status == BACKUP_RAM_OK) {
|
||||||
fuel_gauge_set_soc(&drv->fuel_gauge, pm_recovery_data.soc);
|
fuel_gauge_set_soc(&drv->fuel_gauge, pm_recovery_data.soc, pm_recovery_data.P);
|
||||||
} else {
|
} else {
|
||||||
// Wait for 1s to sample battery data
|
// Wait for 1s to sample battery data
|
||||||
systick_delay_ms(1000);
|
systick_delay_ms(1000);
|
||||||
@ -228,11 +228,11 @@ pm_status_t pm_hibernate(void) {
|
|||||||
drv->request_hibernate = true;
|
drv->request_hibernate = true;
|
||||||
pm_process_state_machine();
|
pm_process_state_machine();
|
||||||
|
|
||||||
if (drv->state != PM_STATE_HIBERNATE) {
|
systick_delay_ms(50);
|
||||||
return PM_REQUEST_REJECTED;
|
|
||||||
}
|
// Whenever hibernation request fall through, request was rejected
|
||||||
|
return PM_REQUEST_REJECTED;
|
||||||
|
|
||||||
return PM_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_status_t pm_turn_on(void) {
|
pm_status_t pm_turn_on(void) {
|
||||||
@ -324,7 +324,7 @@ pm_status_t pm_charging_disable(void) {
|
|||||||
return PM_OK;
|
return PM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_status_t pm_store_data_to_backup_ram(void) {
|
pm_status_t pm_store_data_to_backup_ram() {
|
||||||
pm_driver_t* drv = &g_pm;
|
pm_driver_t* drv = &g_pm;
|
||||||
|
|
||||||
if (!drv->initialized) {
|
if (!drv->initialized) {
|
||||||
@ -333,12 +333,15 @@ pm_status_t pm_store_data_to_backup_ram(void) {
|
|||||||
|
|
||||||
backup_ram_power_manager_data_t pm_data = {0};
|
backup_ram_power_manager_data_t pm_data = {0};
|
||||||
|
|
||||||
|
// Fuel gauge state
|
||||||
if (drv->battery_critical) {
|
if (drv->battery_critical) {
|
||||||
pm_data.soc = 0;
|
pm_data.soc = 0;
|
||||||
} else {
|
} else {
|
||||||
pm_data.soc = drv->fuel_gauge.soc;
|
pm_data.soc = drv->fuel_gauge.soc;
|
||||||
}
|
}
|
||||||
|
pm_data.P = drv->fuel_gauge.P;
|
||||||
|
|
||||||
|
// Power manager state
|
||||||
pm_data.bat_critical = drv->battery_critical;
|
pm_data.bat_critical = drv->battery_critical;
|
||||||
pm_data.bootloader_exit_state = drv->state;
|
pm_data.bootloader_exit_state = drv->state;
|
||||||
|
|
||||||
|
@ -105,21 +105,16 @@ void pm_enter_active(pm_driver_t* drv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pm_internal_state_t pm_handle_state_active(pm_driver_t* drv) {
|
pm_internal_state_t pm_handle_state_active(pm_driver_t* drv) {
|
||||||
|
|
||||||
// Handle hibernate request
|
// Handle hibernate request
|
||||||
if (drv->request_hibernate) {
|
if (drv->request_hibernate) {
|
||||||
drv->request_hibernate = false;
|
drv->request_hibernate = false;
|
||||||
|
|
||||||
return PM_STATE_HIBERNATE;
|
return PM_STATE_HIBERNATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle suspend request
|
// Handle suspend request
|
||||||
if (drv->request_suspend) {
|
if (drv->request_suspend) {
|
||||||
drv->request_suspend = false;
|
drv->request_suspend = false;
|
||||||
|
|
||||||
if (drv->usb_connected || drv->wireless_connected) {
|
|
||||||
return PM_STATE_CHARGING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PM_STATE_SUSPEND;
|
return PM_STATE_SUSPEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,21 +133,16 @@ void pm_enter_power_save(pm_driver_t* drv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pm_internal_state_t pm_handle_state_power_save(pm_driver_t* drv) {
|
pm_internal_state_t pm_handle_state_power_save(pm_driver_t* drv) {
|
||||||
|
|
||||||
// Handle hibernate request
|
// Handle hibernate request
|
||||||
if (drv->request_hibernate) {
|
if (drv->request_hibernate) {
|
||||||
drv->request_hibernate = false;
|
drv->request_hibernate = false;
|
||||||
|
|
||||||
return PM_STATE_HIBERNATE;
|
return PM_STATE_HIBERNATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle suspend request
|
// Handle suspend request
|
||||||
if (drv->request_suspend) {
|
if (drv->request_suspend) {
|
||||||
drv->request_suspend = false;
|
drv->request_suspend = false;
|
||||||
|
|
||||||
if (drv->usb_connected || drv->wireless_connected) {
|
|
||||||
return PM_STATE_CHARGING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PM_STATE_SUSPEND;
|
return PM_STATE_SUSPEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +160,13 @@ pm_internal_state_t pm_handle_state_power_save(pm_driver_t* drv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pm_internal_state_t pm_handle_state_shutting_down(pm_driver_t* drv) {
|
pm_internal_state_t pm_handle_state_shutting_down(pm_driver_t* drv) {
|
||||||
|
|
||||||
|
// System is shutting down, but user can still hibernate the device early.
|
||||||
|
if (drv->request_hibernate) {
|
||||||
|
drv->request_hibernate = false;
|
||||||
|
return PM_STATE_HIBERNATE;
|
||||||
|
}
|
||||||
|
|
||||||
// Return to power save if external power or battery recovered
|
// Return to power save if external power or battery recovered
|
||||||
if (drv->usb_connected || !drv->battery_critical) {
|
if (drv->usb_connected || !drv->battery_critical) {
|
||||||
return PM_STATE_POWER_SAVE;
|
return PM_STATE_POWER_SAVE;
|
||||||
@ -253,6 +250,7 @@ pm_internal_state_t pm_handle_state_hibernate(pm_driver_t* drv) {
|
|||||||
// State enter/exit actions
|
// State enter/exit actions
|
||||||
|
|
||||||
void pm_enter_report_low_battery(pm_driver_t* drv) {
|
void pm_enter_report_low_battery(pm_driver_t* drv) {
|
||||||
|
|
||||||
// Set backlight to minimum
|
// Set backlight to minimum
|
||||||
backlight_set_max_level(0);
|
backlight_set_max_level(0);
|
||||||
|
|
||||||
@ -273,15 +271,14 @@ void pm_exit_shutting_down(pm_driver_t* drv) {
|
|||||||
void pm_enter_suspend(pm_driver_t* drv) {
|
void pm_enter_suspend(pm_driver_t* drv) {
|
||||||
|
|
||||||
pm_control_suspend();
|
pm_control_suspend();
|
||||||
// Not implemented yet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm_enter_hibernate(pm_driver_t* drv) {
|
void pm_enter_hibernate(pm_driver_t* drv) {
|
||||||
|
|
||||||
// TODO: Store power manager data with request to hibernate
|
// Store power manager data with request to hibernate, power manager
|
||||||
// after reboot?
|
// will try to hibernate immediately after reboot.
|
||||||
pm_store_data_to_backup_ram();
|
pm_store_data_to_backup_ram();
|
||||||
|
|
||||||
reboot_device();
|
reboot_device();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user