diff options
author | Vic Yang <victoryang@chromium.org> | 2014-08-08 10:59:17 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-08-10 06:07:11 +0000 |
commit | 0739074fbf735cffefdac7ff6d086084449f6493 (patch) | |
tree | dc4c7b0925762cf700c7bbcc48a7b541468d2978 /test | |
parent | e68bdb6eb5dc0f42347bf1db6f350ae173900d0c (diff) | |
download | chrome-ec-0739074fbf735cffefdac7ff6d086084449f6493.tar.gz |
Add unit test for usb_pd
Initial commit of usb_pd unit test. The test cases are very simple.
We'll add more test cases in similar format.
BUG=chrome-os-partner:31200
TEST=Pass usb_pd test
BRANCH=None
Change-Id: I9e3de5b2c032ee1d3670cde6d8227ce0378ae8a0
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/211643
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'test')
-rw-r--r-- | test/build.mk | 8 | ||||
-rw-r--r-- | test/usb_pd.c | 204 | ||||
-rw-r--r-- | test/usb_pd.tasklist | 17 | ||||
-rw-r--r-- | test/usb_pd_test_util.h | 31 |
4 files changed, 257 insertions, 3 deletions
diff --git a/test/build.mk b/test/build.mk index cb1ced36b1..e87e3fcd88 100644 --- a/test/build.mk +++ b/test/build.mk @@ -31,18 +31,20 @@ 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_sense math_util sbs_charging_v2 battery_get_params_smart +test-list-host+=usb_pd adapter-y=adapter.o -button-y=button.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 console_edit-y=console_edit.o extpwr_gpio-y=extpwr_gpio.o flash-y=flash.o hooks-y=hooks.o host_command-y=host_command.o -kb_8042-y=kb_8042.o interrupt-y=interrupt.o +kb_8042-y=kb_8042.o kb_mkbp-y=kb_mkbp.o kb_scan-y=kb_scan.o led_spring-y=led_spring.o led_spring_impl.o @@ -62,5 +64,5 @@ thermal-y=thermal.o thermal_falco-y=thermal_falco.o timer_calib-y=timer_calib.o timer_dos-y=timer_dos.o +usb_pd-y=usb_pd.o utils-y=utils.o -battery_get_params_smart-y=battery_get_params_smart.o diff --git a/test/usb_pd.c b/test/usb_pd.c new file mode 100644 index 0000000000..fd10d44840 --- /dev/null +++ b/test/usb_pd.c @@ -0,0 +1,204 @@ +/* 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 USB PD module. + */ + +#include "common.h" +#include "crc.h" +#include "task.h" +#include "test_util.h" +#include "timer.h" +#include "usb_pd.h" +#include "usb_pd_config.h" +#include "usb_pd_test_util.h" +#include "util.h" + +struct pd_port_t { + int host_mode; + int cc_volt[2]; /* -1 for Hi-Z */ + int has_vbus; + int msg_tx_id; + int msg_rx_id; + int polarity; +} pd_port[PD_PORT_COUNT]; + +/* Mock functions */ + +int pd_adc_read(int port, int cc) +{ + int val = pd_port[port].cc_volt[cc]; + if (val == -1) + return pd_port[port].host_mode ? 3000 : 0; + return val; +} + +int pd_snk_is_vbus_provided(int port) +{ + return pd_port[port].has_vbus; +} + +void pd_set_host_mode(int port, int enable) +{ + pd_port[port].host_mode = enable; +} + +void pd_select_polarity(int port, int polarity) +{ + pd_port[port].polarity = polarity; +} + +/* Tests */ + +void inc_tx_id(int port) +{ + pd_port[port].msg_tx_id = (pd_port[port].msg_tx_id + 1) % 7; +} + +void inc_rx_id(int port) +{ + pd_port[port].msg_rx_id = (pd_port[port].msg_rx_id + 1) % 7; +} + +static void init_ports(void) +{ + int i; + + for (i = 0; i < PD_PORT_COUNT; ++i) { + pd_port[i].host_mode = 0; + pd_port[i].cc_volt[0] = pd_port[i].cc_volt[1] = -1; + pd_port[i].has_vbus = 0; + } +} + +static void simulate_rx_msg(int port, uint16_t header, int cnt, + const uint32_t *data) +{ + int i; + + pd_test_rx_set_preamble(port, 1); + pd_test_rx_msg_append_sop(port); + pd_test_rx_msg_append_short(port, header); + + crc32_init(); + crc32_hash16(header); + for (i = 0; i < cnt; ++i) { + pd_test_rx_msg_append_word(port, data[i]); + crc32_hash32(data[i]); + } + pd_test_rx_msg_append_word(port, crc32_result()); + + pd_test_rx_msg_append_eop(port); + + pd_simulate_rx(port); +} + +static void simulate_source_cap(int port) +{ + uint16_t header = PD_HEADER(PD_DATA_SOURCE_CAP, PD_ROLE_SOURCE, + pd_port[port].msg_rx_id, pd_src_pdo_cnt); + simulate_rx_msg(port, header, pd_src_pdo_cnt, pd_src_pdo); +} + +static void simulate_goodcrc(int port, int role, int id) +{ + simulate_rx_msg(port, PD_HEADER(PD_CTRL_GOOD_CRC, role, id, 0), + 0, NULL); +} + +static int verify_goodcrc(int port, int role, int id) +{ + return pd_test_tx_msg_verify_sop(0) && + pd_test_tx_msg_verify_short(0, PD_HEADER(PD_CTRL_GOOD_CRC, + role, id, 0)) && + pd_test_tx_msg_verify_crc(0) && + pd_test_tx_msg_verify_eop(0); +} + +static void plug_in_source(int port, int polarity) +{ + pd_port[port].has_vbus = 1; + pd_port[port].cc_volt[polarity] = 3000; +} + +static void plug_in_sink(int port, int polarity) +{ + pd_port[port].has_vbus = 0; + pd_port[port].cc_volt[polarity] = 0; +} + +static void unplug(int port) +{ + pd_port[port].has_vbus = 0; + pd_port[port].cc_volt[0] = -1; + pd_port[port].cc_volt[1] = -1; + task_wake(PORT_TO_TASK_ID(port)); + usleep(30 * MSEC); +} + +static int test_request(void) +{ + plug_in_source(0, 0); + task_wake(PORT_TO_TASK_ID(0)); + usleep(30 * MSEC); + TEST_ASSERT(pd_port[0].polarity == 0); + + simulate_source_cap(0); + task_wait_event(3 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[0].msg_rx_id)); + task_wake(PORT_TO_TASK_ID(0)); + task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ + inc_rx_id(0); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(0)); + TEST_ASSERT(pd_test_tx_msg_verify_short(0, + PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, + pd_port[0].msg_tx_id, 1))); + TEST_ASSERT(pd_test_tx_msg_verify_word(0, RDO_FIXED(2, 450, 900, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_crc(0)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(0)); + inc_tx_id(0); + unplug(0); + return EC_SUCCESS; +} + +static int test_sink(void) +{ + int i; + + plug_in_sink(1, 1); + task_wake(PORT_TO_TASK_ID(1)); + task_wait_event(250 * MSEC); /* tTypeCSinkWaitCap: 210~250 ms */ + TEST_ASSERT(pd_port[1].polarity == 1); + + TEST_ASSERT(pd_test_tx_msg_verify_sop(1)); + TEST_ASSERT(pd_test_tx_msg_verify_short(1, + PD_HEADER(PD_DATA_SOURCE_CAP, PD_ROLE_SOURCE, + pd_port[1].msg_tx_id, pd_src_pdo_cnt))); + for (i = 0; i < pd_src_pdo_cnt; ++i) + TEST_ASSERT(pd_test_tx_msg_verify_word(1, pd_src_pdo[i])); + TEST_ASSERT(pd_test_tx_msg_verify_crc(1)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(1)); + + simulate_goodcrc(1, PD_ROLE_SINK, pd_port[1].msg_tx_id); + task_wake(PORT_TO_TASK_ID(1)); + usleep(30 * MSEC); + inc_tx_id(1); + + unplug(1); + return EC_SUCCESS; +} + +void run_test(void) +{ + test_reset(); + init_ports(); + pd_set_dual_role(PD_DRP_TOGGLE_ON); + + RUN_TEST(test_request); + RUN_TEST(test_sink); + + test_print_result(); +} diff --git a/test/usb_pd.tasklist b/test/usb_pd.tasklist new file mode 100644 index 0000000000..356ef4de39 --- /dev/null +++ b/test/usb_pd.tasklist @@ -0,0 +1,17 @@ +/* Copyright (c) 2013 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 diff --git a/test/usb_pd_test_util.h b/test/usb_pd_test_util.h new file mode 100644 index 0000000000..5be8e0984a --- /dev/null +++ b/test/usb_pd_test_util.h @@ -0,0 +1,31 @@ +/* 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 utilities for USB PD unit test. + */ + +#ifndef __USB_PD_TEST_UTIL_H +#define __USB_PD_TEST_UTIL_H + +/* Simulate Rx message */ +void pd_test_rx_set_preamble(int port, int has_preamble); +void pd_test_rx_msg_append_bits(int port, uint32_t bits, int nb); +void pd_test_rx_msg_append_kcode(int port, uint8_t kcode); +void pd_test_rx_msg_append_sop(int port); +void pd_test_rx_msg_append_eop(int port); +void pd_test_rx_msg_append_4b(int port, uint8_t val); +void pd_test_rx_msg_append_short(int port, uint16_t val); +void pd_test_rx_msg_append_word(int port, uint32_t val); +void pd_simulate_rx(int port); + +/* Verify Tx message */ +int pd_test_tx_msg_verify_kcode(int port, uint8_t kcode); +int pd_test_tx_msg_verify_sop(int port); +int pd_test_tx_msg_verify_eop(int port); +int pd_test_tx_msg_verify_4b5b(int port, uint8_t b4); +int pd_test_tx_msg_verify_short(int port, uint16_t val); +int pd_test_tx_msg_verify_word(int port, uint32_t val); +int pd_test_tx_msg_verify_crc(int port); + +#endif /* __USB_PD_TEST_UTIL_H */ |