From fd9de64cdfd14943110cde1ac69c1f5542acccd1 Mon Sep 17 00:00:00 2001 From: Denis Brockus Date: Wed, 6 Jan 2021 10:52:29 -0700 Subject: TCPMv2: Compliance Unit Test - TD.PD.SRC3.E7 BUG=none BRANCH=none TEST=make buildall Signed-off-by: Denis Brockus Change-Id: Iaa6888d2e0d861d64b2747856465789304dde414 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2613724 Tested-by: Denis Brockus Auto-Submit: Denis Brockus Reviewed-by: Edward Hill Commit-Queue: Denis Brockus --- common/mock/tcpci_i2c_mock.c | 74 ++++++++++++++++++++ include/mock/tcpci_i2c_mock.h | 14 ++++ test/build.mk | 1 + test/test_config.h | 1 + test/usb_tcpmv2_compliance.c | 1 + test/usb_tcpmv2_compliance.h | 1 + test/usb_tcpmv2_compliance.mocklist | 3 +- test/usb_tcpmv2_td_pd_src3_e7.c | 133 ++++++++++++++++++++++++++++++++++++ 8 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 test/usb_tcpmv2_td_pd_src3_e7.c diff --git a/common/mock/tcpci_i2c_mock.c b/common/mock/tcpci_i2c_mock.c index 7cf213533c..e3c3b63675 100644 --- a/common/mock/tcpci_i2c_mock.c +++ b/common/mock/tcpci_i2c_mock.c @@ -282,6 +282,80 @@ int verify_tcpci_tx_with_data(enum tcpm_transmit_type tx_type, } return rv; } + +int verify_tcpci_possible_tx(struct possible_tx possible[], + int possible_cnt, + int *found_index, + uint8_t *data, + int data_bytes, + int *msg_len, + int timeout) +{ + uint64_t end_time; + + *found_index = -1; + + if (timeout <= 0) + timeout = VERIFY_TIMEOUT; + end_time = get_time().val + timeout; + + /* + * Check that nothing was already transmitted. This ensures that all + * transmits are checked, and the test stays in sync with the code + * being tested. + */ + TEST_EQ(tcpci_regs[TCPC_REG_TRANSMIT].value, 0, "%d"); + + /* Now wait for the expected message to be transmitted. */ + while (get_time().val < end_time) { + if (tcpci_regs[TCPC_REG_TRANSMIT].value != 0) { + int i; + int tx_type = TCPC_REG_TRANSMIT_TYPE( + tcpci_regs[TCPC_REG_TRANSMIT].value); + uint16_t header = UINT16_FROM_BYTE_ARRAY_LE( + tx_buffer, 1); + int pd_type = PD_HEADER_TYPE(header); + int pd_cnt = PD_HEADER_CNT(header); + + for (i = 0; i < possible_cnt; ++i) { + int want_tx_type = possible[i].tx_type; + int want_ctrl_msg = possible[i].ctrl_msg; + int want_data_msg = possible[i].data_msg; + + if (tx_type != want_tx_type) + continue; + + if (want_ctrl_msg != 0) { + if (pd_type != want_ctrl_msg || + pd_cnt != 0) + continue; + } + if (want_data_msg != 0) { + if (pd_type != want_data_msg || + pd_cnt == 0) + continue; + + if (data != NULL) { + TEST_GE(data_bytes, + tx_msg_cnt, "%d"); + memcpy(data, tx_buffer, + tx_msg_cnt); + } + if (msg_len != NULL) + *msg_len = tx_msg_cnt; + } + *found_index = i; + tcpci_regs[TCPC_REG_TRANSMIT].value = 0; + return EC_SUCCESS; + } + break; + } + task_wait_event(5 * MSEC); + } + TEST_ASSERT(0); + return EC_ERROR_UNKNOWN; +} + void mock_tcpci_receive(enum pd_msg_type sop, uint16_t header, uint32_t *payload) { diff --git a/include/mock/tcpci_i2c_mock.h b/include/mock/tcpci_i2c_mock.h index 06f5885a57..46691e5b46 100644 --- a/include/mock/tcpci_i2c_mock.h +++ b/include/mock/tcpci_i2c_mock.h @@ -37,6 +37,20 @@ int verify_tcpci_tx_with_data(enum tcpm_transmit_type tx_type, int *msg_len, int timeout); +struct possible_tx { + enum tcpm_transmit_type tx_type; + enum pd_ctrl_msg_type ctrl_msg; + enum pd_data_msg_type data_msg; +}; + +int verify_tcpci_possible_tx(struct possible_tx possible[], + int possible_cnt, + int *found_index, + uint8_t *data, + int data_bytes, + int *msg_len, + int timeout); + void mock_tcpci_receive(enum pd_msg_type sop, uint16_t header, uint32_t *payload); diff --git a/test/build.mk b/test/build.mk index 0f67c9da53..5e3c74511f 100644 --- a/test/build.mk +++ b/test/build.mk @@ -224,6 +224,7 @@ usb_tcpmv2_compliance-y=usb_tcpmv2_compliance.o usb_tcpmv2_compliance_common.o \ usb_tcpmv2_td_pd_src_e2.o \ usb_tcpmv2_td_pd_src_e5.o \ usb_tcpmv2_td_pd_src3_e1.o \ + usb_tcpmv2_td_pd_src3_e7.o \ usb_tcpmv2_td_pd_src3_e26.o \ usb_tcpmv2_td_pd_snk3_e12.o \ usb_tcpmv2_td_pd_other.o diff --git a/test/test_config.h b/test/test_config.h index 712ad61a14..d5f0bfe103 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -493,6 +493,7 @@ int ncp15wb_calculate_temp(uint16_t adc); #define CONFIG_USB_PD_TCPM_TCPCI #define CONFIG_I2C #define CONFIG_I2C_CONTROLLER +#define CONFIG_BATTERY #define I2C_PORT_HOST_TCPC 0 #define CONFIG_USB_PD_DEBUG_LEVEL 3 #define CONFIG_USB_PD_EXTENDED_MESSAGES diff --git a/test/usb_tcpmv2_compliance.c b/test/usb_tcpmv2_compliance.c index 9c97883c45..569fab8527 100644 --- a/test/usb_tcpmv2_compliance.c +++ b/test/usb_tcpmv2_compliance.c @@ -45,6 +45,7 @@ void run_test(int argc, char **argv) RUN_TEST(test_td_pd_src_e5); RUN_TEST(test_td_pd_src3_e1); + RUN_TEST(test_td_pd_src3_e7); RUN_TEST(test_td_pd_src3_e26); RUN_TEST(test_td_pd_snk3_e12); diff --git a/test/usb_tcpmv2_compliance.h b/test/usb_tcpmv2_compliance.h index c3277c0566..120fd0b6a1 100644 --- a/test/usb_tcpmv2_compliance.h +++ b/test/usb_tcpmv2_compliance.h @@ -84,6 +84,7 @@ int test_td_pd_src_e2(void); int test_td_pd_src_e5(void); int test_td_pd_src3_e1(void); +int test_td_pd_src3_e7(void); int test_td_pd_src3_e26(void); int test_td_pd_snk3_e12(void); diff --git a/test/usb_tcpmv2_compliance.mocklist b/test/usb_tcpmv2_compliance.mocklist index 58a3541412..f364fb1050 100644 --- a/test/usb_tcpmv2_compliance.mocklist +++ b/test/usb_tcpmv2_compliance.mocklist @@ -5,4 +5,5 @@ #define CONFIG_TEST_MOCK_LIST \ MOCK(USB_MUX) \ - MOCK(TCPCI_I2C) + MOCK(TCPCI_I2C) \ + MOCK(BATTERY) diff --git a/test/usb_tcpmv2_td_pd_src3_e7.c b/test/usb_tcpmv2_td_pd_src3_e7.c new file mode 100644 index 0000000000..c29685995e --- /dev/null +++ b/test/usb_tcpmv2_td_pd_src3_e7.c @@ -0,0 +1,133 @@ +/* Copyright 2021 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. + */ + +#include "battery.h" +#include "mock/tcpci_i2c_mock.h" +#include "task.h" +#include "driver/tcpm/tcpci.h" +#include "test_util.h" +#include "timer.h" +#include "usb_tcpmv2_compliance.h" +#include "usb_tc_sm.h" + +#define BUFFER_SIZE 100 +#define SRC_CAP_EXT_NUM_BATTERY_OFFSET 22 + +#define EXT_MSG_CHUNKED BIT(15) +#define EXT_MSG_DATA_SIZE_1 1 +#define GBSDB_FIXED_BATTERY_0 (0 << 16) + + +static int number_of_fixed_batteries(void) +{ + return 1; +} + +static int number_of_swappable_batteries(void) +{ + return 0; +} + +/***************************************************************************** + * TD.PD.SRC3.E7 Battery Status sent timely + * + * Description: + * As Consumer (UFP), the Tester verifies that the UUT replies + * Get_Battery_Status message with a Battery_Status message timely. + */ +int test_td_pd_src3_e7(void) +{ + int msg_len; + uint8_t data[BUFFER_SIZE]; + uint32_t ext_msg; + + int found_index; + struct possible_tx possible[2]; + + TEST_EQ(tcpci_startup(), EC_SUCCESS, "%d"); + + /* + * a) Run PROC.PD.E1 Bring-up according to the UUT role. + */ + TEST_EQ(proc_pd_e1(PD_ROLE_DFP, INITIAL_AND_ALREADY_ATTACHED), + EC_SUCCESS, "%d"); + + /* + * b) The Tester waits until it can start an AMS (Run PROC.PD.E3) and + * sends a Get_Source_Cap_Extended message to the UUT. + */ + TEST_EQ(proc_pd_e3(), EC_SUCCESS, "%d"); + + partner_send_msg(PD_MSG_SOP, PD_CTRL_GET_SOURCE_CAP_EXT, 0, 0, NULL); + + /* + * c) If a Not_Supported message is received, and Num_Fixed_Batteries + * and Num_Swappable_Battery_Slots in the VIF are 0, the test + * passes and stops here. + */ + possible[0].tx_type = TCPC_TX_SOP; + possible[0].ctrl_msg = PD_CTRL_NOT_SUPPORTED; + possible[0].data_msg = 0; + + possible[1].tx_type = TCPC_TX_SOP; + possible[1].ctrl_msg = 0; + possible[1].data_msg = PD_EXT_SOURCE_CAP; + + TEST_EQ(verify_tcpci_possible_tx(possible, + 2, + &found_index, + data, + sizeof(data), + &msg_len, + 0), + EC_SUCCESS, "%d"); + if (found_index == 0) { + mock_set_alert(TCPC_REG_ALERT_TX_SUCCESS); + task_wait_event(10 * MSEC); + + if (number_of_fixed_batteries() == 0 && + number_of_swappable_batteries() == 0) + return EC_SUCCESS; + } + /* + * d) If the Number of Batteries/Battery Slots field in the returned + * Source_Capabilities_Extended message is 0, the test passes and + * stops here. + */ + else { + TEST_EQ(found_index, 1, "%d"); + mock_set_alert(TCPC_REG_ALERT_TX_SUCCESS); + task_wait_event(10 * MSEC); + + if (data[2+SRC_CAP_EXT_NUM_BATTERY_OFFSET] == 0) + return EC_SUCCESS; + } + + /* + * e) The Tester waits until it can start an AMS (Run PROC.PD.E3) and + * sends a Get_Battery_Status message to the UUT + */ + ext_msg = EXT_MSG_CHUNKED | + EXT_MSG_DATA_SIZE_1 | + GBSDB_FIXED_BATTERY_0; + partner_send_msg(PD_MSG_SOP, PD_EXT_GET_BATTERY_STATUS, 1, 1, &ext_msg); + + /* + * f) If a Battery_Status message is not received within + * tReceiverResponse max, the test fails. This delay is measured + * from the time the last bit of Get_Battery_Status message EOP has + * been transmitted to the time the first bit of the Battery_Status + * message preamble has been received. + */ + TEST_EQ(verify_tcpci_tx_timeout(TCPC_TX_SOP, + 0, + PD_DATA_BATTERY_STATUS, + (15 * MSEC)), + EC_SUCCESS, "%d"); + mock_set_alert(TCPC_REG_ALERT_TX_SUCCESS); + task_wait_event(10 * MSEC); + + return EC_SUCCESS; +} -- cgit v1.2.1