mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-30 18:38:27 +00:00
feat(core): rework soc limit to battery model dependant soc target.
[no changelog]
This commit is contained in:
parent
93c3b54e2b
commit
6eed9178fa
@ -193,11 +193,21 @@ pm_status_t pm_charging_disable(void);
|
||||
pm_status_t pm_charging_set_max_current(uint16_t current_ma);
|
||||
|
||||
/**
|
||||
* @brief Set the battery State of Charge limit for operations
|
||||
* @param limit SoC limit percentage (0-100%)
|
||||
* @brief Set the battery State of Charge precharge target.
|
||||
*
|
||||
* Charging controller will continously compare taget SoC charging voltage from
|
||||
* battery model (temperature dependant) with the actual battery voltage and if
|
||||
* the battery voltage is above the target, charging is stopped. If the battery
|
||||
* voltage also cross the charging voltage target, Fuel gauge SoC estimate is
|
||||
* enforced with the target value.
|
||||
*
|
||||
* Setting value to `100` disables the precharge target and charging cycle will
|
||||
* be driven with PMIC driver.
|
||||
*
|
||||
* @param target SoC target percentage (0-100%)
|
||||
* @return pm_status_t Status code indicating success or failure
|
||||
*/
|
||||
pm_status_t pm_set_soc_limit(uint8_t limit);
|
||||
pm_status_t pm_set_soc_target(uint8_t target);
|
||||
|
||||
/**
|
||||
* @brief Suspends driver activity so the CPU can enter low-power mode.
|
||||
|
@ -156,8 +156,8 @@ pm_status_t pm_init(bool inherit_state) {
|
||||
// Enable charging by default to max current
|
||||
drv->charging_enabled = true;
|
||||
|
||||
// Set default SOC limit and max charging current limit
|
||||
drv->soc_limit = 100;
|
||||
// Set default SOC target and max charging current limit
|
||||
drv->soc_target = 100;
|
||||
drv->charging_current_max_limit_ma = PM_BATTERY_CHARGING_CURRENT_MAX;
|
||||
|
||||
// Fuel gauge SoC available, set fuel_gauge initialized.
|
||||
@ -527,23 +527,19 @@ static bool pm_load_recovery_data(pm_recovery_data_t* recovery) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pm_status_t pm_set_soc_limit(uint8_t limit) {
|
||||
pm_status_t pm_set_soc_target(uint8_t target) {
|
||||
pm_driver_t* drv = &g_pm;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return PM_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (limit > 100) {
|
||||
return PM_ERROR;
|
||||
}
|
||||
|
||||
if (limit <= PM_SOC_LIMIT_HYSTERESIS) {
|
||||
if (target > 100) {
|
||||
return PM_ERROR;
|
||||
}
|
||||
|
||||
irq_key_t irq_key = irq_lock();
|
||||
drv->soc_limit = limit;
|
||||
drv->soc_target = target;
|
||||
irq_unlock(irq_key);
|
||||
|
||||
return PM_OK;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#define PM_BATTERY_UNDERVOLT_RECOVERY_THR_V 3.1f
|
||||
#define PM_BATTERY_UNDERVOLT_RECOVERY_WPC_THR_V 3.2f
|
||||
#define PM_BATTERY_LOW_THRESHOLD_SOC 15
|
||||
#define PM_SOC_LIMIT_HYSTERESIS 5
|
||||
#define PM_BATTERY_CHARGING_CURRENT_MAX PMIC_CHARGING_LIMIT_MAX
|
||||
#define PM_BATTERY_CHARGING_CURRENT_MIN PMIC_CHARGING_LIMIT_MIN
|
||||
#define PM_BATTERY_SAMPLING_BUF_SIZE 10
|
||||
@ -85,8 +84,9 @@ typedef struct {
|
||||
uint8_t bat_sampling_buf_tail_idx;
|
||||
uint8_t bat_sampling_buf_head_idx;
|
||||
uint8_t soc_ceiled;
|
||||
uint8_t soc_limit;
|
||||
bool soc_limit_reached;
|
||||
|
||||
uint8_t soc_target;
|
||||
bool soc_target_reached;
|
||||
|
||||
// Battery charging state
|
||||
bool charging_enabled;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <sys/systick.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "../fuel_gauge/battery_model.h"
|
||||
#include "../fuel_gauge/fuel_gauge.h"
|
||||
#include "../stwlc38/stwlc38.h"
|
||||
#include "power_manager_internal.h"
|
||||
@ -167,15 +168,33 @@ void pm_charging_controller(pm_driver_t* drv) {
|
||||
pmic_set_charging_limit(drv->charging_current_target_ma);
|
||||
}
|
||||
|
||||
if ((drv->soc_ceiled >= drv->soc_limit) && (drv->soc_limit != 100)) {
|
||||
drv->soc_limit_reached = true;
|
||||
} else if ((drv->soc_limit == 100) ||
|
||||
(drv->soc_ceiled < (drv->soc_limit - PM_SOC_LIMIT_HYSTERESIS))) {
|
||||
drv->soc_limit_reached = false;
|
||||
if (drv->soc_target == 100) {
|
||||
drv->soc_target_reached = false;
|
||||
} else {
|
||||
// Translate SoC target to charging voltage via battery model
|
||||
float target_ocv_voltage_v =
|
||||
battery_ocv(drv->soc_target / 100.0f, drv->pmic_data.ntc_temp, false);
|
||||
|
||||
float battery_ocv_v = battery_meas_to_ocv(
|
||||
drv->pmic_data.vbat, drv->pmic_data.ibat, drv->pmic_data.ntc_temp);
|
||||
|
||||
if (battery_ocv_v > target_ocv_voltage_v) {
|
||||
// current voltage is within tight bounds of target voltage,
|
||||
// we may also force SoC estimate to target value.
|
||||
if (battery_ocv_v < target_ocv_voltage_v + 0.15) {
|
||||
fuel_gauge_set_soc(&drv->fuel_gauge,
|
||||
(drv->soc_target / 100.0f) - 0.0001f,
|
||||
drv->fuel_gauge.P);
|
||||
}
|
||||
|
||||
drv->soc_target_reached = true;
|
||||
|
||||
} else if (drv->soc_ceiled < drv->soc_target) {
|
||||
drv->soc_target_reached = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (drv->soc_limit_reached) {
|
||||
// Set charging current limit to 0
|
||||
if (drv->soc_target_reached) {
|
||||
drv->charging_current_target_ma = 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user