summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTang Qijun <qijun.tang@ecs.corp-partner.google.com>2021-09-09 01:22:28 -0400
committerCommit Bot <commit-bot@chromium.org>2021-10-07 15:55:01 +0000
commit14891fcf8ac0ac2e1c72f5d22321c6b077ab2e53 (patch)
tree3a9987bf6d407e70f8918e47dfe99bc50b02266f
parent234e646fd807dc60f9af78c80db3edf8d5f93cee (diff)
downloadchrome-ec-14891fcf8ac0ac2e1c72f5d22321c6b077ab2e53.tar.gz
chgstv2: Implement battery protection for low voltage
Deep charge inspection is a battery protection mechanism: If battery voltage is lower than 6V, deep charge for more than 30 minutes The battery voltage is still lower than 6V, the system will stop charging BRANCH=trogdor BUG=b:198226241 TEST=run-sbs_charging_v2 Signed-off-by: Tang Qijun <qijun.tang@ecs.corp-partner.google.com> Change-Id: I89adf7809992b9e71b232ad1129af1407acf05a2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3151037 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--common/charge_state_v2.c40
-rw-r--r--include/charge_state.h5
-rw-r--r--include/config.h15
-rw-r--r--test/sbs_charging_v2.c30
-rw-r--r--test/test_config.h3
5 files changed, 93 insertions, 0 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 110d63c7bf..59f38edee8 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -1857,6 +1857,39 @@ static void wakeup_battery(int *need_static)
}
}
+__test_only enum charge_state_v2 charge_get_state_v2(void)
+{
+ return curr.state;
+}
+
+static void deep_charge_battery(int *need_static)
+{
+ if (curr.state == ST_IDLE) {
+ /* Deep charge time out , do nothing */
+ curr.requested_voltage = 0;
+ curr.requested_current = 0;
+ } else if (curr.state == ST_PRECHARGE
+ && (get_time().val > precharge_start_time.val +
+ CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT)) {
+ /* We've tried long enough, give up */
+ CPRINTS("Precharge for low voltage timed out");
+ set_charge_state(ST_IDLE);
+ curr.requested_voltage = 0;
+ curr.requested_current = 0;
+ } else {
+ /* See if we can wake it up */
+ if (curr.state != ST_PRECHARGE) {
+ CPRINTS("Start precharge for low voltage");
+ precharge_start_time = get_time();
+ *need_static = 1;
+ }
+ set_charge_state(ST_PRECHARGE);
+ curr.requested_voltage = batt_info->voltage_max;
+ curr.requested_current = batt_info->precharge_current;
+ }
+}
+
+
static void revive_battery(int *need_static)
{
if (IS_ENABLED(CONFIG_BATTERY_REQUESTS_NIL_WHEN_DEAD)
@@ -2108,6 +2141,13 @@ void charger_task(void *u)
goto wait_for_it;
}
+ if (IS_ENABLED(CONFIG_BATTERY_LOW_VOLTAGE_PROTECTION)
+ && !(curr.batt.flags & BATT_FLAG_BAD_VOLTAGE)
+ && (curr.batt.voltage <= batt_info->voltage_min)) {
+ deep_charge_battery(&need_static);
+ goto wait_for_it;
+ }
+
/* The battery is responding. Yay. Try to use it. */
/*
diff --git a/include/charge_state.h b/include/charge_state.h
index 0ab7ecd686..9349c3ea4c 100644
--- a/include/charge_state.h
+++ b/include/charge_state.h
@@ -82,6 +82,11 @@ enum charge_state {
enum charge_state charge_get_state(void);
/**
+ * Return current charge v2 state.
+ */
+__test_only enum charge_state_v2 charge_get_state_v2(void);
+
+/**
* Return non-zero if battery is so low we want to keep AP off.
*/
int charge_keep_power_off(void);
diff --git a/include/config.h b/include/config.h
index 71f649bbc9..9ce47f8287 100644
--- a/include/config.h
+++ b/include/config.h
@@ -610,6 +610,21 @@
#undef CONFIG_BATTERY_REVIVE_DISCONNECT
/*
+ * Low voltage protection for a battery (a.k.a. deep charge inspection):
+ * If battery voltage is lower than voltage_min, deep charge for more
+ * than precharge time The battery voltage is still lower than voltage_min,
+ * the system will stop charging
+ */
+#undef CONFIG_BATTERY_LOW_VOLTAGE_PROTECTION
+
+/*
+ * If battery voltage is lower than voltage_min, precharge voltage & current
+ * are supplied and charging will be disabled after
+ * CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT seconds.
+ */
+#define CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT (30*60*SECOND)
+
+/*
* Specify the battery percentage at which the host is told it is full.
* If this value is not specified the default is 97% set in battery.h.
*/
diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c
index bdca592d6c..2f9ddee57c 100644
--- a/test/sbs_charging_v2.c
+++ b/test/sbs_charging_v2.c
@@ -365,6 +365,35 @@ static int test_low_battery(void)
return EC_SUCCESS;
}
+static int test_deep_charge_battery(void)
+{
+ enum charge_state_v2 state_v2;
+ const struct battery_info *bat_info = battery_get_info();
+
+ test_setup(1);
+
+ /* battery pack voltage bellow voltage_min */
+ sb_write(SB_VOLTAGE, (bat_info->voltage_min - 200));
+ wait_charging_state();
+ state_v2 = charge_get_state_v2();
+ TEST_ASSERT(state_v2 == ST_PRECHARGE);
+
+ /*
+ * Battery voltage keep bellow voltage_min,
+ * precharge over time CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT
+ */
+ usleep(CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT);
+ state_v2 = charge_get_state_v2();
+ TEST_ASSERT(state_v2 == ST_IDLE);
+
+ /* recovery from a low voltage. */
+ sb_write(SB_VOLTAGE, (bat_info->voltage_normal));
+ wait_charging_state();
+ state_v2 = charge_get_state_v2();
+ TEST_ASSERT(state_v2 == ST_CHARGE);
+
+ return EC_SUCCESS;
+}
static int test_high_temp_battery(void)
{
test_setup(1);
@@ -935,6 +964,7 @@ void run_test(int argc, char **argv)
RUN_TEST(test_low_battery_hostevents);
RUN_TEST(test_battery_sustainer);
RUN_TEST(test_battery_sustainer_discharge_idle);
+ RUN_TEST(test_deep_charge_battery);
test_print_result();
}
diff --git a/test/test_config.h b/test/test_config.h
index 5afc5d1282..a60393dc42 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -282,6 +282,9 @@ int board_discharge_on_ac(int enabled);
#define I2C_PORT_MASTER 0
#define I2C_PORT_BATTERY 0
#define I2C_PORT_CHARGER 0
+#define CONFIG_BATTERY_LOW_VOLTAGE_PROTECTION
+#undef CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT
+#define CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT (2*SECOND)
#endif
#ifdef TEST_THERMAL