summaryrefslogtreecommitdiff
path: root/test/usb_pd.c
diff options
context:
space:
mode:
authorHenry Sun <henrysun@google.com>2019-12-17 13:59:47 +0800
committerCommit Bot <commit-bot@chromium.org>2020-05-27 07:17:02 +0000
commit05763ab160f1fa395d80b7159b3d71e30e6045c5 (patch)
treeed02b006498b0eaaa0743f92ca8328b2641c2ed4 /test/usb_pd.c
parentb3af8a7125cef37701af5466fd30064b1bf4ee02 (diff)
downloadchrome-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.c673
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();
}