summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2012-06-28 13:57:33 +0800
committerGerrit <chrome-bot@google.com>2012-07-08 20:25:17 -0700
commitd6086835e3231472f2075df53a86828fcfd6b5d5 (patch)
treebd82be6a3ed37a7b17df0a4ce219a928bee0e7fd
parente4df521df5c661a5c63a96dce9363be76f9377ca (diff)
downloadchrome-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.c102
-rw-r--r--common/mock_smart_battery_stub.c105
-rw-r--r--common/mock_x86_power.c1
-rw-r--r--test/build.mk8
-rw-r--r--test/charging.py81
-rw-r--r--test/charging.tasklist26
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)