mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-04 21:05:29 +00:00
chore(core): put soc recovery inside the pm_init [no changelog]
This commit is contained in:
parent
f6bb7684cc
commit
ac65d1f59d
@ -91,7 +91,7 @@ typedef struct {
|
|||||||
} pm_report_t;
|
} pm_report_t;
|
||||||
|
|
||||||
/* Public API functions */
|
/* Public API functions */
|
||||||
pm_status_t pm_init(bool skip_boot_sequence);
|
pm_status_t pm_init(bool inherit_state);
|
||||||
void pm_deinit(void);
|
void pm_deinit(void);
|
||||||
pm_status_t pm_get_events(pm_event_t* event_flags);
|
pm_status_t pm_get_events(pm_event_t* event_flags);
|
||||||
pm_status_t pm_get_state(pm_state_t* state);
|
pm_status_t pm_get_state(pm_state_t* state);
|
||||||
|
@ -38,7 +38,7 @@ static void pm_shutdown_timer_handler(void* context);
|
|||||||
|
|
||||||
// API Implementation
|
// API Implementation
|
||||||
|
|
||||||
pm_status_t pm_init(bool skip_bootup_sequence) {
|
pm_status_t pm_init(bool inherit_state) {
|
||||||
pm_driver_t* drv = &g_pm;
|
pm_driver_t* drv = &g_pm;
|
||||||
|
|
||||||
if (drv->initialized) {
|
if (drv->initialized) {
|
||||||
@ -59,38 +59,6 @@ pm_status_t pm_init(bool skip_bootup_sequence) {
|
|||||||
PM_FUEL_GAUGE_R_AGGRESSIVE, PM_FUEL_GAUGE_Q_AGGRESSIVE,
|
PM_FUEL_GAUGE_R_AGGRESSIVE, PM_FUEL_GAUGE_Q_AGGRESSIVE,
|
||||||
PM_FUEL_GAUGE_P_INIT);
|
PM_FUEL_GAUGE_P_INIT);
|
||||||
|
|
||||||
if (skip_bootup_sequence) {
|
|
||||||
// Skip bootup sequence and try to recover the power manages state left
|
|
||||||
// by the bootloader in backup ram.
|
|
||||||
|
|
||||||
backup_ram_power_manager_data_t pm_recovery_data;
|
|
||||||
backup_ram_status_t status =
|
|
||||||
backup_ram_read_power_manager_data(&pm_recovery_data);
|
|
||||||
|
|
||||||
if (status != BACKUP_RAM_OK &&
|
|
||||||
(pm_recovery_data.bootloader_exit_state != PM_STATE_POWER_SAVE &&
|
|
||||||
pm_recovery_data.bootloader_exit_state != PM_STATE_ACTIVE)) {
|
|
||||||
drv->state = PM_STATE_POWER_SAVE;
|
|
||||||
drv->fuel_gauge_request_new_guess = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Backup RAM contain valid data
|
|
||||||
drv->state = pm_recovery_data.bootloader_exit_state;
|
|
||||||
fuel_gauge_set_soc(&drv->fuel_gauge,pm_recovery_data.soc);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
drv->fuel_gauge_initialized = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Start in lowest state and wait for the bootup sequence to
|
|
||||||
// finish (call of pm_turn_on())
|
|
||||||
drv->state = PM_STATE_HIBERNATE;
|
|
||||||
drv->initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable charging by default
|
|
||||||
drv->charging_enabled = false;
|
|
||||||
|
|
||||||
// Create monitoring timer
|
// Create monitoring timer
|
||||||
drv->monitoring_timer = systimer_create(pm_monitoring_timer_handler, NULL);
|
drv->monitoring_timer = systimer_create(pm_monitoring_timer_handler, NULL);
|
||||||
@ -102,7 +70,54 @@ pm_status_t pm_init(bool skip_bootup_sequence) {
|
|||||||
// Initial power source measurement
|
// Initial power source measurement
|
||||||
npm1300_measure(pm_pmic_data_ready, NULL);
|
npm1300_measure(pm_pmic_data_ready, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
// Try to recover SoC from the backup RAM
|
||||||
|
backup_ram_power_manager_data_t pm_recovery_data;
|
||||||
|
backup_ram_status_t status =
|
||||||
|
backup_ram_read_power_manager_data(&pm_recovery_data);
|
||||||
|
|
||||||
|
if (status == BACKUP_RAM_OK) {
|
||||||
|
fuel_gauge_set_soc(&drv->fuel_gauge, pm_recovery_data.soc);
|
||||||
|
} else {
|
||||||
|
// Wait for 1s to sample battery data
|
||||||
|
systick_delay_ms(1000);
|
||||||
|
pm_battery_initial_soc_guess();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inherit_state){
|
||||||
|
|
||||||
|
// Inherit power manager state left in beckup RAM from bootloader.
|
||||||
|
// in case of error, start with PM_STATE_POWER_SAVE as a lowest state in
|
||||||
|
// active mode.
|
||||||
|
if (status != BACKUP_RAM_OK &&
|
||||||
|
(pm_recovery_data.bootloader_exit_state != PM_STATE_POWER_SAVE &&
|
||||||
|
pm_recovery_data.bootloader_exit_state != PM_STATE_ACTIVE)) {
|
||||||
|
|
||||||
|
drv->state = PM_STATE_POWER_SAVE;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Backup RAM contain valid data
|
||||||
|
drv->state = pm_recovery_data.bootloader_exit_state;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
// Start in lowest state and wait for the bootup sequence to
|
||||||
|
// finish (call of pm_turn_on())
|
||||||
|
drv->state = PM_STATE_HIBERNATE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fuel gauge SoC available, set fuel_gauge initialized.
|
||||||
|
drv->fuel_gauge_initialized = true;
|
||||||
|
|
||||||
|
// Enable charging by default
|
||||||
|
drv->charging_enabled = true;
|
||||||
|
|
||||||
drv->initialized = true;
|
drv->initialized = true;
|
||||||
|
|
||||||
return PM_OK;
|
return PM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,24 +263,9 @@ pm_status_t pm_turn_on(void) {
|
|||||||
return PM_REQUEST_REJECTED;
|
return PM_REQUEST_REJECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to recover SoC from the backup RAM
|
|
||||||
backup_ram_power_manager_data_t pm_recovery_data;
|
|
||||||
backup_ram_status_t status =
|
|
||||||
backup_ram_read_power_manager_data(&pm_recovery_data);
|
|
||||||
|
|
||||||
if (status == BACKUP_RAM_OK && pm_recovery_data.soc != 0.0f) {
|
|
||||||
fuel_gauge_set_soc(&drv->fuel_gauge, pm_recovery_data.soc);
|
|
||||||
} else {
|
|
||||||
// Wait for 1s to sample battery data
|
|
||||||
systick_delay_ms(1000);
|
|
||||||
pm_battery_initial_soc_guess();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set monitoiring timer with longer period
|
// Set monitoiring timer with longer period
|
||||||
systimer_set_periodic(drv->monitoring_timer, PM_TIMER_PERIOD_MS);
|
systimer_set_periodic(drv->monitoring_timer, PM_TIMER_PERIOD_MS);
|
||||||
|
|
||||||
drv->fuel_gauge_initialized = true;
|
|
||||||
|
|
||||||
return PM_OK;
|
return PM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,6 @@ typedef struct {
|
|||||||
// Fuel gauge
|
// Fuel gauge
|
||||||
fuel_gauge_state_t fuel_gauge;
|
fuel_gauge_state_t fuel_gauge;
|
||||||
bool fuel_gauge_initialized;
|
bool fuel_gauge_initialized;
|
||||||
bool fuel_gauge_request_new_guess;
|
|
||||||
pm_sampling_data_t bat_sampling_buf[PM_BATTERY_SAMPLING_BUF_SIZE];
|
pm_sampling_data_t bat_sampling_buf[PM_BATTERY_SAMPLING_BUF_SIZE];
|
||||||
uint8_t bat_sampling_buf_tail_idx;
|
uint8_t bat_sampling_buf_tail_idx;
|
||||||
uint8_t bat_sampling_buf_head_idx;
|
uint8_t bat_sampling_buf_head_idx;
|
||||||
|
@ -35,39 +35,6 @@ void pm_monitor_power_sources(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update fuel gauge state
|
|
||||||
if (drv->fuel_gauge_initialized) {
|
|
||||||
if (drv->fuel_gauge_request_new_guess) {
|
|
||||||
// Request new single SoC guess based on the latest measurements
|
|
||||||
fuel_gauge_initial_guess(&drv->fuel_gauge, drv->pmic_data.vbat,
|
|
||||||
drv->pmic_data.ibat, drv->pmic_data.ntc_temp);
|
|
||||||
|
|
||||||
drv->fuel_gauge_request_new_guess = false;
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fuel_gauge_update(&drv->fuel_gauge, drv->pmic_sampling_period_ms,
|
|
||||||
drv->pmic_data.vbat, drv->pmic_data.ibat,
|
|
||||||
drv->pmic_data.ntc_temp);
|
|
||||||
|
|
||||||
// Ceil the float soc to user friendly integer
|
|
||||||
uint8_t soc_ceiled_temp =
|
|
||||||
(int)(drv->fuel_gauge.soc_latched * 100 + 0.999f);
|
|
||||||
if (soc_ceiled_temp != drv->soc_ceiled) {
|
|
||||||
drv->soc_ceiled = soc_ceiled_temp;
|
|
||||||
PM_SET_EVENT(drv->event_flags, PM_EVENT_SOC_UPDATED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
pm_battery_sampling(drv->pmic_data.vbat, drv->pmic_data.ibat,
|
|
||||||
drv->pmic_data.ntc_temp);
|
|
||||||
|
|
||||||
// Battery sampling period, collect data before initial guess is made.
|
|
||||||
fuel_gauge_initial_guess(&drv->fuel_gauge, drv->pmic_data.vbat,
|
|
||||||
drv->pmic_data.ibat, drv->pmic_data.ntc_temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check USB power source status
|
// Check USB power source status
|
||||||
if (drv->pmic_data.usb_status != 0x0) {
|
if (drv->pmic_data.usb_status != 0x0) {
|
||||||
if (!drv->usb_connected) {
|
if (!drv->usb_connected) {
|
||||||
@ -103,6 +70,35 @@ void pm_monitor_power_sources(void) {
|
|||||||
drv->battery_critical = false;
|
drv->battery_critical = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run battery charging controller
|
||||||
|
pm_charging_controller(drv);
|
||||||
|
|
||||||
|
// Fuel gauge not initialized yet, battery SoC not available,
|
||||||
|
// Sample the battery data into the circular buffer, request new PMIC
|
||||||
|
if(!drv->fuel_gauge_initialized){
|
||||||
|
|
||||||
|
pm_battery_sampling(drv->pmic_data.vbat, drv->pmic_data.ibat,
|
||||||
|
drv->pmic_data.ntc_temp);
|
||||||
|
|
||||||
|
// Request fresh measurements
|
||||||
|
npm1300_measure(pm_pmic_data_ready, NULL);
|
||||||
|
drv->pmic_measurement_ready = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fuel_gauge_update(&drv->fuel_gauge, drv->pmic_sampling_period_ms,
|
||||||
|
drv->pmic_data.vbat, drv->pmic_data.ibat,
|
||||||
|
drv->pmic_data.ntc_temp);
|
||||||
|
|
||||||
|
// Ceil the float soc to user friendly integer
|
||||||
|
uint8_t soc_ceiled_temp = (int)(drv->fuel_gauge.soc_latched * 100 + 0.999f);
|
||||||
|
if (soc_ceiled_temp != drv->soc_ceiled) {
|
||||||
|
drv->soc_ceiled = soc_ceiled_temp;
|
||||||
|
PM_SET_EVENT(drv->event_flags, PM_EVENT_SOC_UPDATED);
|
||||||
|
}
|
||||||
|
|
||||||
// Check battery voltage for low threshold
|
// Check battery voltage for low threshold
|
||||||
if (drv->soc_ceiled <= PM_BATTERY_LOW_THRESHOLD_SOC && !drv->battery_low) {
|
if (drv->soc_ceiled <= PM_BATTERY_LOW_THRESHOLD_SOC && !drv->battery_low) {
|
||||||
drv->battery_low = true;
|
drv->battery_low = true;
|
||||||
@ -111,9 +107,6 @@ void pm_monitor_power_sources(void) {
|
|||||||
drv->battery_low = false;
|
drv->battery_low = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run battery charging controller
|
|
||||||
pm_charging_controller(drv);
|
|
||||||
|
|
||||||
// Process state machine with updated battery and power source information
|
// Process state machine with updated battery and power source information
|
||||||
pm_process_state_machine();
|
pm_process_state_machine();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user