diff options
author | Henry Sun <henrysun@google.com> | 2019-12-17 13:59:47 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-27 07:17:02 +0000 |
commit | 05763ab160f1fa395d80b7159b3d71e30e6045c5 (patch) | |
tree | ed02b006498b0eaaa0743f92ca8328b2641c2ed4 /test/usb_pd.c | |
parent | b3af8a7125cef37701af5466fd30064b1bf4ee02 (diff) | |
download | chrome-ec-05763ab160f1fa395d80b7159b3d71e30e6045c5.tar.gz |
gsctool: fast forward to cros/factory-coral-10122.B
Checkout gsctool related files from coral factory branch
git checkout cros/factory-coral-10122.B -- \
include/ util/ test/ board/cr50/ chip/g
BRANCH=reef
BUG=b:145473707
TEST=emerge-reef ec-utils
TEST=build test image with dependent changes, check gsctool was
compiled out.
Cq-Depend: chromium:1970774
Cq-Depend: chromium:1970516
Cq-Depend: chromium:1970517
Cq-Depend: chromium:1970518
Cq-Depend: chromium:1970519
Change-Id: I1b602d65b662ad25e4f46ab285894052e99949ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1970673
Reviewed-by: Henry Sun <henrysun@google.com>
Tested-by: Henry Sun <henrysun@google.com>
Commit-Queue: Henry Sun <henrysun@google.com>
Diffstat (limited to 'test/usb_pd.c')
-rw-r--r-- | test/usb_pd.c | 673 |
1 files changed, 634 insertions, 39 deletions
diff --git a/test/usb_pd.c b/test/usb_pd.c index ea68c66599..69b7448ea6 100644 --- a/test/usb_pd.c +++ b/test/usb_pd.c @@ -4,7 +4,7 @@ * * Test USB PD module. */ - +#include "battery.h" #include "common.h" #include "crc.h" #include "task.h" @@ -14,6 +14,14 @@ #include "usb_pd_test_util.h" #include "util.h" +#define PORT0 0 +#define PORT1 1 + +#define BATTERY_DESIGN_VOLTAGE 7600 +#define BATTERY_DESIGN_CAPACITY 5131 +#define BATTERY_FULL_CHARGE_CAPACITY 5131 +#define BATTERY_REMAINING_CAPACITY 2566 + struct pd_port_t { int host_mode; int has_vbus; @@ -22,9 +30,60 @@ struct pd_port_t { int polarity; int partner_role; /* -1 for none */ int partner_polarity; + int rev; } pd_port[CONFIG_USB_PD_PORT_COUNT]; +static int give_back_called; + /* Mock functions */ +#ifdef CONFIG_USB_PD_REV30 + +uint16_t pd_get_identity_vid(int port) +{ + return 0; +} + +uint16_t pd_get_identity_pid(int port) +{ + return 0; +} + +enum battery_present battery_is_present(void) +{ + return BP_YES; +} + +int battery_status(int *status) +{ + *status = 1; + return 0; +} + +int battery_remaining_capacity(int *capacity) +{ + *capacity = BATTERY_REMAINING_CAPACITY; + return 0; +} + +int battery_full_charge_capacity(int *capacity) +{ + *capacity = BATTERY_FULL_CHARGE_CAPACITY; + return 0; +} + +int battery_design_capacity(int *capacity) +{ + *capacity = BATTERY_DESIGN_CAPACITY; + return 0; +} + +int battery_design_voltage(int *voltage) +{ + *voltage = BATTERY_DESIGN_VOLTAGE; + return 0; +} + +#endif int pd_adc_read(int port, int cc) { @@ -67,6 +126,11 @@ int pd_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) return 0; } +int board_select_rp_value(int port, int rp) +{ + return 0; +} + /* Tests */ void inc_tx_id(int port) @@ -87,6 +151,11 @@ static void init_ports(void) pd_port[i].host_mode = 0; pd_port[i].partner_role = -1; pd_port[i].has_vbus = 0; +#ifdef CONFIG_USB_PD_REV30 + pd_port[i].rev = PD_REV30; +#else + pd_port[i].rev = PD_REV20; +#endif } } @@ -113,27 +182,93 @@ static void simulate_rx_msg(int port, uint16_t header, int cnt, pd_simulate_rx(port); } -static void simulate_source_cap(int port) +static void simulate_wait(int port) +{ + uint16_t header = PD_HEADER(PD_CTRL_WAIT, PD_ROLE_SOURCE, + PD_ROLE_DFP, pd_port[port].msg_rx_id, + 0, pd_port[port].rev, 0); + + simulate_rx_msg(port, header, 0, NULL); +} + +static void simulate_accept(int port) +{ + uint16_t header = PD_HEADER(PD_CTRL_ACCEPT, PD_ROLE_SOURCE, + PD_ROLE_DFP, pd_port[port].msg_rx_id, + 0, pd_port[port].rev, 0); + + simulate_rx_msg(port, header, 0, NULL); +} + +static void simulate_reject(int port) +{ + uint16_t header = PD_HEADER(PD_CTRL_REJECT, PD_ROLE_SOURCE, + PD_ROLE_DFP, pd_port[port].msg_rx_id, + 0, pd_port[port].rev, 0); + + simulate_rx_msg(port, header, 0, NULL); +} + + +#ifdef CONFIG_USB_PD_REV30 +static void simulate_get_bat_cap(int port) { + uint16_t msg[2]; + uint16_t header = PD_HEADER(PD_EXT_GET_BATTERY_CAP, PD_ROLE_SOURCE, + PD_ROLE_DFP, pd_port[port].msg_rx_id, + 1, pd_port[port].rev, 1); + + /* set extended header */ + msg[0] = PD_EXT_HEADER(0, 0, 1); + + /* set battery status ref */ + msg[1] = 0; + + simulate_rx_msg(port, header, 1, (const uint32_t *)msg); +} + +static void simulate_get_bat_status(int port) +{ + uint16_t msg[2]; + uint16_t header = PD_HEADER(PD_EXT_GET_BATTERY_STATUS, PD_ROLE_SOURCE, + PD_ROLE_DFP, pd_port[port].msg_rx_id, + 1, pd_port[port].rev, 1); + + /* set extended header */ + msg[0] = PD_EXT_HEADER(0, 0, 1); + + /* set battery status ref */ + msg[1] = 0; + + simulate_rx_msg(port, header, 1, (const uint32_t *)msg); +} +#endif + +static void simulate_source_cap(int port, uint32_t cnt) +{ + uint32_t src_pdo_cnt = (cnt == 0) ? 1 : pd_src_pdo_cnt; + uint16_t header = PD_HEADER(PD_DATA_SOURCE_CAP, PD_ROLE_SOURCE, PD_ROLE_DFP, pd_port[port].msg_rx_id, - pd_src_pdo_cnt); - simulate_rx_msg(port, header, pd_src_pdo_cnt, pd_src_pdo); + src_pdo_cnt, pd_port[port].rev, 0); + + simulate_rx_msg(port, header, 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, role, id, 0), - 0, NULL); + simulate_rx_msg(port, PD_HEADER(PD_CTRL_GOOD_CRC, role, role, id, 0, + pd_port[port].rev, 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, role, id, 0)) && - pd_test_tx_msg_verify_crc(0) && - pd_test_tx_msg_verify_eop(0); + + return pd_test_tx_msg_verify_sop(port) && + pd_test_tx_msg_verify_short(port, PD_HEADER(PD_CTRL_GOOD_CRC, + role, role, id, 0, 0, 0)) && + pd_test_tx_msg_verify_crc(port) && + pd_test_tx_msg_verify_eop(port); } static void plug_in_source(int port, int polarity) @@ -152,74 +287,531 @@ static void plug_in_sink(int port, int polarity) static void unplug(int port) { + pd_port[port].msg_tx_id = 0; + pd_port[port].msg_rx_id = 0; pd_port[port].has_vbus = 0; pd_port[port].partner_role = -1; task_wake(PD_PORT_TO_TASK_ID(port)); usleep(30 * MSEC); } -static int test_request(void) +void pd_snk_give_back(int port, uint32_t * const ma, uint32_t * const mv) +{ + if (*ma == 3000) + give_back_called = 1; +} + +static void simulate_ps_rdy(int port) +{ + uint16_t header = PD_HEADER(PD_CTRL_PS_RDY, PD_ROLE_SOURCE, + PD_ROLE_DFP, pd_port[port].msg_rx_id, + 0, pd_port[port].rev, 0); + + simulate_rx_msg(port, header, 0, NULL); +} + +static void simulate_goto_min(int port) +{ + uint16_t header = PD_HEADER(PD_CTRL_GOTO_MIN, PD_ROLE_SOURCE, + PD_ROLE_DFP, pd_port[port].msg_rx_id, 0, pd_port[port].rev, 0); + + simulate_rx_msg(port, header, 0, NULL); +} + +static int test_request_with_wait_and_contract(void) { +#ifdef CONFIG_USB_PD_REV30 + uint32_t expected_status_bsdo = + BSDO_CAP(DIV_ROUND_NEAREST(BATTERY_REMAINING_CAPACITY * + BATTERY_DESIGN_VOLTAGE, 100000)) | + BSDO_PRESENT; + uint16_t expected_cap_hdr = PD_EXT_HEADER(0, 0, 9); + uint16_t expected_cap_vid = USB_VID_GOOGLE; +#ifdef CONFIG_USB_PID + uint16_t expected_cap_pid = CONFIG_USB_PID; +#else + uint16_t expected_cap_pid = 0; +#endif + uint16_t expected_cap_des = + DIV_ROUND_NEAREST(BATTERY_DESIGN_CAPACITY * + BATTERY_DESIGN_VOLTAGE, 100000); + uint16_t expected_cap_ful = + DIV_ROUND_NEAREST(BATTERY_FULL_CHARGE_CAPACITY * + BATTERY_DESIGN_VOLTAGE, 100000); + uint16_t expected_cap_type = 0; +#endif + +#ifdef CONFIG_USB_PD_GIVE_BACK + uint32_t expected_rdo = + RDO_FIXED(2, 3000, PD_MIN_CURRENT_MA, RDO_GIVE_BACK); +#else + uint32_t expected_rdo = RDO_FIXED(2, 3000, 3000, 0); +#endif + uint8_t port = PORT0; + + plug_in_source(port, 0); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(2 * PD_T_CC_DEBOUNCE + 100 * MSEC); + TEST_ASSERT(pd_port[port].polarity == 0); + + /* We're in SNK_DISCOVERY now. Let's send the source cap. */ + simulate_source_cap(port, 1); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(port, PD_ROLE_SINK, + pd_port[port].msg_rx_id)); + + /* Wait for the power request */ + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ + inc_rx_id(port); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 1, pd_port[port].rev, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_rdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request was good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_tx_id(port); + + /* We're in SNK_REQUESTED. Send accept */ + simulate_accept(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_rx_id(port); + + /* + * We're in SNK_TRANSITION. + * And we have an explicit power contract. + */ + simulate_source_cap(port, 1); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(port, PD_ROLE_SINK, + pd_port[port].msg_rx_id)); + + /* Wait for the power request */ + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ + inc_rx_id(port); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 1, pd_port[port].rev, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_rdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request was good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_tx_id(port); + + /* We're in SNK_REQUESTED. Send wait */ + simulate_wait(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + /* PD_T_SINK_REQUEST. Request is sent again after 100 ms */ + task_wait_event(100 * MSEC); + inc_rx_id(port); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* We had an explicit contract. So request should have been resent. */ + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 1, + pd_port[port].rev, 0 + ))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_rdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request was good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_tx_id(port); + + /* We're in SNK_REQUESTED. Send accept */ + simulate_accept(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_rx_id(port); + + /* We're in SNK_TRANSITION. Send ps_rdy */ + simulate_ps_rdy(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_rx_id(port); + + /* + * Test Extended Get_Battery_Cap and Get_Battery_Status messages. + */ +#ifdef CONFIG_USB_PD_REV30 + /* We're in SNK_READY. Send get battery cap. */ + simulate_get_bat_cap(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_rx_id(port); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_EXT_BATTERY_CAP, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 3, pd_port[port].rev, 1))); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, expected_cap_hdr)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, expected_cap_vid)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, expected_cap_pid)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, expected_cap_des)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, expected_cap_ful)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, expected_cap_type)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request was good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_tx_id(port); + + /* Send get battery status. */ + simulate_get_bat_status(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_rx_id(port); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_DATA_BATTERY_STATUS, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 1, pd_port[port].rev, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_status_bsdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request was good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_tx_id(port); +#endif + /* We're in SNK_READY. Send goto_min */ + simulate_goto_min(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_rx_id(port); + +#ifdef CONFIG_USB_PD_GIVE_BACK + TEST_ASSERT(give_back_called); +#else + TEST_ASSERT(!give_back_called); +#endif + /* We're done */ + unplug(port); + + return EC_SUCCESS; +} + +static int test_request_with_wait(void) +{ +#ifdef CONFIG_USB_PD_GIVE_BACK + uint32_t expected_rdo = RDO_FIXED(1, 900, PD_MIN_CURRENT_MA, + RDO_CAP_MISMATCH | RDO_GIVE_BACK); +#else uint32_t expected_rdo = RDO_FIXED(1, 900, 900, RDO_CAP_MISMATCH); +#endif + uint8_t port = PORT0; + + plug_in_source(port, 0); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(2 * PD_T_CC_DEBOUNCE + 100 * MSEC); + TEST_ASSERT(pd_port[port].polarity == 0); + + /* We're in SNK_DISCOVERY now. Let's send the source cap. */ + simulate_source_cap(port, 0); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(port, + PD_ROLE_SINK, pd_port[port].msg_rx_id)); - plug_in_source(0, 0); + /* Wait for the power request */ + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ + inc_rx_id(port); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 1, pd_port[port].rev, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_rdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request is good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); task_wake(PD_PORT_TO_TASK_ID(0)); + task_wait_event(30 * MSEC); + inc_tx_id(port); + + /* We're in SNK_REQUESTED. Send wait */ + simulate_wait(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_rx_id(port); + + /* We didn't have an explicit contract. So we're in SNK_DISCOVERY. */ + /* Resend Source Cap. */ + simulate_source_cap(port, 0); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(port, + PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + /* Wait for the power request */ + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ + inc_rx_id(port); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 1, pd_port[port].rev, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_rdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request was good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_tx_id(port); + + /* We're done */ + unplug(port); + return EC_SUCCESS; +} + +static int test_request_with_reject(void) +{ +#ifdef CONFIG_USB_PD_GIVE_BACK + uint32_t expected_rdo = RDO_FIXED(1, 900, PD_MIN_CURRENT_MA, + RDO_CAP_MISMATCH | RDO_GIVE_BACK); +#else + uint32_t expected_rdo = RDO_FIXED(1, 900, 900, RDO_CAP_MISMATCH); +#endif + uint8_t port = PORT0; + + plug_in_source(port, 0); + task_wake(PD_PORT_TO_TASK_ID(port)); task_wait_event(2 * PD_T_CC_DEBOUNCE + 100 * MSEC); - TEST_ASSERT(pd_port[0].polarity == 0); + TEST_ASSERT(pd_port[port].polarity == 0); /* We're in SNK_DISCOVERY now. Let's send the source cap. */ - simulate_source_cap(0); + simulate_source_cap(port, 0); task_wait_event(30 * MSEC); - TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[0].msg_rx_id)); + TEST_ASSERT(verify_goodcrc(port, + PD_ROLE_SINK, pd_port[port].msg_rx_id)); /* Wait for the power request */ + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ + inc_rx_id(port); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 1, pd_port[port].rev, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_rdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request is good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); task_wake(PD_PORT_TO_TASK_ID(0)); + task_wait_event(30 * MSEC); + inc_tx_id(port); + + /* We're in SNK_REQUESTED. Send reject */ + simulate_reject(port); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_rx_id(port); + + /* We're in SNK_READY. Send source cap. again. */ + simulate_source_cap(port, 0); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(port, + PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + /* Wait for the power request */ + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ + inc_rx_id(port); + + /* Process the request */ + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, + PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, + pd_port[port].msg_tx_id, 1, pd_port[port].rev, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_rdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + /* We're done */ + unplug(port); + return EC_SUCCESS; +} + +static int test_request(void) +{ +#ifdef CONFIG_USB_PD_GIVE_BACK + uint32_t expected_rdo = RDO_FIXED(1, 900, PD_MIN_CURRENT_MA, + RDO_CAP_MISMATCH | RDO_GIVE_BACK); +#else + uint32_t expected_rdo = RDO_FIXED(1, 900, 900, RDO_CAP_MISMATCH); +#endif + uint8_t port = PORT0; + + plug_in_source(port, 0); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(2 * PD_T_CC_DEBOUNCE + 100 * MSEC); + TEST_ASSERT(pd_port[port].polarity == 0); + + /* We're in SNK_DISCOVERY now. Let's send the source cap. */ + simulate_source_cap(port, 0); + task_wait_event(30 * MSEC); + TEST_ASSERT(verify_goodcrc(port, + PD_ROLE_SINK, pd_port[port].msg_rx_id)); + + /* Wait for the power request */ + task_wake(PD_PORT_TO_TASK_ID(port)); task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ - inc_rx_id(0); + inc_rx_id(port); /* Process the request */ - TEST_ASSERT(pd_test_tx_msg_verify_sop(0)); - TEST_ASSERT(pd_test_tx_msg_verify_short(0, + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, - pd_port[0].msg_tx_id, 1))); - TEST_ASSERT(pd_test_tx_msg_verify_word(0, expected_rdo)); - TEST_ASSERT(pd_test_tx_msg_verify_crc(0)); - TEST_ASSERT(pd_test_tx_msg_verify_eop(0)); - inc_tx_id(0); + pd_port[port].msg_tx_id, 1, pd_port[port].rev, 0))); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, expected_rdo)); + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + + /* Request was good. Send GoodCRC */ + simulate_goodcrc(port, PD_ROLE_SOURCE, pd_port[port].msg_tx_id); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(30 * MSEC); + inc_tx_id(port); /* We're done */ - unplug(0); + unplug(port); + return EC_SUCCESS; } static int test_sink(void) { int i; + uint8_t port = PORT1; - plug_in_sink(1, 1); - task_wake(PD_PORT_TO_TASK_ID(1)); + plug_in_sink(port, 1); + task_wake(PD_PORT_TO_TASK_ID(port)); task_wait_event(250 * MSEC); /* tTypeCSinkWaitCap: 210~250 ms */ - TEST_ASSERT(pd_port[1].polarity == 1); + TEST_ASSERT(pd_port[port].polarity == 1); /* The source cap should be sent */ - TEST_ASSERT(pd_test_tx_msg_verify_sop(1)); - TEST_ASSERT(pd_test_tx_msg_verify_short(1, + TEST_ASSERT(pd_test_tx_msg_verify_sop(port)); + TEST_ASSERT(pd_test_tx_msg_verify_short(port, PD_HEADER(PD_DATA_SOURCE_CAP, PD_ROLE_SOURCE, - PD_ROLE_DFP, pd_port[1].msg_tx_id, - pd_src_pdo_cnt))); + PD_ROLE_DFP, pd_port[port].msg_tx_id, + pd_src_pdo_cnt, pd_port[port].rev, 0))); + 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)); + TEST_ASSERT(pd_test_tx_msg_verify_word(port, pd_src_pdo[i])); + + TEST_ASSERT(pd_test_tx_msg_verify_crc(port)); + TEST_ASSERT(pd_test_tx_msg_verify_eop(port)); + + /* Wake from pd_start_tx */ + task_wake(PD_PORT_TO_TASK_ID(port)); + usleep(30 * MSEC); /* Looks good. Ack the source cap. */ - simulate_goodcrc(1, PD_ROLE_SINK, pd_port[1].msg_tx_id); - task_wake(PD_PORT_TO_TASK_ID(1)); + simulate_goodcrc(port, PD_ROLE_SINK, pd_port[port].msg_tx_id); + + /* Wake from pd_rx_start */ + task_wake(PD_PORT_TO_TASK_ID(port)); usleep(30 * MSEC); - inc_tx_id(1); + inc_tx_id(port); /* We're done */ - unplug(1); + unplug(port); return EC_SUCCESS; } @@ -231,6 +823,9 @@ void run_test(void) RUN_TEST(test_request); RUN_TEST(test_sink); + RUN_TEST(test_request_with_wait); + RUN_TEST(test_request_with_wait_and_contract); + RUN_TEST(test_request_with_reject); test_print_result(); } |