diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2014-11-05 10:02:01 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-13 00:29:58 +0000 |
commit | cf48a3640c271663fc1c4156b16f4a25264944d9 (patch) | |
tree | 0330fdc3a2c6453bc46a4310431a1506bd978cfb /test | |
parent | 06fb4fe0f2ee33c912fa10ed7fecdbe8c9c193d6 (diff) | |
download | chrome-ec-cf48a3640c271663fc1c4156b16f4a25264944d9.tar.gz |
charge_manager: Add unit tests
Add unit tests for the charge_manager module.
BUG=chrome-os-partner:32003
TEST=`make buildall -j`
BRANCH=Samus
Change-Id: I31962588ca7360e2ffde6b83459505872e2128b9
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/227620
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'test')
-rw-r--r-- | test/build.mk | 3 | ||||
-rw-r--r-- | test/charge_manager.c | 266 | ||||
-rw-r--r-- | test/charge_manager.tasklist | 17 | ||||
-rw-r--r-- | test/test_config.h | 5 |
4 files changed, 290 insertions, 1 deletions
diff --git a/test/build.mk b/test/build.mk index ff5e617fbb..0515d5a142 100644 --- a/test/build.mk +++ b/test/build.mk @@ -31,13 +31,14 @@ test-list-host+=thermal flash queue kb_8042 extpwr_gpio console_edit system test-list-host+=sbs_charging adapter host_command thermal_falco led_spring test-list-host+=bklight_lid bklight_passthru interrupt timer_dos button test-list-host+=motion_lid math_util sbs_charging_v2 battery_get_params_smart -test-list-host+=lightbar inductive_charging usb_pd fan +test-list-host+=lightbar inductive_charging usb_pd fan charge_manager adapter-y=adapter.o battery_get_params_smart-y=battery_get_params_smart.o bklight_lid-y=bklight_lid.o bklight_passthru-y=bklight_passthru.o button-y=button.o +charge_manager-y=charge_manager.o console_edit-y=console_edit.o extpwr_gpio-y=extpwr_gpio.o flash-y=flash.o diff --git a/test/charge_manager.c b/test/charge_manager.c new file mode 100644 index 0000000000..b721d79e52 --- /dev/null +++ b/test/charge_manager.c @@ -0,0 +1,266 @@ +/* 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 manager module. + */ + +#include "charge_manager.h" +#include "test_util.h" +#include "timer.h" +#include "usb_pd_config.h" +#include "util.h" + +#define CHARGE_MANAGER_SLEEP_MS 50 + +/* Charge supplier priority: lower number indicates higher priority. */ +const int supplier_priority[] = { + [CHARGE_SUPPLIER_TEST1] = 0, + [CHARGE_SUPPLIER_TEST2] = 1, + [CHARGE_SUPPLIER_TEST3] = 1, + [CHARGE_SUPPLIER_TEST4] = 1, + [CHARGE_SUPPLIER_TEST5] = 3, + [CHARGE_SUPPLIER_TEST6] = 3, + [CHARGE_SUPPLIER_TEST7] = 5, + [CHARGE_SUPPLIER_TEST8] = 6, + [CHARGE_SUPPLIER_TEST9] = 6, +}; +BUILD_ASSERT(ARRAY_SIZE(supplier_priority) == CHARGE_SUPPLIER_COUNT); + +static unsigned int active_charge_limit = CHARGE_SUPPLIER_NONE; +static unsigned int active_charge_port = CHARGE_PORT_NONE; +static int new_power_request[PD_PORT_COUNT]; + +/* Callback functions called by CM on state change */ +void board_set_charge_limit(int charge_ma) +{ + active_charge_limit = charge_ma; +} + +void board_set_active_charge_port(int charge_port) +{ + active_charge_port = charge_port; +} + +void pd_set_new_power_request(int port) +{ + new_power_request[port] = 1; +} + +void clear_new_power_requests(void) +{ + int i; + for (i = 0; i < PD_PORT_COUNT; ++i) + new_power_request[i] = 0; +} + +static void wait_for_charge_manager_refresh(void) +{ + msleep(CHARGE_MANAGER_SLEEP_MS); +} + +static void initialize_charge_table(int current, int voltage, int ceil) +{ + int i, j; + struct charge_port_info charge; + + charge.current = current; + charge.voltage = voltage; + + for (i = 0; i < PD_PORT_COUNT; ++i) { + charge_manager_set_ceil(i, ceil); + for (j = 0; j < CHARGE_SUPPLIER_COUNT; ++j) + charge_manager_update(j, i, &charge); + } + wait_for_charge_manager_refresh(); +} + +static int test_initialization(void) +{ + int i, j; + struct charge_port_info charge; + + /* + * No charge port should be selected until all ports + suppliers + * have reported in with an initial charge. + */ + TEST_ASSERT(active_charge_port == CHARGE_PORT_NONE); + charge.current = 1000; + charge.voltage = 5000; + + /* Initialize all supplier/port pairs, except for the last one */ + for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i) + for (j = 0; j < PD_PORT_COUNT; ++j) { + if (i == CHARGE_SUPPLIER_COUNT - 1 && + j == PD_PORT_COUNT - 1) + break; + charge_manager_update(i, j, &charge); + } + + /* Verify no active charge port, since all pairs haven't updated */ + wait_for_charge_manager_refresh(); + TEST_ASSERT(active_charge_port == CHARGE_PORT_NONE); + + /* Update last pair and verify a charge port has been selected */ + charge_manager_update(CHARGE_SUPPLIER_COUNT-1, + PD_PORT_COUNT-1, + &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(active_charge_port != CHARGE_PORT_NONE); + + return EC_SUCCESS; +} + +static int test_priority(void) +{ + struct charge_port_info charge; + + /* Initialize table to no charge */ + initialize_charge_table(0, 5000, 5000); + TEST_ASSERT(active_charge_port == CHARGE_PORT_NONE); + + /* + * Set a 1A charge via a high-priority supplier and a 2A charge via + * a low-priority supplier, and verify the HP supplier is chosen. + */ + charge.current = 2000; + charge.voltage = 5000; + charge_manager_update(CHARGE_SUPPLIER_TEST6, 0, &charge); + charge.current = 1000; + charge_manager_update(CHARGE_SUPPLIER_TEST2, 1, &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(active_charge_port == 1); + TEST_ASSERT(active_charge_limit == 1000); + + /* + * Set a higher charge on a LP supplier and verify we still use the + * lower charge. + */ + charge.current = 1500; + charge_manager_update(CHARGE_SUPPLIER_TEST7, 1, &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(active_charge_port == 1); + TEST_ASSERT(active_charge_limit == 1000); + + /* + * Zero our HP charge and verify fallback to next highest priority, + * which happens to be a different port. + */ + charge.current = 0; + charge_manager_update(CHARGE_SUPPLIER_TEST2, 1, &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(active_charge_port == 0); + TEST_ASSERT(active_charge_limit == 2000); + + /* Add a charge at equal priority and verify highest charge selected */ + charge.current = 2500; + charge_manager_update(CHARGE_SUPPLIER_TEST5, 0, &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(active_charge_port == 0); + TEST_ASSERT(active_charge_limit == 2500); + + charge.current = 3000; + charge_manager_update(CHARGE_SUPPLIER_TEST6, 1, &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(active_charge_port == 1); + TEST_ASSERT(active_charge_limit == 3000); + + return EC_SUCCESS; +} + +static int test_charge_ceil(void) +{ + int port; + struct charge_port_info charge; + + /* Initialize table to 1A @ 5V, and verify port + limit */ + initialize_charge_table(1000, 5000, 1000); + TEST_ASSERT(active_charge_port != CHARGE_PORT_NONE); + TEST_ASSERT(active_charge_limit == 1000); + + /* Set a 500mA ceiling, verify port is unchanged */ + port = active_charge_port; + charge_manager_set_ceil(port, 500); + wait_for_charge_manager_refresh(); + TEST_ASSERT(port == active_charge_port); + TEST_ASSERT(active_charge_limit == 500); + + /* Raise the ceiling to 2A, verify limit goes back to 1A */ + charge_manager_set_ceil(port, 2000); + wait_for_charge_manager_refresh(); + TEST_ASSERT(port == active_charge_port); + TEST_ASSERT(active_charge_limit == 1000); + + /* Verify that ceiling is ignored in determining active charge port */ + charge.current = 2000; + charge.voltage = 5000; + charge_manager_update(0, 0, &charge); + charge.current = 2500; + charge_manager_update(0, 1, &charge); + charge_manager_set_ceil(1, 750); + wait_for_charge_manager_refresh(); + TEST_ASSERT(active_charge_port == 1); + TEST_ASSERT(active_charge_limit == 750); + + return EC_SUCCESS; +} + +static int test_new_power_request(void) +{ + struct charge_port_info charge; + + /* Initialize table to no charge */ + initialize_charge_table(0, 5000, 5000); + /* Clear power requests, and verify they are zero'd */ + clear_new_power_requests(); + wait_for_charge_manager_refresh(); + TEST_ASSERT(new_power_request[0] == 0); + TEST_ASSERT(new_power_request[1] == 0); + + /* Charge from port 1 and verify NPR on port 1 only */ + charge.current = 1000; + charge.voltage = 5000; + charge_manager_update(CHARGE_SUPPLIER_TEST2, 1, &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(new_power_request[0] == 0); + TEST_ASSERT(new_power_request[1] == 1); + clear_new_power_requests(); + + /* Reduce port 1 limit and verify NPR on port 1 only */ + charge_manager_set_ceil(1, 500); + wait_for_charge_manager_refresh(); + TEST_ASSERT(new_power_request[0] == 0); + TEST_ASSERT(new_power_request[1] == 1); + clear_new_power_requests(); + + /* Add low-priority source and verify no NPRs */ + charge_manager_update(CHARGE_SUPPLIER_TEST6, 0, &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(new_power_request[0] == 0); + TEST_ASSERT(new_power_request[1] == 0); + clear_new_power_requests(); + + /* + * Add higher-priority source and verify NPR on both ports, + * since we're switching charge ports. + */ + charge_manager_update(CHARGE_SUPPLIER_TEST1, 0, &charge); + wait_for_charge_manager_refresh(); + TEST_ASSERT(new_power_request[0] == 1); + TEST_ASSERT(new_power_request[1] == 1); + clear_new_power_requests(); + + return EC_SUCCESS; +} + +void run_test(void) +{ + test_reset(); + + RUN_TEST(test_initialization); + RUN_TEST(test_priority); + RUN_TEST(test_charge_ceil); + RUN_TEST(test_new_power_request); + + test_print_result(); +} diff --git a/test/charge_manager.tasklist b/test/charge_manager.tasklist new file mode 100644 index 0000000000..927bd24ee1 --- /dev/null +++ b/test/charge_manager.tasklist @@ -0,0 +1,17 @@ +/* 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. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_TEST(n, r, d, s) 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 + * 's' is the stack size in bytes; must be a multiple of 8 + */ +#define CONFIG_TEST_TASK_LIST /* No test task */ diff --git a/test/test_config.h b/test/test_config.h index 303bc54f86..2fd090d5d0 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -133,5 +133,10 @@ int board_discharge_on_ac(int enabled); #define CONFIG_SW_CRC #endif +#ifdef TEST_CHARGE_MANAGER +#define CONFIG_CHARGE_MANAGER +#define CONFIG_USB_PD_DUAL_ROLE +#endif + #endif /* TEST_BUILD */ #endif /* __CROS_EC_TEST_CONFIG_H */ |