diff --git a/core/embed/sys/backup_ram/backup_ram.c b/core/embed/sys/backup_ram/backup_ram.c index 525356aef9..b73b0e4ab6 100644 --- a/core/embed/sys/backup_ram/backup_ram.c +++ b/core/embed/sys/backup_ram/backup_ram.c @@ -186,6 +186,11 @@ backup_ram_status_t backup_ram_read_power_manager_data( return BACKUP_RAM_DATA_CHECK_ERROR; } + // If SoC is equal to 0.0f, battery critical flag must be set + if (pm_data->soc == 0.0f && !pm_data->bat_critical) { + return BACKUP_RAM_DATA_CHECK_ERROR; + } + return BACKUP_RAM_OK; } diff --git a/core/embed/sys/power_manager/stm32u5/power_manager.c b/core/embed/sys/power_manager/stm32u5/power_manager.c index 5ce23889f4..659f390738 100644 --- a/core/embed/sys/power_manager/stm32u5/power_manager.c +++ b/core/embed/sys/power_manager/stm32u5/power_manager.c @@ -27,6 +27,9 @@ #include "../stwlc38/stwlc38.h" #include "power_manager_internal.h" + +#pragma GCC optimize ("O0") + // Global driver instance pm_driver_t g_pm = { .initialized = false, @@ -55,7 +58,7 @@ pm_status_t pm_init(bool skip_bootup_sequence) { } // 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_P_INIT); @@ -76,8 +79,8 @@ pm_status_t pm_init(bool skip_bootup_sequence) { } else { // Backup RAM contain valid data drv->state = pm_recovery_data.bootloader_exit_state; - drv->fuel_gauge.soc = pm_recovery_data.soc; - drv->fuel_gauge_request_new_guess = false; + fuel_gauge_set_soc(&drv->fuel_gauge,pm_recovery_data.soc); + } drv->fuel_gauge_initialized = true; @@ -109,10 +112,6 @@ pm_status_t pm_init(bool skip_bootup_sequence) { void pm_deinit(void) { pm_driver_t* drv = &g_pm; - if(drv->fuel_gauge_initialized){ - pm_store_data_to_backup_ram(); - } - if (drv->monitoring_timer) { systimer_delete(drv->monitoring_timer); drv->monitoring_timer = NULL; @@ -123,6 +122,10 @@ void pm_deinit(void) { drv->shutdown_timer = NULL; } + if(drv->fuel_gauge_initialized){ + pm_store_data_to_backup_ram(); + } + npm1300_deinit(); stwlc38_deinit(); @@ -228,9 +231,9 @@ pm_status_t pm_turn_on(void) { } // Poll until at least single PMIC measurement is done - while(drv->pmic_last_update_ms == 0){ - } + while(drv->pmic_last_update_ms == 0){}; + // Check if device has enough power to startup if(drv->pmic_data.usb_status == 0x0 && drv->pmic_data.vbat < PM_BATTERY_UNDERVOLT_RECOVERY_THR_V){ return PM_REQUEST_REJECTED; @@ -243,16 +246,16 @@ pm_status_t pm_turn_on(void) { return PM_REQUEST_REJECTED; } - irq_key_t irq_key = irq_lock(); - // 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) { - drv->fuel_gauge.soc = pm_recovery_data.soc; + 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(); } @@ -261,8 +264,6 @@ pm_status_t pm_turn_on(void) { drv->fuel_gauge_initialized = true; - irq_unlock(irq_key); - return PM_OK; } diff --git a/core/embed/sys/power_manager/stm32u5/power_manager_internal.h b/core/embed/sys/power_manager/stm32u5/power_manager_internal.h index 6aa09eef01..e16ae54ec7 100644 --- a/core/embed/sys/power_manager/stm32u5/power_manager_internal.h +++ b/core/embed/sys/power_manager/stm32u5/power_manager_internal.h @@ -89,8 +89,8 @@ typedef struct { // Power source hardware state npm1300_report_t pmic_data; stwlc38_report_t wireless_data; - uint32_t pmic_last_update_ms; - uint32_t pmic_sampling_period_ms; + volatile uint32_t pmic_last_update_ms; + volatile uint32_t pmic_sampling_period_ms; bool pmic_measurement_ready; // Power source logical state diff --git a/core/embed/sys/power_manager/stm32u5/power_monitoring.c b/core/embed/sys/power_manager/stm32u5/power_monitoring.c index 6dea5e3b9b..d5a6b36ee3 100644 --- a/core/embed/sys/power_manager/stm32u5/power_monitoring.c +++ b/core/embed/sys/power_manager/stm32u5/power_monitoring.c @@ -27,6 +27,8 @@ #include "../stwlc38/stwlc38.h" #include "power_manager_internal.h" +#pragma GCC optimize ("O0") + void pm_monitor_power_sources(void) { pm_driver_t* drv = &g_pm; @@ -133,7 +135,7 @@ void pm_pmic_data_ready(void* context, npm1300_report_t* report) { drv->pmic_sampling_period_ms = PM_BATTERY_SAMPLING_PERIOD_MS; } else { // Timeout, reset the last update timestamp - drv->pmic_sampling_period_ms = drv->pmic_last_update_ms - systick_ms(); + drv->pmic_sampling_period_ms = systick_ms() - drv->pmic_last_update_ms; } drv->pmic_last_update_ms = systick_ms();