mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-02 11:58:32 +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);
|
pm_status_t pm_charging_set_max_current(uint16_t current_ma);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the battery State of Charge limit for operations
|
* @brief Set the battery State of Charge precharge target.
|
||||||
* @param limit SoC limit percentage (0-100%)
|
*
|
||||||
|
* 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
|
* @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.
|
* @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
|
// Enable charging by default to max current
|
||||||
drv->charging_enabled = true;
|
drv->charging_enabled = true;
|
||||||
|
|
||||||
// Set default SOC limit and max charging current limit
|
// Set default SOC target and max charging current limit
|
||||||
drv->soc_limit = 100;
|
drv->soc_target = 100;
|
||||||
drv->charging_current_max_limit_ma = PM_BATTERY_CHARGING_CURRENT_MAX;
|
drv->charging_current_max_limit_ma = PM_BATTERY_CHARGING_CURRENT_MAX;
|
||||||
|
|
||||||
// Fuel gauge SoC available, set fuel_gauge initialized.
|
// 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;
|
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;
|
pm_driver_t* drv = &g_pm;
|
||||||
|
|
||||||
if (!drv->initialized) {
|
if (!drv->initialized) {
|
||||||
return PM_NOT_INITIALIZED;
|
return PM_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limit > 100) {
|
if (target > 100) {
|
||||||
return PM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (limit <= PM_SOC_LIMIT_HYSTERESIS) {
|
|
||||||
return PM_ERROR;
|
return PM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_key_t irq_key = irq_lock();
|
irq_key_t irq_key = irq_lock();
|
||||||
drv->soc_limit = limit;
|
drv->soc_target = target;
|
||||||
irq_unlock(irq_key);
|
irq_unlock(irq_key);
|
||||||
|
|
||||||
return PM_OK;
|
return PM_OK;
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#define PM_BATTERY_UNDERVOLT_RECOVERY_THR_V 3.1f
|
#define PM_BATTERY_UNDERVOLT_RECOVERY_THR_V 3.1f
|
||||||
#define PM_BATTERY_UNDERVOLT_RECOVERY_WPC_THR_V 3.2f
|
#define PM_BATTERY_UNDERVOLT_RECOVERY_WPC_THR_V 3.2f
|
||||||
#define PM_BATTERY_LOW_THRESHOLD_SOC 15
|
#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_MAX PMIC_CHARGING_LIMIT_MAX
|
||||||
#define PM_BATTERY_CHARGING_CURRENT_MIN PMIC_CHARGING_LIMIT_MIN
|
#define PM_BATTERY_CHARGING_CURRENT_MIN PMIC_CHARGING_LIMIT_MIN
|
||||||
#define PM_BATTERY_SAMPLING_BUF_SIZE 10
|
#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_tail_idx;
|
||||||
uint8_t bat_sampling_buf_head_idx;
|
uint8_t bat_sampling_buf_head_idx;
|
||||||
uint8_t soc_ceiled;
|
uint8_t soc_ceiled;
|
||||||
uint8_t soc_limit;
|
|
||||||
bool soc_limit_reached;
|
uint8_t soc_target;
|
||||||
|
bool soc_target_reached;
|
||||||
|
|
||||||
// Battery charging state
|
// Battery charging state
|
||||||
bool charging_enabled;
|
bool charging_enabled;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <sys/systick.h>
|
#include <sys/systick.h>
|
||||||
#include <trezor_rtl.h>
|
#include <trezor_rtl.h>
|
||||||
|
|
||||||
|
#include "../fuel_gauge/battery_model.h"
|
||||||
#include "../fuel_gauge/fuel_gauge.h"
|
#include "../fuel_gauge/fuel_gauge.h"
|
||||||
#include "../stwlc38/stwlc38.h"
|
#include "../stwlc38/stwlc38.h"
|
||||||
#include "power_manager_internal.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);
|
pmic_set_charging_limit(drv->charging_current_target_ma);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((drv->soc_ceiled >= drv->soc_limit) && (drv->soc_limit != 100)) {
|
if (drv->soc_target == 100) {
|
||||||
drv->soc_limit_reached = true;
|
drv->soc_target_reached = false;
|
||||||
} else if ((drv->soc_limit == 100) ||
|
} else {
|
||||||
(drv->soc_ceiled < (drv->soc_limit - PM_SOC_LIMIT_HYSTERESIS))) {
|
// Translate SoC target to charging voltage via battery model
|
||||||
drv->soc_limit_reached = false;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drv->soc_limit_reached) {
|
drv->soc_target_reached = true;
|
||||||
// Set charging current limit to 0
|
|
||||||
|
} else if (drv->soc_ceiled < drv->soc_target) {
|
||||||
|
drv->soc_target_reached = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drv->soc_target_reached) {
|
||||||
drv->charging_current_target_ma = 0;
|
drv->charging_current_target_ma = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user