summaryrefslogtreecommitdiff
path: root/test/sbs_charging_v2.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /test/sbs_charging_v2.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14469.8.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'test/sbs_charging_v2.c')
-rw-r--r--test/sbs_charging_v2.c940
1 files changed, 0 insertions, 940 deletions
diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c
deleted file mode 100644
index bdca592d6c..0000000000
--- a/test/sbs_charging_v2.c
+++ /dev/null
@@ -1,940 +0,0 @@
-/* Copyright 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Test charge_state_v2 behavior
- */
-
-#include "battery_smart.h"
-#include "charge_state.h"
-#include "chipset.h"
-#include "common.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "math_util.h"
-#include "power.h"
-#include "task.h"
-#include "test_util.h"
-#include "util.h"
-
-#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;
-static int is_full;
-
-/* The simulation doesn't really hibernate, so we must reset this ourselves */
-extern timestamp_t shutdown_target_time;
-
-static void reset_mocks(void)
-{
- mock_chipset_state = CHIPSET_STATE_ON;
- is_shutdown = is_force_discharge = is_hibernated = 0;
- override_voltage = override_current = override_usec = 0;
- shutdown_target_time.val = 0ULL;
- is_full = 0;
-}
-
-int board_cut_off_battery(void)
-{
- return EC_SUCCESS;
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- is_shutdown = 1;
- mock_chipset_state = CHIPSET_STATE_HARD_OFF;
-}
-
-int chipset_in_state(int state_mask)
-{
- return state_mask & mock_chipset_state;
-}
-
-int chipset_in_or_transitioning_to_state(int state_mask)
-{
- return state_mask & mock_chipset_state;
-}
-
-enum power_state power_get_state(void)
-{
- if (is_shutdown)
- return POWER_S5;
- else if (is_hibernated)
- return POWER_G3;
- else
- return POWER_S0;
-}
-
-int board_discharge_on_ac(int enabled)
-{
- is_force_discharge = enabled;
- return EC_SUCCESS;
-}
-
-void system_hibernate(int sec, int usec)
-{
- is_hibernated = 1;
-}
-
-int charger_profile_override(struct charge_state_data *curr)
-{
- if (override_voltage)
- curr->requested_voltage = override_voltage;
- if (override_current)
- curr->requested_current = override_current;
-
- if (override_usec)
- return override_usec;
-
- /* Don't let it sleep a whole minute when the AP is off */
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
- return CHARGE_POLL_PERIOD_LONG;
-
- return 0;
-}
-
-static uint32_t meh;
-enum ec_status charger_profile_override_get_param(uint32_t param,
- uint32_t *value)
-{
- if (param == CS_PARAM_CUSTOM_PROFILE_MIN) {
- *value = meh;
- return EC_RES_SUCCESS;
- }
- return EC_RES_INVALID_PARAM;
-}
-enum ec_status charger_profile_override_set_param(uint32_t param,
- uint32_t value)
-{
- if (param == CS_PARAM_CUSTOM_PROFILE_MIN) {
- meh = value;
- return EC_RES_SUCCESS;
- }
- return EC_RES_INVALID_PARAM;
-}
-
-static int wait_charging_state(void)
-{
- enum charge_state state;
- task_wake(TASK_ID_CHARGER);
- msleep(WAIT_CHARGER_TASK);
- state = charge_get_state();
- ccprintf("[CHARGING TEST] state = %d\n", state);
- return state;
-}
-
-static int charge_control(enum ec_charge_control_mode mode)
-{
- struct ec_params_charge_control p;
-
- p.cmd = EC_CHARGE_CONTROL_CMD_SET;
- p.mode = mode;
- p.sustain_soc.lower = -1;
- p.sustain_soc.upper = -1;
- return test_send_host_command(EC_CMD_CHARGE_CONTROL, 2, &p, sizeof(p),
- NULL, 0);
-}
-
-__override int charge_get_display_charge(void)
-{
- return display_soc;
-}
-
-__override int calc_is_full(void)
-{
- return is_full;
-}
-
-/* Setup init condition */
-static void test_setup(int on_ac)
-{
- const struct battery_info *bat_info = battery_get_info();
-
- reset_mocks();
-
- /* 50% of charge */
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, 50);
- sb_write(SB_ABSOLUTE_STATE_OF_CHARGE, 50);
- /* full charge capacity in mAh */
- sb_write(SB_FULL_CHARGE_CAPACITY, 0xf000);
- /* 25 degree Celsius */
- sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(25));
- /* battery pack voltage */
- sb_write(SB_VOLTAGE, bat_info->voltage_normal);
- /* desired charging voltage/current */
- sb_write(SB_CHARGING_VOLTAGE, bat_info->voltage_max);
- sb_write(SB_CHARGING_CURRENT, 4000);
-
- /* battery pack current is positive when charging */
- if (on_ac) {
- sb_write(SB_CURRENT, 1000);
- gpio_set_level(GPIO_AC_PRESENT, 1);
- } else {
- sb_write(SB_CURRENT, -100);
- gpio_set_level(GPIO_AC_PRESENT, 0);
- }
-
- /* Reset the charger state to initial state */
- charge_control(CHARGE_CONTROL_NORMAL);
-
- /* Let things stabilize */
- wait_charging_state();
-}
-
-/* Host Event helpers */
-static int ev_is_set(int event)
-{
- return host_get_events() & EC_HOST_EVENT_MASK(event);
-}
-static int ev_is_clear(int event)
-{
- return !ev_is_set(event);
-}
-static void ev_clear(int event)
-{
- host_clear_events(EC_HOST_EVENT_MASK(event));
-}
-
-static int test_charge_state(void)
-{
- enum charge_state state;
- uint32_t flags;
-
- /* On AC */
- test_setup(1);
-
- ccprintf("[CHARGING TEST] AC on\n");
-
- /* Detach battery, charging error */
- ccprintf("[CHARGING TEST] Detach battery\n");
- TEST_ASSERT(test_detach_i2c(I2C_PORT_BATTERY, BATTERY_ADDR_FLAGS) ==
- EC_SUCCESS);
- msleep(BATTERY_DETACH_DELAY);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_ERROR);
-
- /* Attach battery again, charging */
- ccprintf("[CHARGING TEST] Attach battery\n");
- test_attach_i2c(I2C_PORT_BATTERY, BATTERY_ADDR_FLAGS);
- /* And changing full capacity should trigger a host event */
- ev_clear(EC_HOST_EVENT_BATTERY);
- sb_write(SB_FULL_CHARGE_CAPACITY, 0xeff0);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY));
-
- /* Unplug AC, discharging at 1000mAh */
- ccprintf("[CHARGING TEST] AC off\n");
- gpio_set_level(GPIO_AC_PRESENT, 0);
- sb_write(SB_CURRENT, -1000);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- flags = charge_get_flags();
- TEST_ASSERT(!(flags & CHARGE_FLAG_EXTERNAL_POWER));
- TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
-
- /* Discharging waaaay overtemp is ignored */
- ccprintf("[CHARGING TEST] AC off, batt temp = 0xffff\n");
- gpio_set_level(GPIO_AC_PRESENT, 0);
- sb_write(SB_CURRENT, -1000);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- sb_write(SB_TEMPERATURE, 0xffff);
- state = wait_charging_state();
- TEST_ASSERT(!is_shutdown);
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(40));
-
- /* Discharging overtemp */
- ccprintf("[CHARGING TEST] AC off, batt temp = 90 C\n");
- gpio_set_level(GPIO_AC_PRESENT, 0);
- sb_write(SB_CURRENT, -1000);
-
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(90));
- state = wait_charging_state();
- sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
- TEST_ASSERT(is_shutdown);
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(40));
-
- /* Force idle */
- ccprintf("[CHARGING TEST] AC on, force idle\n");
- gpio_set_level(GPIO_AC_PRESENT, 1);
- sb_write(SB_CURRENT, 1000);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
- charge_control(CHARGE_CONTROL_IDLE);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_IDLE);
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(flags & CHARGE_FLAG_FORCE_IDLE);
- charge_control(CHARGE_CONTROL_NORMAL);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
-
- /* Force discharge */
- ccprintf("[CHARGING TEST] AC on, force discharge\n");
- gpio_set_level(GPIO_AC_PRESENT, 1);
- sb_write(SB_CURRENT, 1000);
- charge_control(CHARGE_CONTROL_DISCHARGE);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_IDLE);
- TEST_ASSERT(is_force_discharge);
- charge_control(CHARGE_CONTROL_NORMAL);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
- TEST_ASSERT(!is_force_discharge);
-
- return EC_SUCCESS;
-}
-
-static int test_low_battery(void)
-{
- test_setup(1);
-
- ccprintf("[CHARGING TEST] Low battery with AC and positive current\n");
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
- sb_write(SB_CURRENT, 1000);
- wait_charging_state();
- mock_chipset_state = CHIPSET_STATE_SOFT_OFF;
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
- TEST_ASSERT(!is_hibernated);
-
- ccprintf("[CHARGING TEST] Low battery with AC and negative current\n");
- sb_write(SB_CURRENT, -1000);
- wait_charging_state();
- sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
- TEST_ASSERT(is_hibernated);
-
- ccprintf("[CHARGING TEST] Low battery shutdown S0->S5\n");
- mock_chipset_state = CHIPSET_STATE_ON;
- hook_notify(HOOK_CHIPSET_PRE_INIT);
- hook_notify(HOOK_CHIPSET_STARTUP);
- gpio_set_level(GPIO_AC_PRESENT, 0);
- is_hibernated = 0;
- sb_write(SB_CURRENT, -1000);
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
- wait_charging_state();
- mock_chipset_state = CHIPSET_STATE_SOFT_OFF;
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
- wait_charging_state();
- /* after a while, the EC should hibernate */
- sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
- TEST_ASSERT(is_hibernated);
-
- ccprintf("[CHARGING TEST] Low battery shutdown S5\n");
- is_hibernated = 0;
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, 10);
- wait_charging_state();
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
- wait_charging_state();
- /* after a while, the EC should hibernate */
- sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
- TEST_ASSERT(is_hibernated);
-
- ccprintf("[CHARGING TEST] Low battery AP shutdown\n");
- is_shutdown = 0;
- mock_chipset_state = CHIPSET_STATE_ON;
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, 10);
- gpio_set_level(GPIO_AC_PRESENT, 1);
- sb_write(SB_CURRENT, 1000);
- wait_charging_state();
- gpio_set_level(GPIO_AC_PRESENT, 0);
- sb_write(SB_CURRENT, -1000);
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
- wait_charging_state();
- usleep(32 * SECOND);
- wait_charging_state();
- TEST_ASSERT(is_shutdown);
-
- return EC_SUCCESS;
-}
-
-static int test_high_temp_battery(void)
-{
- test_setup(1);
-
- ccprintf("[CHARGING TEST] High battery temperature shutdown\n");
- ev_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN);
- sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(90));
- wait_charging_state();
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_SHUTDOWN));
- TEST_ASSERT(!is_shutdown);
- sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
- TEST_ASSERT(is_shutdown);
-
- ccprintf("[CHARGING TEST] High battery temp S0->S5 hibernate\n");
- mock_chipset_state = CHIPSET_STATE_SOFT_OFF;
- wait_charging_state();
- TEST_ASSERT(is_hibernated);
-
- return EC_SUCCESS;
-}
-
-static int test_cold_battery_with_ac(void)
-{
- test_setup(1);
-
- ccprintf("[CHARGING TEST] Cold battery no shutdown with AC\n");
- ev_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN);
- sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(-90));
- wait_charging_state();
- sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
- TEST_ASSERT(!is_shutdown);
-
- return EC_SUCCESS;
-}
-
-static int test_cold_battery_no_ac(void)
-{
- test_setup(0);
-
- ccprintf("[CHARGING TEST] Cold battery shutdown when discharging\n");
- ev_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN);
- sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(-90));
- wait_charging_state();
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_SHUTDOWN));
- TEST_ASSERT(!is_shutdown);
- sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
- TEST_ASSERT(is_shutdown);
-
- return EC_SUCCESS;
-}
-
-static int test_external_funcs(void)
-{
- int rv, temp;
- uint32_t flags;
- int state;
-
- /* Connect the AC */
- test_setup(1);
-
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
-
- /* Invalid or do-nothing commands first */
- UART_INJECT("chg\n");
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
-
- UART_INJECT("chg blahblah\n");
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
-
- UART_INJECT("chg idle\n");
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
-
- UART_INJECT("chg idle blargh\n");
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
-
- /* Now let's force idle on and off */
- UART_INJECT("chg idle on\n");
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_IDLE);
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(flags & CHARGE_FLAG_FORCE_IDLE);
-
- UART_INJECT("chg idle off\n");
- wait_charging_state();
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
- flags = charge_get_flags();
- TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
- TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
-
- /* and the rest */
- TEST_ASSERT(charge_get_state() == PWR_STATE_CHARGE);
- TEST_ASSERT(!charge_want_shutdown());
- TEST_ASSERT(charge_get_percent() == 50);
- temp = 0;
- rv = charge_get_battery_temp(0, &temp);
- TEST_ASSERT(rv == EC_SUCCESS);
- TEST_ASSERT(K_TO_C(temp) == 25);
-
- return EC_SUCCESS;
-}
-
-#define CHG_OPT1 0x2000
-#define CHG_OPT2 0x4000
-static int test_hc_charge_state(void)
-{
- enum charge_state state;
- int i, rv, tmp;
- struct ec_params_charge_state params;
- struct ec_response_charge_state resp;
-
- /* Let's connect the AC again. */
- test_setup(1);
-
- /* Initialize the charger options with some nonzero value */
- TEST_ASSERT(charger_set_option(CHG_OPT1) == EC_SUCCESS);
-
- /* Get the state */
- memset(&resp, 0, sizeof(resp));
- params.cmd = CHARGE_STATE_CMD_GET_STATE;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- TEST_ASSERT(resp.get_state.ac);
- TEST_ASSERT(resp.get_state.chg_voltage);
- TEST_ASSERT(resp.get_state.chg_current);
- TEST_ASSERT(resp.get_state.chg_input_current);
- TEST_ASSERT(resp.get_state.batt_state_of_charge);
-
- /* Check all the params */
- for (i = 0; i < CS_NUM_BASE_PARAMS; i++) {
-
- /* Read it */
- memset(&resp, 0, sizeof(resp));
- params.cmd = CHARGE_STATE_CMD_GET_PARAM;
- params.get_param.param = i;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- if (i != CS_PARAM_LIMIT_POWER)
- TEST_ASSERT(resp.get_param.value);
- else
- TEST_ASSERT(!resp.get_param.value);
-
- /* Bump it up a bit */
- tmp = resp.get_param.value;
- switch (i) {
- case CS_PARAM_CHG_VOLTAGE:
- case CS_PARAM_CHG_CURRENT:
- case CS_PARAM_CHG_INPUT_CURRENT:
- tmp -= 128; /* Should be valid delta */
- break;
- case CS_PARAM_CHG_STATUS:
- case CS_PARAM_LIMIT_POWER:
- /* These ones can't be set */
- break;
- case CS_PARAM_CHG_OPTION:
- tmp = CHG_OPT2;
- break;
- }
- params.cmd = CHARGE_STATE_CMD_SET_PARAM;
- params.set_param.param = i;
- params.set_param.value = tmp;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- if (i == CS_PARAM_CHG_STATUS || i == CS_PARAM_LIMIT_POWER)
- TEST_ASSERT(rv == EC_RES_ACCESS_DENIED);
- else
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- /* Allow the change to take effect */
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_CHARGE);
-
- /* Read it back again*/
- memset(&resp, 0, sizeof(resp));
- params.cmd = CHARGE_STATE_CMD_GET_PARAM;
- params.get_param.param = i;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- TEST_ASSERT(resp.get_param.value == tmp);
- }
-
- /* And a custom profile param */
- meh = 0xdeadbeef;
- memset(&resp, 0, sizeof(resp));
- params.cmd = CHARGE_STATE_CMD_GET_PARAM;
- params.get_param.param = CS_PARAM_CUSTOM_PROFILE_MIN;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- TEST_ASSERT(resp.get_param.value == meh);
- params.cmd = CHARGE_STATE_CMD_SET_PARAM;
- params.set_param.param = CS_PARAM_CUSTOM_PROFILE_MIN;
- params.set_param.value = 0xc0def00d;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- /* Allow the change to take effect */
- state = wait_charging_state();
- TEST_ASSERT(meh == params.set_param.value);
-
- /* param out of range */
- params.cmd = CHARGE_STATE_CMD_GET_PARAM;
- params.get_param.param = CS_NUM_BASE_PARAMS;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- TEST_ASSERT(rv == EC_RES_INVALID_PARAM);
- params.cmd = CHARGE_STATE_CMD_SET_PARAM;
- params.set_param.param = CS_NUM_BASE_PARAMS;
- params.set_param.value = 0x1000; /* random value */
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- TEST_ASSERT(rv == EC_RES_INVALID_PARAM);
-
- /* command out of range */
- params.cmd = CHARGE_STATE_NUM_CMDS;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &params, sizeof(params),
- &resp, sizeof(resp));
- TEST_ASSERT(rv == EC_RES_INVALID_PARAM);
-
- /*
- * We've screwed with the charger settings, so let the state machine
- * reset itself before we stop.
- */
- test_setup(0);
- test_setup(1);
-
- return EC_SUCCESS;
-}
-
-static int test_hc_current_limit(void)
-{
- int rv, norm_current, lower_current;
- struct ec_params_charge_state cs_params;
- struct ec_response_charge_state cs_resp;
- struct ec_params_current_limit cl_params;
-
- /* On AC */
- test_setup(1);
-
- /* See what current the charger is delivering */
- cs_params.cmd = CHARGE_STATE_CMD_GET_STATE;
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &cs_params, sizeof(cs_params),
- &cs_resp, sizeof(cs_resp));
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- norm_current = cs_resp.get_state.chg_current;
-
- /* Lower it a bit */
- lower_current = norm_current - 256;
- cl_params.limit = lower_current;
- rv = test_send_host_command(EC_CMD_CHARGE_CURRENT_LIMIT, 0,
- &cl_params, sizeof(cl_params),
- 0, 0);
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- wait_charging_state();
-
- /* See that it's changed */
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &cs_params, sizeof(cs_params),
- &cs_resp, sizeof(cs_resp));
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- TEST_ASSERT(lower_current == cs_resp.get_state.chg_current);
-
- /* Remove the limit */
- cl_params.limit = -1U;
- rv = test_send_host_command(EC_CMD_CHARGE_CURRENT_LIMIT, 0,
- &cl_params, sizeof(cl_params),
- 0, 0);
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- wait_charging_state();
-
- /* See that it's back */
- rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
- &cs_params, sizeof(cs_params),
- &cs_resp, sizeof(cs_resp));
- TEST_ASSERT(rv == EC_RES_SUCCESS);
- TEST_ASSERT(norm_current == cs_resp.get_state.chg_current);
-
- return EC_SUCCESS;
-}
-
-static int test_low_battery_hostevents(void)
-{
- int state;
-
- test_setup(0);
-
- ccprintf("[CHARGING TEST] Low battery host events\n");
-
- /* You know you make me wanna */
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_LOW + 1);
- ev_clear(EC_HOST_EVENT_BATTERY_LOW);
- ev_clear(EC_HOST_EVENT_BATTERY_CRITICAL);
- ev_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_LOW));
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_CRITICAL));
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
-
- /* (Shout) a little bit louder now */
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_LOW - 1);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_CRITICAL));
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
- TEST_ASSERT(!is_shutdown);
-
- /* (Shout) a little bit louder now */
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_CRITICAL + 1);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_CRITICAL));
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
- TEST_ASSERT(!is_shutdown);
-
- /* (Shout) a little bit louder now */
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_CRITICAL - 1);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_CRITICAL));
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
- TEST_ASSERT(!is_shutdown);
-
- /* (Shout) a little bit louder now */
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_SHUTDOWN + 1);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_CRITICAL));
- TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
- TEST_ASSERT(!is_shutdown);
-
- /* (Shout) a little bit louder now */
- sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_SHUTDOWN - 1);
- state = wait_charging_state();
- TEST_ASSERT(state == PWR_STATE_DISCHARGE);
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_CRITICAL));
- /* hey-hey-HEY-hey. Doesn't immediately shut down */
- TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_SHUTDOWN));
- TEST_ASSERT(!is_shutdown);
- /* after a while, the AP should shut down */
- sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
- TEST_ASSERT(is_shutdown);
-
- 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. */
-
- ccprintf("Test SoC < lower < upper.\n");
- display_soc = 780;
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL);
- ccprintf("Pass.\n");
-
- ccprintf("Test lower < upper < SoC.\n");
- display_soc = 810;
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_DISCHARGE);
- ccprintf("Pass.\n");
-
- ccprintf("Test unplug AC.\n");
- gpio_set_level(GPIO_AC_PRESENT, 0);
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL);
- ccprintf("Pass.\n");
-
- ccprintf("Test replug AC.\n");
- gpio_set_level(GPIO_AC_PRESENT, 1);
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_DISCHARGE);
- ccprintf("Pass.\n");
-
- ccprintf("Test lower < SoC < upper.\n");
- display_soc = 799;
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_DISCHARGE);
- ccprintf("Pass.\n");
-
- ccprintf("Test SoC < lower < upper.\n");
- display_soc = 789;
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL);
- ccprintf("Pass.\n");
-
- ccprintf("Test disable sustainer.\n");
- charge_control(CHARGE_CONTROL_NORMAL);
- display_soc = 810;
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL);
- ccprintf("Pass.\n");
-
- ccprintf("Test enable sustainer when battery is full.\n");
- display_soc = 1000;
- is_full = 1;
- wait_charging_state();
- /* 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);
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_DISCHARGE);
- ccprintf("Pass.\n");
-
- /* Disable sustainer, unplug AC, upper < SoC < 100. */
- charge_control(CHARGE_CONTROL_NORMAL);
- display_soc = 810;
- is_full = 0;
- gpio_set_level(GPIO_AC_PRESENT, 0);
- wait_charging_state();
-
- ccprintf("Test enable sustainer when AC is present.\n");
- gpio_set_level(GPIO_AC_PRESENT, 1);
- wait_charging_state();
- /* 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);
- wait_charging_state();
- TEST_ASSERT(get_chg_ctrl_mode() == CHARGE_CONTROL_DISCHARGE);
- ccprintf("Pass.\n");
-
- 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(int argc, char **argv)
-{
- RUN_TEST(test_charge_state);
- RUN_TEST(test_low_battery);
- RUN_TEST(test_high_temp_battery);
- RUN_TEST(test_cold_battery_with_ac);
- RUN_TEST(test_cold_battery_no_ac);
- RUN_TEST(test_external_funcs);
- RUN_TEST(test_hc_charge_state);
- 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();
-}