summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2021-07-23 07:37:06 -0700
committerCommit Bot <commit-bot@chromium.org>2021-08-21 00:42:40 +0000
commite401ae9cff33a8ddf5447aea42dc5d2bead9b005 (patch)
treea2611ba729130589b63cd46a2e83745c1b0c2dae
parent7abbab0eef31f7c12725e4ae77a96418c2ea807b (diff)
downloadchrome-ec-e401ae9cff33a8ddf5447aea42dc5d2bead9b005.tar.gz
chgstv2/sustainer: Stop AC current when discharging
Currently, the battery sustainer discharges the battery using CHARGE_CONTROL_IDLE, which uses the AC current and stops the current from the battery. With this change, when lower < upper, the sustainer discharges using DISCHARGE. When lower == upper, the sustainer discharges using IDLE. BUG=b:188457962 BRANCH=None TEST=run-sbs_charging_v2 Change-Id: I4af31eff488bc9cfa627f84994b685488c3c9061 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3049290 Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Reviewed-by: Derek Basehore <dbasehore@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3105743
-rw-r--r--common/charge_state_v2.c18
-rw-r--r--test/sbs_charging_v2.c68
2 files changed, 79 insertions, 7 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 104539e780..b8ad1fc425 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -1531,22 +1531,28 @@ static void sustain_battery_soc(void)
soc = charge_get_display_charge() / 10;
+ /*
+ * When lower < upper, the sustainer discharges using DISCHARGE. When
+ * lower == upper, the sustainer discharges using IDLE. The following
+ * switch statement handle both cases but in reality either DISCHARGE
+ * or IDLE is used but not both.
+ */
switch (mode) {
case CHARGE_CONTROL_NORMAL:
/* Going up */
if (sustain_soc.upper < soc)
- mode = CHARGE_CONTROL_DISCHARGE;
+ mode = sustain_soc.upper == sustain_soc.lower ?
+ CHARGE_CONTROL_IDLE : CHARGE_CONTROL_DISCHARGE;
break;
case CHARGE_CONTROL_IDLE:
- /* discharging naturally */
+ /* Discharging naturally */
if (soc < sustain_soc.lower)
- /* TODO: Charge slowly */
mode = CHARGE_CONTROL_NORMAL;
break;
case CHARGE_CONTROL_DISCHARGE:
- /* discharging rapidly (discharge_on_ac) */
- if (soc < sustain_soc.upper)
- mode = CHARGE_CONTROL_IDLE;
+ /* Discharging actively. */
+ if (soc < sustain_soc.lower)
+ mode = CHARGE_CONTROL_NORMAL;
break;
default:
return;
diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c
index 6b7bf04ca4..addd438d7e 100644
--- a/test/sbs_charging_v2.c
+++ b/test/sbs_charging_v2.c
@@ -748,7 +748,7 @@ static int test_battery_sustainer(void)
ccprintf("Test lower < SoC < upper.\n");
display_soc = 799;
wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_IDLE);
+ TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_DISCHARGE);
ccprintf("Pass.\n");
ccprintf("Test SoC < lower < upper.\n");
@@ -805,6 +805,71 @@ static int test_battery_sustainer(void)
return EC_SUCCESS;
}
+static int test_battery_sustainer_discharge_idle(void)
+{
+ struct ec_params_charge_control p;
+ int rv;
+
+ test_setup(1);
+
+ /* Enable sustainer */
+ p.cmd = EC_CHARGE_CONTROL_CMD_SET;
+ p.mode = CHARGE_CONTROL_NORMAL;
+ p.sustain_soc.lower = 80;
+ p.sustain_soc.upper = 80;
+ rv = test_send_host_command(EC_CMD_CHARGE_CONTROL, 2,
+ &p, sizeof(p), NULL, 0);
+ TEST_ASSERT(rv == EC_RES_SUCCESS);
+
+ /* Check mode transition as the SoC changes. */
+
+ /* SoC < lower (= upper) */
+ display_soc = 780;
+ wait_charging_state();
+ TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL);
+
+ /* (lower =) upper < SoC */
+ display_soc = 810;
+ wait_charging_state();
+ TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_IDLE);
+
+ /* Unplug AC. Sustainer gets deactivated. */
+ gpio_set_level(GPIO_AC_PRESENT, 0);
+ wait_charging_state();
+ TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL);
+
+ /* Replug AC. Sustainer gets re-activated. */
+ gpio_set_level(GPIO_AC_PRESENT, 1);
+ wait_charging_state();
+ TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_IDLE);
+
+ /* lower = SoC = upper */
+ display_soc = 800;
+ wait_charging_state();
+ TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_IDLE);
+
+ /* SoC < lower (= upper) */
+ display_soc = 789;
+ wait_charging_state();
+ TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL);
+
+ /* Disable sustainer */
+ p.cmd = EC_CHARGE_CONTROL_CMD_SET;
+ p.mode = CHARGE_CONTROL_NORMAL;
+ p.sustain_soc.lower = -1;
+ p.sustain_soc.upper = -1;
+ rv = test_send_host_command(EC_CMD_CHARGE_CONTROL, 2,
+ &p, sizeof(p), NULL, 0);
+ TEST_ASSERT(rv == EC_RES_SUCCESS);
+
+ /* This time, mode will stay in NORMAL even when upper < SoC. */
+ display_soc = 810;
+ wait_charging_state();
+ TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL);
+
+ return EC_SUCCESS;
+}
+
void run_test(void)
{
RUN_TEST(test_charge_state);
@@ -815,6 +880,7 @@ void run_test(void)
RUN_TEST(test_hc_current_limit);
RUN_TEST(test_low_battery_hostevents);
RUN_TEST(test_battery_sustainer);
+ RUN_TEST(test_battery_sustainer_discharge_idle);
test_print_result();
}