summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2021-05-31 13:30:24 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-09-13 17:32:57 +0000
commitc11c2208865e7c70d7c11afcb3e38f861421dcfd (patch)
treeb984815c6d0a15f1332d2c4c50bb971db38c2957
parentb92a150243dc4ad7ff69d7bb865da79841f3e0cb (diff)
downloadchrome-ec-c11c2208865e7c70d7c11afcb3e38f861421dcfd.tar.gz
chgstv2: Add unit test for battery sustainer
This patch adds a unit test for the battery sustainer. BUG=b:188457962 BRANCH=None TEST=make run-sbs_charging_v2 Change-Id: Ica227cf4ee3f71a746150fb6a5f4e40ab8ca0720 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2987734 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3869644 Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--common/charge_state_v2.c45
-rw-r--r--test/sbs_charging_v2.c82
2 files changed, 107 insertions, 20 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 31f526f6ef..9c8c81229a 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -181,6 +181,11 @@ static void problem(enum problem_type p, int v)
problems_exist = 1;
}
+test_export_static enum ec_charge_control_mode get_chg_ctrl_mode(void)
+{
+ return chg_ctl_mode;
+}
+
static int battery_sustainer_set(int8_t lower, int8_t upper)
{
if (lower == -1 || upper == -1) {
@@ -1066,6 +1071,9 @@ static void dump_charge_state(void)
#define DUMP(FLD, FMT) ccprintf(#FLD " = " FMT "\n", curr.FLD)
#define DUMP_CHG(FLD, FMT) ccprintf("\t" #FLD " = " FMT "\n", curr.chg. FLD)
#define DUMP_BATT(FLD, FMT) ccprintf("\t" #FLD " = " FMT "\n", curr.batt. FLD)
+
+ enum ec_charge_control_mode cmode = get_chg_ctrl_mode();
+
ccprintf("state = %s\n", state_list[curr.state]);
DUMP(ac, "%d");
DUMP(batt_is_charging, "%d");
@@ -1099,8 +1107,8 @@ static void dump_charge_state(void)
DUMP(input_voltage, "%dmV");
#endif
ccprintf("chg_ctl_mode = %s (%d)\n",
- chg_ctl_mode < CHARGE_CONTROL_COUNT
- ? mode_text[chg_ctl_mode] : "UNDEF", chg_ctl_mode);
+ cmode < CHARGE_CONTROL_COUNT ? mode_text[cmode] : "UNDEF",
+ cmode);
ccprintf("manual_voltage = %d\n", manual_voltage);
ccprintf("manual_current = %d\n", manual_current);
ccprintf("user_current_limit = %dmA\n", user_current_limit);
@@ -1118,6 +1126,7 @@ static void dump_charge_state(void)
static void show_charging_progress(void)
{
int rv = 0, minutes, to_full;
+ int dsoc;
#ifdef CONFIG_BATTERY_SMART
/*
@@ -1151,19 +1160,17 @@ static void show_charging_progress(void)
}
#endif
+ dsoc = charge_get_display_charge();
if (rv)
CPRINTS("Battery %d%% (Display %d.%d %%) / ??h:?? %s%s",
curr.batt.state_of_charge,
- curr.batt.display_charge / 10,
- curr.batt.display_charge % 10,
+ dsoc / 10, dsoc % 10,
to_full ? "to full" : "to empty",
is_full ? ", not accepting current" : "");
else
CPRINTS("Battery %d%% (Display %d.%d %%) / %dh:%d %s%s",
curr.batt.state_of_charge,
- curr.batt.display_charge / 10,
- curr.batt.display_charge % 10,
- minutes / 60, minutes % 60,
+ dsoc / 10, dsoc % 10, minutes / 60, minutes % 60,
to_full ? "to full" : "to empty",
is_full ? ", not accepting current" : "");
@@ -1516,7 +1523,7 @@ const struct batt_params *charger_current_battery_params(void)
static void sustain_battery_soc(void)
{
- enum ec_charge_control_mode mode = chg_ctl_mode;
+ enum ec_charge_control_mode mode = get_chg_ctrl_mode();
int soc;
int rv;
@@ -1527,7 +1534,7 @@ static void sustain_battery_soc(void)
soc = charge_get_display_charge() / 10;
- switch (chg_ctl_mode) {
+ switch (mode) {
case CHARGE_CONTROL_NORMAL:
/* Going up */
if (sustain_soc.upper < soc)
@@ -1548,7 +1555,7 @@ static void sustain_battery_soc(void)
return;
}
- if (mode == chg_ctl_mode)
+ if (mode == get_chg_ctrl_mode())
return;
rv = set_chg_ctrl_mode(mode);
@@ -1795,7 +1802,7 @@ void charger_task(void *u)
/* Okay, we're on AC and we should have a battery. */
/* Used for factory tests. */
- if (chg_ctl_mode != CHARGE_CONTROL_NORMAL) {
+ if (get_chg_ctrl_mode() != CHARGE_CONTROL_NORMAL) {
set_charge_state(ST_IDLE);
goto wait_for_it;
}
@@ -1887,7 +1894,7 @@ void charger_task(void *u)
wait_for_it:
#ifdef CONFIG_CHARGER_PROFILE_OVERRIDE
- if (chg_ctl_mode == CHARGE_CONTROL_NORMAL) {
+ if (get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL) {
sleep_usec = charger_profile_override(&curr);
if (sleep_usec < 0)
problem(PR_CUSTOM, sleep_usec);
@@ -1935,11 +1942,11 @@ wait_for_it:
#endif
(is_full != prev_full) ||
(curr.state != prev_state) ||
- (curr.batt.display_charge != prev_disp_charge)) {
+ (charge_get_display_charge() != prev_disp_charge)) {
sustain_battery_soc();
show_charging_progress();
prev_charge = curr.batt.state_of_charge;
- prev_disp_charge = curr.batt.display_charge;
+ prev_disp_charge = charge_get_display_charge();
#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER
prev_charge_base = charge_base;
#endif
@@ -2221,7 +2228,7 @@ uint32_t charge_get_flags(void)
{
uint32_t flags = 0;
- if (chg_ctl_mode != CHARGE_CONTROL_NORMAL)
+ if (get_chg_ctrl_mode() != CHARGE_CONTROL_NORMAL)
flags |= CHARGE_FLAG_FORCE_IDLE;
if (curr.ac)
flags |= CHARGE_FLAG_EXTERNAL_POWER;
@@ -2242,7 +2249,7 @@ int charge_get_percent(void)
return is_full ? 100 : curr.batt.state_of_charge;
}
-int charge_get_display_charge(void)
+test_mockable int charge_get_display_charge(void)
{
return curr.batt.display_charge;
}
@@ -2349,7 +2356,7 @@ static int charge_command_charge_control(struct host_cmd_handler_args *args)
if (args->version >= 2) {
if (p->cmd == EC_CHARGE_CONTROL_CMD_SET) {
- if (chg_ctl_mode == CHARGE_CONTROL_NORMAL) {
+ if (get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL) {
rv = battery_sustainer_set(
p->sustain_soc.lower,
p->sustain_soc.upper);
@@ -2361,7 +2368,7 @@ static int charge_command_charge_control(struct host_cmd_handler_args *args)
battery_sustainer_disable();
}
} else if (p->cmd == EC_CHARGE_CONTROL_CMD_GET) {
- r->mode = chg_ctl_mode;
+ r->mode = get_chg_ctrl_mode();
r->sustain_soc.lower = sustain_soc.lower;
r->sustain_soc.upper = sustain_soc.upper;
args->response_size = sizeof(*r);
@@ -2671,7 +2678,7 @@ int charge_get_charge_state_debug(int param, uint32_t *value)
{
switch (param) {
case CS_PARAM_DEBUG_CTL_MODE:
- *value = chg_ctl_mode;
+ *value = get_chg_ctrl_mode();
break;
case CS_PARAM_DEBUG_MANUAL_CURRENT:
*value = manual_current;
diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c
index a37648ef61..03676ec942 100644
--- a/test/sbs_charging_v2.c
+++ b/test/sbs_charging_v2.c
@@ -19,11 +19,14 @@
#define WAIT_CHARGER_TASK 600
#define BATTERY_DETACH_DELAY 35000
+enum ec_charge_control_mode get_chg_ctrl_mode(void);
+
static int mock_chipset_state = CHIPSET_STATE_ON;
static int is_shutdown;
static int is_force_discharge;
static int is_hibernated;
static int override_voltage, override_current, override_usec;
+static int display_soc;
/* The simulation doesn't really hibernate, so we must reset this ourselves */
extern timestamp_t shutdown_warning_time;
@@ -109,10 +112,15 @@ static int charge_control(enum ec_charge_control_mode mode)
{
struct ec_params_charge_control params;
params.mode = mode;
- return test_send_host_command(EC_CMD_CHARGE_CONTROL, 1, &params,
+ return test_send_host_command(EC_CMD_CHARGE_CONTROL, 2, &params,
sizeof(params), NULL, 0);
}
+__override int charge_get_display_charge(void)
+{
+ return display_soc;
+}
+
/* Setup init condition */
static void test_setup(int on_ac)
{
@@ -676,7 +684,78 @@ static int test_low_battery_hostevents(void)
return EC_SUCCESS;
}
+static int test_battery_sustainer(void)
+{
+ struct ec_params_charge_control p;
+ struct ec_response_charge_control r;
+ int rv;
+
+ test_setup(1);
+
+ /* Enable sustainer */
+ p.cmd = EC_CHARGE_CONTROL_CMD_SET;
+ p.mode = CHARGE_CONTROL_NORMAL;
+ p.sustain_soc.lower = 79;
+ 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);
+
+ p.cmd = EC_CHARGE_CONTROL_CMD_GET;
+ rv = test_send_host_command(EC_CMD_CHARGE_CONTROL, 2,
+ &p, sizeof(p), &r, sizeof(r));
+ TEST_ASSERT(rv == EC_RES_SUCCESS);
+ TEST_ASSERT(r.sustain_soc.lower == 79);
+ TEST_ASSERT(r.sustain_soc.upper == 80);
+
+ /* 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_DISCHARGE);
+ /* 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_DISCHARGE);
+
+ /* lower < SoC < upper */
+ display_soc = 799;
+ 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)
{
@@ -687,6 +766,7 @@ void run_test(void)
RUN_TEST(test_hc_charge_state);
RUN_TEST(test_hc_current_limit);
RUN_TEST(test_low_battery_hostevents);
+ RUN_TEST(test_battery_sustainer);
test_print_result();
}