mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-26 18:02:35 +00:00
fix(core): remove ULTRA_POWER_SAVE and STARTUP_REJECTED states, improve battery low state detection [no changelog]
This commit is contained in:
parent
19948372c7
commit
3beebe5956
@ -45,15 +45,15 @@ pm_status_t pm_init(bool skip_bootup_sequence) {
|
|||||||
return PM_OK;
|
return PM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear driver instance
|
||||||
|
memset(drv, 0, sizeof(pm_driver_t));
|
||||||
|
|
||||||
// Initialize hardware subsystems
|
// Initialize hardware subsystems
|
||||||
if (!npm1300_init() || !stwlc38_init()) {
|
if (!npm1300_init() || !stwlc38_init()) {
|
||||||
pm_deinit();
|
pm_deinit();
|
||||||
return PM_ERROR;
|
return PM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear fuel gauge state
|
|
||||||
memset(&drv->fuel_gauge, 0, sizeof(fuel_gauge_state_t));
|
|
||||||
|
|
||||||
// Initialize fuel gauge
|
// Initialize fuel gauge
|
||||||
fuel_gauge_init(&(drv->fuel_gauge), PM_FUEL_GAUGE_R, PM_FUEL_GAUGE_Q,
|
fuel_gauge_init(&(drv->fuel_gauge), PM_FUEL_GAUGE_R, PM_FUEL_GAUGE_Q,
|
||||||
PM_FUEL_GAUGE_R_AGGRESSIVE, PM_FUEL_GAUGE_Q_AGGRESSIVE,
|
PM_FUEL_GAUGE_R_AGGRESSIVE, PM_FUEL_GAUGE_Q_AGGRESSIVE,
|
||||||
@ -227,6 +227,15 @@ pm_status_t pm_turn_on(void) {
|
|||||||
return PM_NOT_INITIALIZED;
|
return PM_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Poll until at least single PMIC measurement is done
|
||||||
|
while(drv->pmic_last_update_ms == 0){
|
||||||
|
}
|
||||||
|
|
||||||
|
if(drv->pmic_data.usb_status == 0x0 &&
|
||||||
|
drv->pmic_data.vbat < PM_BATTERY_UNDERVOLT_RECOVERY_THR_V){
|
||||||
|
return PM_REQUEST_REJECTED;
|
||||||
|
}
|
||||||
|
|
||||||
drv->request_turn_on = true;
|
drv->request_turn_on = true;
|
||||||
pm_process_state_machine();
|
pm_process_state_machine();
|
||||||
|
|
||||||
@ -320,8 +329,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};
|
||||||
|
|
||||||
|
if (drv->battery_critical) {
|
||||||
|
pm_data.soc = 0;
|
||||||
|
} else {
|
||||||
|
pm_data.soc = drv->fuel_gauge.soc;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm_data.bat_critical = drv->battery_critical;
|
||||||
pm_data.bootloader_exit_state = drv->state;
|
pm_data.bootloader_exit_state = drv->state;
|
||||||
pm_data.soc = drv->fuel_gauge.soc;
|
|
||||||
|
|
||||||
backup_ram_status_t status = backup_ram_store_power_manager_data(&pm_data);
|
backup_ram_status_t status = backup_ram_store_power_manager_data(&pm_data);
|
||||||
|
|
||||||
|
@ -31,10 +31,10 @@
|
|||||||
#define PM_TIMER_PERIOD_MS 300
|
#define PM_TIMER_PERIOD_MS 300
|
||||||
#define PM_BATTERY_SAMPLING_PERIOD_MS 100
|
#define PM_BATTERY_SAMPLING_PERIOD_MS 100
|
||||||
#define PM_SHUTDOWN_TIMEOUT_MS 15000
|
#define PM_SHUTDOWN_TIMEOUT_MS 15000
|
||||||
#define PM_BATTERY_UNDERVOLT_THRESHOLD_V 3.0f
|
#define PM_BATTERY_UNDERVOLT_THR_V 3.0f
|
||||||
#define PM_BATTERY_UNDERVOLT_HYSTERESIS_V 0.5f
|
#define PM_BATTERY_UNDERVOLT_RECOVERY_THR_V 3.3f
|
||||||
#define PM_BATTERY_LOW_THRESHOLD_V 3.15f
|
#define PM_BATTERY_LOW_THRESHOLD_SOC 15
|
||||||
#define PM_BATTERY_LOW_RECOVERY_V 3.2f
|
|
||||||
#define PM_BATTERY_SAMPLING_BUF_SIZE 10
|
#define PM_BATTERY_SAMPLING_BUF_SIZE 10
|
||||||
|
|
||||||
#define PM_WPC_CHARGE_CURR_STEP_MA 50
|
#define PM_WPC_CHARGE_CURR_STEP_MA 50
|
||||||
@ -50,22 +50,13 @@
|
|||||||
#define PM_CLEAR_EVENT(flags, event) ((flags) &= ~(event))
|
#define PM_CLEAR_EVENT(flags, event) ((flags) &= ~(event))
|
||||||
#define PM_CLEAR_ALL_EVENTS(flags) ((flags) = 0)
|
#define PM_CLEAR_ALL_EVENTS(flags) ((flags) = 0)
|
||||||
|
|
||||||
/* Power manager states */
|
|
||||||
#define PM_STATE_LIST(STATE) \
|
|
||||||
STATE(HIBERNATE) \
|
|
||||||
STATE(CHARGING) \
|
|
||||||
STATE(STARTUP_REJECTED) \
|
|
||||||
STATE(SUSPEND) \
|
|
||||||
STATE(ULTRA_POWER_SAVE) \
|
|
||||||
STATE(SHUTTING_DOWN) \
|
|
||||||
STATE(POWER_SAVE) \
|
|
||||||
STATE(ACTIVE)
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
#define STATE(name) PM_STATE_##name,
|
PM_STATE_HIBERNATE,
|
||||||
PM_STATE_LIST(STATE)
|
PM_STATE_CHARGING,
|
||||||
#undef STATE
|
PM_STATE_SUSPEND,
|
||||||
PM_STATE_COUNT
|
PM_STATE_SHUTTING_DOWN,
|
||||||
|
PM_STATE_POWER_SAVE,
|
||||||
|
PM_STATE_ACTIVE,
|
||||||
} pm_internal_state_t;
|
} pm_internal_state_t;
|
||||||
|
|
||||||
// Power manager battery sampling data structure)
|
// Power manager battery sampling data structure)
|
||||||
|
@ -44,6 +44,7 @@ void pm_monitor_power_sources(void) {
|
|||||||
|
|
||||||
drv->fuel_gauge_request_new_guess = false;
|
drv->fuel_gauge_request_new_guess = false;
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fuel_gauge_update(&drv->fuel_gauge, PM_BATTERY_SAMPLING_PERIOD_MS,
|
fuel_gauge_update(&drv->fuel_gauge, PM_BATTERY_SAMPLING_PERIOD_MS,
|
||||||
drv->pmic_data.vbat, drv->pmic_data.ibat,
|
drv->pmic_data.vbat, drv->pmic_data.ibat,
|
||||||
@ -94,19 +95,18 @@ void pm_monitor_power_sources(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check battery voltage for critical (undervoltage) threshold
|
// Check battery voltage for critical (undervoltage) threshold
|
||||||
if ((drv->pmic_data.vbat < PM_BATTERY_UNDERVOLT_THRESHOLD_V) &&
|
if ((drv->pmic_data.vbat < PM_BATTERY_UNDERVOLT_THR_V) &&
|
||||||
!drv->battery_critical) {
|
!drv->battery_critical) {
|
||||||
drv->battery_critical = true;
|
drv->battery_critical = true;
|
||||||
} else if (drv->pmic_data.vbat > (PM_BATTERY_UNDERVOLT_THRESHOLD_V +
|
} else if (drv->pmic_data.vbat > (PM_BATTERY_UNDERVOLT_RECOVERY_THR_V) &&
|
||||||
PM_BATTERY_UNDERVOLT_HYSTERESIS_V) &&
|
|
||||||
drv->battery_critical) {
|
drv->battery_critical) {
|
||||||
drv->battery_critical = false;
|
drv->battery_critical = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check battery voltage for low threshold
|
// Check battery voltage for low threshold
|
||||||
if (drv->pmic_data.vbat < PM_BATTERY_LOW_THRESHOLD_V && !drv->battery_low) {
|
if (drv->soc_ceiled <= PM_BATTERY_LOW_THRESHOLD_SOC && !drv->battery_low) {
|
||||||
drv->battery_low = true;
|
drv->battery_low = true;
|
||||||
} else if (drv->pmic_data.vbat > PM_BATTERY_LOW_RECOVERY_V &&
|
} else if (drv->soc_ceiled > PM_BATTERY_LOW_THRESHOLD_SOC &&
|
||||||
drv->battery_low) {
|
drv->battery_low) {
|
||||||
drv->battery_low = false;
|
drv->battery_low = false;
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,6 @@
|
|||||||
#ifdef USE_BUTTON
|
#ifdef USE_BUTTON
|
||||||
#include <io/button.h>
|
#include <io/button.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_RGB_LED
|
|
||||||
#include <io/rgb_led.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/bootutils.h>
|
#include <sys/bootutils.h>
|
||||||
#include <sys/systick.h>
|
#include <sys/systick.h>
|
||||||
#include <sys/systimer.h>
|
#include <sys/systimer.h>
|
||||||
@ -45,12 +42,6 @@ static const pm_state_handler_t state_handlers[] = {
|
|||||||
.handle = pm_handle_state_power_save,
|
.handle = pm_handle_state_power_save,
|
||||||
.exit = NULL,
|
.exit = NULL,
|
||||||
},
|
},
|
||||||
[PM_STATE_ULTRA_POWER_SAVE] =
|
|
||||||
{
|
|
||||||
.enter = NULL,
|
|
||||||
.handle = pm_handle_state_ultra_power_save,
|
|
||||||
.exit = NULL,
|
|
||||||
},
|
|
||||||
[PM_STATE_SHUTTING_DOWN] =
|
[PM_STATE_SHUTTING_DOWN] =
|
||||||
{
|
{
|
||||||
.enter = pm_enter_shutting_down,
|
.enter = pm_enter_shutting_down,
|
||||||
@ -63,17 +54,11 @@ static const pm_state_handler_t state_handlers[] = {
|
|||||||
.handle = pm_handle_state_suspend,
|
.handle = pm_handle_state_suspend,
|
||||||
.exit = NULL,
|
.exit = NULL,
|
||||||
},
|
},
|
||||||
[PM_STATE_STARTUP_REJECTED] =
|
|
||||||
{
|
|
||||||
.enter = NULL,
|
|
||||||
.handle = pm_handle_state_startup_rejected,
|
|
||||||
.exit = NULL,
|
|
||||||
},
|
|
||||||
[PM_STATE_CHARGING] =
|
[PM_STATE_CHARGING] =
|
||||||
{
|
{
|
||||||
.enter = pm_enter_charging,
|
.enter = NULL,
|
||||||
.handle = pm_handle_state_charging,
|
.handle = pm_handle_state_charging,
|
||||||
.exit = pm_exit_charging,
|
.exit = NULL,
|
||||||
},
|
},
|
||||||
[PM_STATE_HIBERNATE] =
|
[PM_STATE_HIBERNATE] =
|
||||||
{
|
{
|
||||||
@ -184,17 +169,6 @@ pm_internal_state_t pm_handle_state_power_save(pm_driver_t* drv) {
|
|||||||
return drv->state;
|
return drv->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_internal_state_t pm_handle_state_ultra_power_save(pm_driver_t* drv) {
|
|
||||||
// Go to power save if external power or battery above critical
|
|
||||||
if (drv->usb_connected || !drv->battery_critical) {
|
|
||||||
return PM_STATE_POWER_SAVE;
|
|
||||||
} else {
|
|
||||||
return PM_STATE_STARTUP_REJECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return drv->state;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
||||||
// 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) {
|
||||||
@ -227,20 +201,11 @@ pm_internal_state_t pm_handle_state_startup_rejected(pm_driver_t* drv) {
|
|||||||
return drv->state;
|
return drv->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm_enter_charging(pm_driver_t* drv) {
|
|
||||||
|
|
||||||
#ifdef USE_RGB_LED
|
|
||||||
// Initialize RGB
|
|
||||||
rgb_led_init();
|
|
||||||
rgb_led_set_color(0x0000FF);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pm_internal_state_t pm_handle_state_charging(pm_driver_t* drv) {
|
pm_internal_state_t pm_handle_state_charging(pm_driver_t* drv) {
|
||||||
|
|
||||||
if (drv->request_turn_on) {
|
if (drv->request_turn_on) {
|
||||||
drv->request_turn_on = false;
|
drv->request_turn_on = false;
|
||||||
return PM_STATE_ULTRA_POWER_SAVE;
|
return PM_STATE_POWER_SAVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go back to hibernate if external power was removed.
|
// Go back to hibernate if external power was removed.
|
||||||
@ -260,19 +225,12 @@ pm_internal_state_t pm_handle_state_charging(pm_driver_t* drv) {
|
|||||||
return drv->state;
|
return drv->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm_exit_charging(pm_driver_t* drv) {
|
|
||||||
|
|
||||||
#ifdef USE_RGB_LED
|
|
||||||
// Turn off RGB LED
|
|
||||||
rgb_led_set_color(0x0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pm_internal_state_t pm_handle_state_hibernate(pm_driver_t* drv) {
|
pm_internal_state_t pm_handle_state_hibernate(pm_driver_t* drv) {
|
||||||
|
|
||||||
if (drv->request_turn_on) {
|
if (drv->request_turn_on) {
|
||||||
drv->request_turn_on = false;
|
drv->request_turn_on = false;
|
||||||
return PM_STATE_ULTRA_POWER_SAVE;
|
return PM_STATE_POWER_SAVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// External power source, start charging
|
// External power source, start charging
|
||||||
@ -298,8 +256,6 @@ 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);
|
||||||
|
|
||||||
// Set RGB LED to red
|
|
||||||
// rgb_led_set_color(RGB_LED_COLOR_RED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm_enter_shutting_down(pm_driver_t* drv) {
|
void pm_enter_shutting_down(pm_driver_t* drv) {
|
||||||
|
Loading…
Reference in New Issue
Block a user