summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/host/task.c5
-rw-r--r--test/usb_prl.c222
-rw-r--r--test/usb_typec_ctvpd.c8
3 files changed, 145 insertions, 90 deletions
diff --git a/core/host/task.c b/core/host/task.c
index d004698ed7..b6ab778b60 100644
--- a/core/host/task.c
+++ b/core/host/task.c
@@ -206,6 +206,11 @@ uint32_t task_set_event(task_id_t tskid, uint32_t event, int wait)
return 0;
}
+uint32_t *task_get_event_bitmap(task_id_t tskid)
+{
+ return &tasks[tskid].event;
+}
+
uint32_t task_wait_event(int timeout_us)
{
int tid = task_get_current();
diff --git a/test/usb_prl.c b/test/usb_prl.c
index d1cbaf5a94..308117493b 100644
--- a/test/usb_prl.c
+++ b/test/usb_prl.c
@@ -122,6 +122,11 @@ static void init_port(int port, int rev)
tcpm_set_rx_enable(port, 0);
}
+static inline uint32_t pending_pd_task_events(int port)
+{
+ return *task_get_event_bitmap(PD_PORT_TO_TASK_ID(port));
+}
+
void inc_tx_id(int port)
{
pd_port[port].msg_tx_id = (pd_port[port].msg_tx_id + 1) & 7;
@@ -179,6 +184,12 @@ static void cycle_through_state_machine(int port, uint32_t num, uint32_t time)
for (i = 0; i < num; i++) {
task_wake(PD_PORT_TO_TASK_ID(port));
task_wait_event(time);
+ /*
+ * Ensure that the PD task actually ran otherwise loop again.
+ * This can happen for slow/overloaded cpus (e.g. cq machine).
+ */
+ if (TASK_EVENT_WAKE & pending_pd_task_events(port))
+ --i;
}
}
@@ -255,21 +266,32 @@ static int verify_chunk_data_reception(int port, uint16_t header, int len)
int i;
uint8_t *td = (uint8_t *)test_data;
- if (pd_port[port].mock_got_soft_reset)
+ if (pd_port[port].mock_got_soft_reset) {
+ ccprintf("Got mock soft reset\n");
return 0;
+ }
- if (!pd_port[port].mock_pe_message_received)
+ if (!pd_port[port].mock_pe_message_received) {
+ ccprintf("No mock pe msg received\n");
return 0;
+ }
- if (pd_port[port].mock_pe_error >= 0)
+ if (pd_port[port].mock_pe_error >= 0) {
+ ccprintf("Mock pe error (%d)\n", pd_port[port].mock_pe_error);
return 0;
+ }
- if (emsg[port].len != len)
+ if (emsg[port].len != len) {
+ ccprintf("emsg len (%d) != 0\n", emsg[port].len);
return 0;
+ }
- for (i = 0; i < len; i++)
- if (emsg[port].buf[i] != td[i])
+ for (i = 0; i < len; i++) {
+ if (emsg[port].buf[i] != td[i]) {
+ ccprintf("emsg buf[%d] != td\n", i);
return 0;
+ }
+ }
return 1;
}
@@ -322,7 +344,6 @@ static int simulate_receive_extended_data(int port,
int data_offset = 0;
uint8_t *expected_data = (uint8_t *)test_data;
uint16_t header;
- int req_timeout;
pd_port[port].mock_pe_error = -1;
pd_port[port].mock_pe_message_received = 0;
@@ -331,10 +352,10 @@ static int simulate_receive_extended_data(int port,
memset(emsg[port].buf, 0, 260);
dsize = len;
-
- cycle_through_state_machine(port, 2, 40 * MSEC);
-
for (j = 0; j < 10; j++) {
+ /* Let state machine settle before starting another round */
+ cycle_through_state_machine(port, 10, MSEC);
+
byte_len = len;
if (byte_len > 26)
byte_len = 26;
@@ -352,26 +373,33 @@ static int simulate_receive_extended_data(int port,
pd_port[port].data_role, pd_port[port].msg_rx_id,
nw, pd_port[port].rev, 1);
- cycle_through_state_machine(port, 2, 40 * MSEC);
-
- if (pd_port[port].mock_pe_error >= 0)
+ if (pd_port[port].mock_pe_error >= 0) {
+ ccprintf("Mock pe error (%d) iteration (%d)\n",
+ pd_port[port].mock_pe_error, j);
return 0;
+ }
- if (pd_port[port].mock_pe_message_received)
+ if (pd_port[port].mock_pe_message_received) {
+ ccprintf("Mock pe msg received iteration (%d)\n", j);
return 0;
+ }
- if (emsg[port].len != 0)
+ if (emsg[port].len != 0) {
+ ccprintf("emsg len (%d) != 0 iteration (%d)\n",
+ emsg[port].len, j);
return 0;
+ }
simulate_rx_msg(port, header, nw, (uint32_t *)td);
- task_wait_event(40 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
if (!verify_goodcrc(port, pd_port[port].data_role,
- pd_port[port].msg_rx_id))
+ pd_port[port].msg_rx_id)) {
+ ccprintf("Verify goodcrc bad iteration (%d)\n", j);
return 0;
+ }
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40);
+ cycle_through_state_machine(port, 1, MSEC);
inc_rx_id(port);
/*
@@ -381,52 +409,58 @@ static int simulate_receive_extended_data(int port,
break;
/*
- * Wait for request chunk message
+ * We need to ensure that the TX event has been set, which may
+ * require an extra cycle through the state machine
*/
- req_timeout = 0;
- while (rch_get_state(port) != RCH_REQUESTING_CHUNK &&
- req_timeout < 5) {
- req_timeout++;
- msleep(2);
- }
+ if (!(PD_EVENT_TX & pending_pd_task_events(port)))
+ cycle_through_state_machine(port, 1, MSEC);
chunk_num++;
/* Test Request next chunk packet */
- if (!pd_test_tx_msg_verify_sop(port))
+ if (!pd_test_tx_msg_verify_sop(port)) {
+ ccprintf("Verify sop bad iteration (%d)\n", j);
return 0;
+ }
if (!pd_test_tx_msg_verify_short(port,
PD_HEADER(msg_type,
pd_port[port].power_role,
pd_port[port].data_role,
pd_port[port].msg_tx_id,
- 1, pd_port[port].rev, 1)))
+ 1, pd_port[port].rev, 1))) {
+ ccprintf("Verify msg short bad iteration (%d)\n", j);
return 0;
+ }
if (!pd_test_tx_msg_verify_word(port,
- PD_EXT_HEADER(chunk_num, 1, 0)))
+ PD_EXT_HEADER(chunk_num, 1, 0))) {
+ ccprintf("Verify msg word bad iteration (%d)\n", j);
return 0;
+ }
- if (!pd_test_tx_msg_verify_crc(port))
+ if (!pd_test_tx_msg_verify_crc(port)) {
+ ccprintf("Verify msg crc bad iteration (%d)\n", j);
return 0;
+ }
- if (!pd_test_tx_msg_verify_eop(port))
+ if (!pd_test_tx_msg_verify_eop(port)) {
+ ccprintf("Verify msg eop bad iteration (%d)\n", j);
return 0;
+ }
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
/* Request next chunk packet was good. Send GoodCRC */
simulate_goodcrc(port, pd_port[port].power_role,
pd_port[port].msg_tx_id);
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40 * MSEC);
+
+ cycle_through_state_machine(port, 1, MSEC);
+
inc_tx_id(port);
}
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(20 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
return verify_chunk_data_reception(port, header, dsize);
}
@@ -459,10 +493,11 @@ static int simulate_send_ctrl_msg_request_from_pe(int port,
pd_port[port].mock_pe_error = -1;
pd_port[port].mock_pe_message_sent = 0;
prl_send_ctrl_msg(port, type, msg_type);
- task_wait_event(40 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
+ /* Soft reset takes another iteration through the state machine */
if (msg_type == PD_CTRL_SOFT_RESET)
- cycle_through_state_machine(port, 1, 20 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
return verify_ctrl_msg_transmission(port, msg_type);
}
@@ -531,7 +566,7 @@ static int simulate_send_data_msg_request_from_pe(int port,
emsg[port].len = len;
prl_send_data_msg(port, type, msg_type);
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
return verify_data_msg_transmission(port, msg_type, len);
}
@@ -558,15 +593,19 @@ static int verify_extended_data_msg_transmission(int port,
nw = (byte_len + 2 + 3) >> 2;
- if (!pd_test_tx_msg_verify_sop(port))
+ if (!pd_test_tx_msg_verify_sop(port)) {
+ ccprintf("failed tx sop; iteration (%d)\n", j);
return 0;
+ }
if (!pd_test_tx_msg_verify_short(port,
PD_HEADER(msg_type, pd_port[port].power_role,
pd_port[port].data_role,
pd_port[port].msg_tx_id,
- nw, pd_port[port].rev, 1)))
+ nw, pd_port[port].rev, 1))) {
+ ccprintf("failed tx short\n");
return 0;
+ }
td = PD_EXT_HEADER(chunk_number_to_send, 0, dsize);
td |= *(expected_data + data_offset++) << 16;
td |= *(expected_data + data_offset++) << 24;
@@ -574,8 +613,10 @@ static int verify_extended_data_msg_transmission(int port,
if (byte_len == 1)
td &= 0x00ffffff;
- if (!pd_test_tx_msg_verify_word(port, td))
+ if (!pd_test_tx_msg_verify_word(port, td)) {
+ ccprintf("failed tx word\n");
return 0;
+ }
byte_len -= 2;
@@ -605,20 +646,22 @@ static int verify_extended_data_msg_transmission(int port,
}
}
- if (!pd_test_tx_msg_verify_crc(port))
+ if (!pd_test_tx_msg_verify_crc(port)) {
+ ccprintf("failed tx crc\n");
return 0;
+ }
- if (!pd_test_tx_msg_verify_eop(port))
+ if (!pd_test_tx_msg_verify_eop(port)) {
+ ccprintf("failed tx eop\n");
return 0;
+ }
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(10 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
/* Send GoodCRC */
simulate_goodcrc(port, pd_port[port].power_role,
pd_port[port].msg_tx_id);
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
inc_tx_id(port);
len -= 26;
@@ -626,13 +669,15 @@ static int verify_extended_data_msg_transmission(int port,
break;
chunk_number_to_send++;
- cycle_through_state_machine(port, 4, 10 * MSEC);
+ /* Let state machine settle */
+ cycle_through_state_machine(port, 10, MSEC);
if (!simulate_request_chunk(port, msg_type,
- chunk_number_to_send, dsize))
+ chunk_number_to_send, dsize)) {
+ ccprintf("failed request chunk\n");
return 0;
+ }
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
inc_rx_id(port);
}
@@ -658,7 +703,7 @@ static int simulate_send_extended_data_msg(int port,
buf[i] = td[i];
prl_send_ext_data_msg(port, type, msg_type);
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
return verify_extended_data_msg_transmission(port, msg_type,
len);
@@ -673,11 +718,7 @@ static void enable_prl(int port, int en)
pd_port[port].msg_rx_id = 0;
/* Init PRL */
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(10 * MSEC);
-
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(10 * MSEC);
+ cycle_through_state_machine(port, 10, MSEC);
prl_set_rev(port, pd_port[port].rev);
}
@@ -763,14 +804,14 @@ static int test_send_ctrl_msg(void)
TEST_ASSERT(simulate_send_ctrl_msg_request_from_pe(port,
TCPC_TX_SOP, PD_CTRL_ACCEPT));
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
simulate_goodcrc(port, pd_port[port].power_role,
pd_port[port].msg_tx_id);
inc_tx_id(port);
- cycle_through_state_machine(port, 3, 10 * MSEC);
+ /* Let statemachine settle */
+ cycle_through_state_machine(port, 10, MSEC);
TEST_ASSERT(!pd_port[port].mock_got_soft_reset);
TEST_ASSERT(pd_port[port].mock_pe_message_sent);
@@ -793,7 +834,7 @@ static int test_send_ctrl_msg_with_retry_and_fail(void)
* TEST: Control message transmission fail with retry
*/
task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40 * MSEC);
+ task_wait_event(MSEC);
TEST_ASSERT(prl_tx_get_state(port) ==
PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
@@ -801,34 +842,32 @@ static int test_send_ctrl_msg_with_retry_and_fail(void)
TEST_ASSERT(simulate_send_ctrl_msg_request_from_pe(port,
TCPC_TX_SOP, PD_CTRL_ACCEPT));
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
simulate_goodcrc(port, pd_port[port].power_role,
pd_port[port].msg_tx_id);
/* Do not increment tx_id so phy layer will not transmit message */
- cycle_through_state_machine(port, 3, 10 * MSEC);
+ /* Let statemachine settle */
+ cycle_through_state_machine(port, 10, MSEC);
TEST_ASSERT(!pd_port[port].mock_got_soft_reset);
TEST_ASSERT(pd_port[port].mock_pe_message_sent);
task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40 * MSEC);
+ task_wait_event(MSEC);
TEST_ASSERT(prl_tx_get_state(port) ==
PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
pd_port[port].mock_pe_message_sent = 0;
prl_send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_ACCEPT);
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
for (i = 0; i < N_RETRY_COUNT + 1; i++) {
- cycle_through_state_machine(port, 10, 10 * MSEC);
-
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(PD_T_TCPC_TX_TIMEOUT);
+ /* Ensure that we have timed out */
+ cycle_through_state_machine(port, 10, 100 * MSEC);
TEST_ASSERT(!pd_port[port].mock_got_soft_reset);
TEST_ASSERT(pd_port[port].mock_pe_message_sent == 0);
@@ -854,8 +893,6 @@ static int test_send_ctrl_msg_with_retry_and_success(void)
/*
* TEST: Control message transmission fail with retry
*/
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40 * MSEC);
TEST_ASSERT(prl_tx_get_state(port) ==
PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
@@ -929,8 +966,7 @@ static int test_send_data_msg(void)
* TEST: Sending data message with 1 to 28 bytes
*/
for (i = 1; i <= 28; i++) {
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
TEST_ASSERT(prl_tx_get_state(port) ==
PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
@@ -938,14 +974,13 @@ static int test_send_data_msg(void)
TEST_ASSERT(simulate_send_data_msg_request_from_pe(port,
TCPC_TX_SOP, PD_DATA_SOURCE_CAP, i));
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(30 * MSEC);
+ cycle_through_state_machine(port, 1, MSEC);
simulate_goodcrc(port, pd_port[port].power_role,
pd_port[port].msg_tx_id);
inc_tx_id(port);
- cycle_through_state_machine(port, 3, 10 * MSEC);
+ cycle_through_state_machine(port, 10, MSEC);
TEST_ASSERT(!pd_port[port].mock_got_soft_reset);
TEST_ASSERT(pd_port[port].mock_pe_message_sent);
@@ -979,7 +1014,7 @@ static int test_send_data_msg_to_much_data(void)
task_wake(PD_PORT_TO_TASK_ID(port));
task_wait_event(30 * MSEC);
- cycle_through_state_machine(port, 3, 10 * MSEC);
+ cycle_through_state_machine(port, 10, MSEC);
TEST_ASSERT(!pd_port[port].mock_got_soft_reset);
TEST_ASSERT(!pd_port[port].mock_pe_message_sent);
@@ -1004,11 +1039,12 @@ static int test_send_extended_data_msg(void)
pd_port[port].mock_got_soft_reset = 0;
pd_port[port].mock_pe_error = -1;
+ ccprintf("Iteration ");
for (i = 29; i <= 260; i++) {
+ ccprintf(".%d", i);
pd_port[port].mock_pe_message_sent = 0;
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40 * MSEC);
+ cycle_through_state_machine(port, 10, MSEC);
TEST_ASSERT(prl_tx_get_state(port) ==
PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
@@ -1016,10 +1052,7 @@ static int test_send_extended_data_msg(void)
TEST_ASSERT(simulate_send_extended_data_msg(
port, TCPC_TX_SOP, PD_EXT_MANUFACTURER_INFO, i));
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(30 * MSEC);
-
- cycle_through_state_machine(port, 3, 10 * MSEC);
+ cycle_through_state_machine(port, 10, MSEC);
TEST_ASSERT(!pd_port[port].mock_got_soft_reset);
TEST_ASSERT(pd_port[port].mock_pe_message_sent);
@@ -1060,7 +1093,7 @@ static int test_receive_soft_reset_msg(void)
task_wake(PD_PORT_TO_TASK_ID(port));
task_wait_event(30 * MSEC);
- cycle_through_state_machine(port, 3, 10 * MSEC);
+ cycle_through_state_machine(port, 10, MSEC);
TEST_ASSERT(pd_port[port].mock_got_soft_reset);
TEST_ASSERT(pd_port[port].mock_pe_error < 0);
@@ -1317,6 +1350,21 @@ int pd_task(void *u)
return EC_SUCCESS;
}
+/* Reset the state machine between each test */
+void before_test(void)
+{
+ pd_port[PORT0].mock_pe_message_sent = 0;
+ pd_port[PORT0].mock_pe_error = -1;
+ pd_port[PORT0].mock_pe_hard_reset_sent = 0;
+ pd_port[PORT0].mock_pe_got_hard_reset = 0;
+ pd_port[PORT0].mock_pe_message_received = 0;
+ pd_port[PORT0].mock_got_soft_reset = 0;
+ pd_port[PORT0].pd_enable = false;
+ cycle_through_state_machine(PORT0, 10, MSEC);
+ pd_port[PORT0].pd_enable = true;
+ cycle_through_state_machine(PORT0, 10, MSEC);
+}
+
void run_test(void)
{
test_reset();
diff --git a/test/usb_typec_ctvpd.c b/test/usb_typec_ctvpd.c
index 8c8b5e3897..61fc64f9b9 100644
--- a/test/usb_typec_ctvpd.c
+++ b/test/usb_typec_ctvpd.c
@@ -76,8 +76,10 @@ uint64_t wait_for_state_change(int port, uint64_t timeout)
wait = get_time().val + timeout;
start = get_time().val;
- while (get_state_tc(port) == state && get_time().val < wait)
+ while (get_state_tc(port) == state && get_time().val < wait) {
+ task_wake(PD_PORT_TO_TASK_ID(port));
task_wait_event(5 * MSEC);
+ }
return get_time().val - start;
}
@@ -635,9 +637,9 @@ static int test_vpd_host_src_detection_message_reception(void)
host_connect_source(VBUS_0);
- wait_for_state_change(port, 10 * MSEC);
+ wait_for_state_change(port, 100 * MSEC);
- TEST_ASSERT(get_state_tc(port) == TC_UNATTACHED_SNK);
+ TEST_EQ(get_state_tc(port), TC_UNATTACHED_SNK, "%d");
host_disconnect_source();