diff options
author | Vic Yang <victoryang@chromium.org> | 2012-06-28 13:57:33 +0800 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-07-08 20:25:17 -0700 |
commit | d6086835e3231472f2075df53a86828fcfd6b5d5 (patch) | |
tree | bd82be6a3ed37a7b17df0a4ce219a928bee0e7fd | |
parent | e4df521df5c661a5c63a96dce9363be76f9377ca (diff) | |
download | chrome-ec-d6086835e3231472f2075df53a86828fcfd6b5d5.tar.gz |
Add a test of charging state machine
This test checks charging state machine works correctly:
- Charge when AC plugged. Discharge when AC unplugged.
- Shutdown when over/under-temperature during discharging.
- Stop charging when over/under-temperature during charging.
BUG=chrome-os-partner:10270
TEST=Test passed
Change-Id: I460645c70f5dcd30e258c43956ffe416c8bce906
Reviewed-on: https://gerrit.chromium.org/gerrit/26383
Reviewed-by: Rong Chang <rongchang@chromium.org>
Commit-Ready: Vic Yang <victoryang@chromium.org>
Tested-by: Vic Yang <victoryang@chromium.org>
-rw-r--r-- | common/mock_charger.c | 102 | ||||
-rw-r--r-- | common/mock_smart_battery_stub.c | 105 | ||||
-rw-r--r-- | common/mock_x86_power.c | 1 | ||||
-rw-r--r-- | test/build.mk | 8 | ||||
-rw-r--r-- | test/charging.py | 81 | ||||
-rw-r--r-- | test/charging.tasklist | 26 |
6 files changed, 322 insertions, 1 deletions
diff --git a/common/mock_charger.c b/common/mock_charger.c new file mode 100644 index 0000000000..b930835dcd --- /dev/null +++ b/common/mock_charger.c @@ -0,0 +1,102 @@ +/* Copyright (c) 2012 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. + * + * Mock battery charger driver. + */ + +#include "board.h" +#include "charger.h" +#include "console.h" +#include "common.h" +#include "smart_battery.h" +#include "uart.h" +#include "util.h" + +static const struct charger_info mock_charger_info = { + .name = "MockCharger", + .voltage_max = 19200, + .voltage_min = 1024, + .voltage_step = 16, + .current_max = 8192, + .current_min = 128, + .current_step = 128, + .input_current_max = 8064, + .input_current_min = 128, + .input_current_step = 128, +}; + +#define OPTION_CHARGE_INHIBIT (1 << 0) + +static uint32_t mock_option = 0; +static uint32_t mock_current = 0; +static uint32_t mock_voltage = 0; + +const struct charger_info *charger_get_info(void) +{ + return &mock_charger_info; +} + + +int charger_get_status(int *status) +{ + *status = CHARGER_LEVEL_2; + if (mock_option & CHARGE_FLAG_INHIBIT_CHARGE) + *status |= CHARGER_CHARGE_INHIBITED; + + return EC_SUCCESS; +} + + +int charger_set_mode(int mode) +{ + if (mode & CHARGE_FLAG_INHIBIT_CHARGE) + mock_option |= OPTION_CHARGE_INHIBIT; + else + mock_option &= ~OPTION_CHARGE_INHIBIT; + return EC_SUCCESS; +} + + +int charger_get_current(int *current) +{ + *current = mock_current; + return EC_SUCCESS; +} + + +int charger_set_current(int current) +{ + const struct charger_info *info = charger_get_info(); + + if (current > 0 && current < info->current_min) + current = info->current_min; + if (current > info->current_max) + current = info->current_max; + + mock_current = current; + uart_printf("Charger set current: %d\n", current); + return EC_SUCCESS; +} + + +int charger_get_voltage(int *voltage) +{ + *voltage = mock_voltage; + return EC_SUCCESS; +} + + +int charger_set_voltage(int voltage) +{ + mock_voltage = voltage; + uart_printf("Charger set voltage: %d\n", voltage); + return EC_SUCCESS; +} + + +int charger_post_init(void) +{ + mock_current = CONFIG_CHARGER_INPUT_CURRENT; + return EC_SUCCESS; +} diff --git a/common/mock_smart_battery_stub.c b/common/mock_smart_battery_stub.c new file mode 100644 index 0000000000..49b44859c9 --- /dev/null +++ b/common/mock_smart_battery_stub.c @@ -0,0 +1,105 @@ +#include "console.h" +#include "smart_battery.h" +#include "smart_battery_stub.h" +#include "uart.h" +#include "util.h" + +static int mock_temperature = 2981; +static int mock_desire_voltage = 7000; +static int mock_desire_current = 3000; +static int mock_voltage = 6000; +static int mock_current = 3000; + +int sb_read(int cmd, int *param) +{ + switch (cmd) + { + case SB_TEMPERATURE: + *param = mock_temperature; + break; + case SB_VOLTAGE: + *param = mock_voltage; + break; + case SB_CURRENT: + *param = mock_current; + break; + case SB_RELATIVE_STATE_OF_CHARGE: + case SB_ABSOLUTE_STATE_OF_CHARGE: + *param = 70; /* 70% charged */ + break; + case SB_REMAINING_CAPACITY: + *param = 7000; /* 7000 mAh */ + break; + case SB_FULL_CHARGE_CAPACITY: + case SB_DESIGN_CAPACITY: + *param = 10000; /* 10000 mAh */ + break; + case SB_AVERAGE_TIME_TO_EMPTY: + case SB_RUN_TIME_TO_EMPTY: + *param = 60; /* 60 min to empty */ + break; + case SB_AVERAGE_TIME_TO_FULL: + *param = 30; /* 30 min to full */ + break; + case SB_CHARGING_CURRENT: + *param = mock_desire_current; + break; + case SB_CHARGING_VOLTAGE: + *param = mock_desire_voltage; + break; + case SB_CYCLE_COUNT: + *param = 10; + break; + case SB_DESIGN_VOLTAGE: + *param = 7400; /* 7.4 V */ + break; + case SB_SERIAL_NUMBER: + *param = 112233; + break; + default: + *param = 0; + break; + } + + return EC_SUCCESS; +} + + +int sb_write(int cmd, int param) +{ + uart_printf("sb_write: cmd = %d, param = %d\n", cmd, param); + return EC_SUCCESS; +} + + +static int command_sb_mock(int argc, char **argv) +{ + char *e; + int v; + + if (argc < 3) + return EC_ERROR_PARAM_COUNT; + + v = strtoi(argv[2], &e, 0); + if (*e) + return EC_ERROR_PARAM2; + + if (!strcasecmp(argv[1], "temperature")) + mock_temperature = v; + else if (!strcasecmp(argv[1], "desire_voltage")) + mock_desire_voltage = v; + else if (!strcasecmp(argv[1], "desire_current")) + mock_desire_current = v; + else if (!strcasecmp(argv[1], "voltage")) + mock_voltage = v; + else if (!strcasecmp(argv[1], "current")) + mock_current = v; + else + return EC_ERROR_PARAM1; + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(sbmock, command_sb_mock, + "name value", + "Mock smart battery attribute", + NULL); diff --git a/common/mock_x86_power.c b/common/mock_x86_power.c index e108f8bd15..ac7f969bbc 100644 --- a/common/mock_x86_power.c +++ b/common/mock_x86_power.c @@ -32,6 +32,7 @@ void x86_power_cpu_overheated(int too_hot) void x86_power_force_shutdown(void) { uart_puts("Force shutdown\n"); + mock_power_on = 0; } diff --git a/test/build.mk b/test/build.mk index b950372ec7..c6240e1252 100644 --- a/test/build.mk +++ b/test/build.mk @@ -7,7 +7,7 @@ # test-list=hello pingpong timer_calib timer_dos timer_jump mutex thermal -test-list+=power_button kb_deghost kb_debounce scancode typematic +test-list+=power_button kb_deghost kb_debounce scancode typematic charging #disable: powerdemo pingpong-y=pingpong.o @@ -43,3 +43,9 @@ common-mock-typematic-i8042.o=mock_i8042.o # Mock modules for 'kb_debounce' chip-mock-kb_debounce-keyboard_scan_stub.o=mock_keyboard_scan_stub.o common-mock-kb_debounce-i8042.o=mock_i8042.o + +# Mock modules for 'charging; +chip-mock-charging-gpio.o=mock_gpio.o +common-mock-charging-x86_power.o=mock_x86_power.o +common-mock-charging-smart_battery_stub.o=mock_smart_battery_stub.o +common-mock-charging-charger_bq24725.o=mock_charger.o diff --git a/test/charging.py b/test/charging.py new file mode 100644 index 0000000000..366d3faa3c --- /dev/null +++ b/test/charging.py @@ -0,0 +1,81 @@ +# Copyright (c) 2011 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. +# +# Charging state machine unit test +# + +import time + +def consume_charge_state(helper): + try: + while True: + helper.wait_output("Charge state \S+ -> \S+", + use_re=True, + timeout=1) + except: + pass + +def wait_charge_state(helper, state): + helper.wait_output("Charge state \S+ -> %s" % state, use_re=True) + +def test(helper): + helper.wait_output("--- UART initialized") + + # Check charge when AC present + consume_charge_state(helper) + helper.ec_command("gpiomock AC_PRESENT 1") + wait_charge_state(helper, "charge") + + # Check discharge when AC not present + helper.ec_command("gpiomock AC_PRESENT 0") + wait_charge_state(helper, "discharge") + + # Check charge current + helper.ec_command("sbmock desire_current 2800") + helper.ec_command("gpiomock AC_PRESENT 1") + helper.wait_output("Charger set current: 2800") + + # Check charger voltage + helper.ec_command("gpiomock AC_PRESENT 0") + wait_charge_state(helper, "discharge") + helper.ec_command("sbmock desire_voltage 7500") + helper.ec_command("gpiomock AC_PRESENT 1") + helper.wait_output("Charger set voltage: 7500") + + # While powered on and discharging, over-temperature should trigger + # system shutdown + helper.ec_command("gpiomock AC_PRESENT 0") + wait_charge_state(helper, "discharge") + helper.ec_command("powermock on") + helper.ec_command("sbmock temperature 3700") + helper.wait_output("Force shutdown") + helper.ec_command("sbmock temperature 2981") + time.sleep(1) + + # While powered on and discharging, under-temperature should trigger + # system shutdown + helper.ec_command("powermock on") + helper.ec_command("sbmock temperature 2600") + helper.wait_output("Force shutdown") + helper.ec_command("sbmock temperature 2981") + + # While powered on and charging, over-temperature should stop battery + # from charging + consume_charge_state(helper) + helper.ec_command("gpiomock AC_PRESENT 1") + wait_charge_state(helper, "charge") + helper.ec_command("powermock on") + helper.ec_command("sbmock temperature 3700") + wait_charge_state(helper, "idle") + helper.ec_command("sbmock temperature 2981") + wait_charge_state(helper, "charge") + + # While powered on and charging, under-temperature should stop battery + # from charging + helper.ec_command("sbmock temperature 2600") + wait_charge_state(helper, "idle") + helper.ec_command("sbmock temperature 2981") + wait_charge_state(helper, "charge") + + return True # PASS ! diff --git a/test/charging.tasklist b/test/charging.tasklist new file mode 100644 index 0000000000..4a0d674e91 --- /dev/null +++ b/test/charging.tasklist @@ -0,0 +1,26 @@ +/* Copyright (c) 2012 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. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK(n, r, d) where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + */ +#define CONFIG_TASK_LIST \ + TASK(WATCHDOG, watchdog_task, NULL) \ + TASK(VBOOTHASH, vboot_hash_task, NULL) \ + TASK(PWM, pwm_task, NULL) \ + TASK(TYPEMATIC, keyboard_typematic_task, NULL) \ + TASK(POWERSTATE, charge_state_machine_task, NULL) \ + TASK(X86POWER, x86_power_task, NULL) \ + TASK(I8042CMD, i8042_command_task, NULL) \ + TASK(KEYSCAN, keyboard_scan_task, NULL) \ + TASK(POWERBTN, power_button_task, NULL) \ + TASK(CONSOLE, console_task, NULL) |