summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@chromium.org>2019-10-14 14:06:05 -0600
committerCommit Bot <commit-bot@chromium.org>2019-10-16 08:42:19 +0000
commit7a4e700b6488a138d0c5c55aaa47e626d90a5299 (patch)
tree7df9a085eed09ffbcff37b4c8a09c71b5e9af0ca
parent2dd2eecaa743a65d8369c7799bbc1450b0d91d0e (diff)
downloadchrome-ec-7a4e700b6488a138d0c5c55aaa47e626d90a5299.tar.gz
pd: Add PE FRS unit test for new stack
BUG=none BRANCH=none TEST=make buildall -j Change-Id: I55453ddf1d1da0fdee902a33e14357716fb12c4a Signed-off-by: Denis Brockus <dbrockus@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1859826 Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--common/usbc/build.mk1
-rw-r--r--common/usbc/usb_pe_drp_sm.c29
-rw-r--r--include/config.h6
-rw-r--r--include/usb_prl_sm.h7
-rw-r--r--test/build.mk3
-rw-r--r--test/fake_battery.c42
-rw-r--r--test/fake_prl.c60
-rw-r--r--test/fake_usbc.c116
-rw-r--r--test/test_config.h13
-rw-r--r--test/usb_pe.h133
-rw-r--r--test/usb_pe_drp.c134
-rw-r--r--test/usb_pe_drp.tasklist9
12 files changed, 551 insertions, 2 deletions
diff --git a/common/usbc/build.mk b/common/usbc/build.mk
index fea97cde43..69e540ed67 100644
--- a/common/usbc/build.mk
+++ b/common/usbc/build.mk
@@ -15,6 +15,7 @@ ifneq ($(CONFIG_USB_PE_SM),)
all-obj-$(CONFIG_USB_TYPEC_VPD)+=$(_usbc_dir)usb_pe_ctvpd_sm.o
all-obj-$(CONFIG_USB_TYPEC_CTVPD)+=$(_usbc_dir)usb_pe_ctvpd_sm.o
all-obj-$(CONFIG_USB_TYPEC_DRP_ACC_TRYSRC)+=$(_usbc_dir)usb_pe_drp_sm.o
+all-obj-$(CONFIG_TEST_USB_PE_SM)+=$(_usbc_dir)usb_pe_drp_sm.o
endif
all-obj-$(CONFIG_USB_TYPEC_VPD)+=$(_usbc_dir)usb_tc_vpd_sm.o
all-obj-$(CONFIG_USB_TYPEC_CTVPD)+=$(_usbc_dir)usb_tc_ctvpd_sm.o
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index abd5e5bb6b..fc1fb2353e 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -437,7 +437,8 @@ static struct svdm_amode_data *get_modep(int port, uint16_t svid);
#endif
test_export_static enum usb_pe_state get_state_pe(const int port);
-static void set_state_pe(const int port, const enum usb_pe_state new_state);
+test_export_static void set_state_pe(const int port,
+ const enum usb_pe_state new_state);
static void pe_init(int port)
{
@@ -730,7 +731,8 @@ void pe_exit_dp_mode(int port)
*/
/* Set the TypeC state machine to a new state. */
-static void set_state_pe(const int port, const enum usb_pe_state new_state)
+test_export_static void set_state_pe(const int port,
+ const enum usb_pe_state new_state)
{
set_state(port, &pe[port].ctx, &pe_states[new_state]);
}
@@ -3384,6 +3386,7 @@ static void pe_do_port_discovery_entry(int port)
static void pe_do_port_discovery_run(int port)
{
+#ifdef CONFIG_USB_PD_ALT_MODE_DFP
uint32_t *payload = (uint32_t *)emsg[port].buf;
struct svdm_amode_data *modep = get_modep(port, PD_VDO_VID(payload[0]));
int ret = 0;
@@ -3473,6 +3476,7 @@ static void pe_do_port_discovery_run(int port)
pe[port].vdm_cnt = ret;
set_state_pe(port, PE_VDM_REQUEST);
}
+#endif
}
/**
@@ -5138,4 +5142,25 @@ const struct test_sm_data test_pe_sm_data[] = {
},
};
const int test_pe_sm_data_size = ARRAY_SIZE(test_pe_sm_data);
+
+void pe_set_flag(int port, int flag)
+{
+ PE_SET_FLAG(port, flag);
+}
+void pe_clr_flag(int port, int flag)
+{
+ PE_CLR_FLAG(port, flag);
+}
+int pe_chk_flag(int port, int flag)
+{
+ return PE_CHK_FLAG(port, flag);
+}
+int pe_get_all_flags(int port)
+{
+ return pe[port].flags;
+}
+void pe_set_all_flags(int port, int flags)
+{
+ pe[port].flags = flags;
+}
#endif
diff --git a/include/config.h b/include/config.h
index 0c738e8a3c..9ecd19abbb 100644
--- a/include/config.h
+++ b/include/config.h
@@ -925,6 +925,12 @@
#define CONFIG_USB_PE_SM
/*
+ * Define to enable Policy Engine State Machine. This is an override
+ * that is used to just pull in PE for unit testing.
+ */
+#undef CONFIG_TEST_USB_PE_SM
+
+/*
* Board specific maximum input current limit, in mA.
*/
#undef CONFIG_CHARGER_MAX_INPUT_CURRENT
diff --git a/include/usb_prl_sm.h b/include/usb_prl_sm.h
index 694d4fd923..7f580741e5 100644
--- a/include/usb_prl_sm.h
+++ b/include/usb_prl_sm.h
@@ -121,5 +121,12 @@ void prl_start_ams(int port);
*/
void prl_end_ams(int port);
+#ifdef TEST_BUILD
+/**
+ * Fake to track the last sent control message
+ */
+enum pd_ctrl_msg_type fake_prl_get_last_sent_ctrl_msg(int port);
+#endif
+
#endif /* __CROS_EC_USB_PRL_H */
diff --git a/test/build.mk b/test/build.mk
index e9a7f53648..f4f2d5d44b 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -80,6 +80,7 @@ test-list-host += usb_typec_vpd
test-list-host += usb_typec_ctvpd
test-list-host += usb_typec_drp_acc_trysrc
test-list-host += usb_prl
+test-list-host += usb_pe_drp
test-list-host += utils
test-list-host += utils_str
test-list-host += vboot
@@ -158,6 +159,8 @@ usb_typec_ctvpd-y=usb_typec_ctvpd.o vpd_api.o usb_sm_checks.o
usb_typec_drp_acc_trysrc-y=usb_typec_drp_acc_trysrc.o vpd_api.o \
usb_sm_checks.o
usb_prl-y=usb_prl.o usb_sm_checks.o
+usb_pe_drp-y=usb_pe_drp.o usb_sm_checks.o \
+ fake_battery.o fake_prl.o fake_usbc.o
utils-y=utils.o
utils_str-y=utils_str.o
vboot-y=vboot.o
diff --git a/test/fake_battery.c b/test/fake_battery.c
new file mode 100644
index 0000000000..4442300572
--- /dev/null
+++ b/test/fake_battery.c
@@ -0,0 +1,42 @@
+/* Copyright 2019 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.
+ *
+ * Fake BATTERY module.
+ */
+#include "battery.h"
+#include "common.h"
+
+int battery_design_voltage(int *voltage)
+{
+ *voltage = 0;
+ return 0;
+}
+
+enum battery_present battery_is_present(void)
+{
+ return BP_NO;
+}
+
+int battery_design_capacity(int *capacity)
+{
+ *capacity = 0;
+ return 0;
+}
+
+int battery_full_charge_capacity(int *capacity)
+{
+ *capacity = 0;
+ return 0;
+}
+
+int battery_remaining_capacity(int *capacity)
+{
+ *capacity = 0;
+ return 0;
+}
+
+int battery_status(int *status)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
diff --git a/test/fake_prl.c b/test/fake_prl.c
new file mode 100644
index 0000000000..abdc27763f
--- /dev/null
+++ b/test/fake_prl.c
@@ -0,0 +1,60 @@
+/* Copyright 2019 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.
+ *
+ * Fake Protocol Layer module.
+ */
+#include "common.h"
+#include "usb_emsg.h"
+#include "usb_prl_sm.h"
+
+struct extended_msg emsg[CONFIG_USB_PD_PORT_COUNT];
+
+void prl_end_ams(int port)
+{}
+
+void prl_execute_hard_reset(int port)
+{}
+
+enum pd_rev_type prl_get_rev(int port)
+{
+ return PD_REV30;
+}
+
+void prl_hard_reset_complete(int port)
+{}
+
+int prl_is_running(int port)
+{
+ return 0;
+}
+
+void prl_reset(int port)
+{}
+
+static enum pd_ctrl_msg_type last_ctrl_msg[CONFIG_USB_PD_PORT_COUNT];
+void prl_send_ctrl_msg(int port, enum tcpm_transmit_type type,
+ enum pd_ctrl_msg_type msg)
+{
+ last_ctrl_msg[port] = msg;
+}
+
+void prl_send_data_msg(int port, enum tcpm_transmit_type type,
+ enum pd_data_msg_type msg)
+{}
+
+void prl_send_ext_data_msg(int port, enum tcpm_transmit_type type,
+ enum pd_ext_msg_type msg)
+{}
+
+void prl_set_rev(int port, enum pd_rev_type rev)
+{}
+
+void prl_start_ams(int port)
+{}
+
+
+enum pd_ctrl_msg_type fake_prl_get_last_sent_ctrl_msg(int port)
+{
+ return last_ctrl_msg[port];
+}
diff --git a/test/fake_usbc.c b/test/fake_usbc.c
new file mode 100644
index 0000000000..f9cb69f4c9
--- /dev/null
+++ b/test/fake_usbc.c
@@ -0,0 +1,116 @@
+/* Copyright 2019 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 Type-C module.
+ */
+#include "common.h"
+#include "usb_tc_sm.h"
+
+int pd_is_vbus_present(int port)
+{
+ return 0;
+}
+
+void pd_request_data_swap(int port)
+{}
+
+void pd_request_power_swap(int port)
+{}
+
+void pd_request_vconn_swap_off(int port)
+{}
+
+void pd_request_vconn_swap_on(int port)
+{}
+
+
+static int data_role;
+int tc_get_data_role(int port)
+{
+ return data_role;
+}
+void tc_set_data_role(int port, int role)
+{
+ data_role = role;
+}
+
+static int power_role;
+int tc_get_power_role(int port)
+{
+ return power_role;
+}
+void tc_set_power_role(int port, int role)
+{
+ power_role = role;
+}
+
+int tc_check_vconn_swap(int port)
+{
+ return 0;
+}
+
+void tc_ctvpd_detected(int port)
+{}
+
+void tc_disc_ident_complete(int port)
+{}
+
+static int attached_snk;
+int tc_is_attached_snk(int port)
+{
+ return attached_snk;
+}
+
+static int attached_src;
+int tc_is_attached_src(int port)
+{
+ return attached_src;
+}
+
+int tc_is_vconn_src(int port)
+{
+ return 0;
+}
+
+void tc_hard_reset(int port)
+{}
+
+void tc_partner_dr_data(int port, int en)
+{}
+
+void tc_partner_dr_power(int port, int en)
+{}
+
+void tc_partner_extpower(int port, int en)
+{}
+
+void tc_partner_usb_comm(int port, int en)
+{}
+
+void tc_pd_connection(int port, int en)
+{}
+
+void tc_pr_swap_complete(int port)
+{}
+
+void tc_prs_snk_src_assert_rp(int port)
+{
+ attached_snk = 0;
+ attached_src = 1;
+}
+
+void tc_prs_src_snk_assert_rd(int port)
+{
+ attached_snk = 1;
+ attached_src = 0;
+}
+
+void tc_set_timeout(int port, uint64_t timeout)
+{}
+
+void tc_start_error_recovery(int port)
+{}
+
+void tc_snk_power_off(int port)
+{}
diff --git a/test/test_config.h b/test/test_config.h
index b6dfbb29b8..7771a05c0f 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -284,6 +284,19 @@ int ncp15wb_calculate_temp(uint16_t adc);
#define CONFIG_SW_CRC
#endif
+#if defined(TEST_USB_PE_DRP)
+#define CONFIG_TEST_USB_PE_SM
+#define CONFIG_USB_PD_PORT_COUNT 1
+#define CONFIG_USB_PE_SM
+#define CONFIG_USB_PID 0x5036
+#define CONFIG_USB_POWER_DELIVERY
+#undef CONFIG_USB_PRL_SM
+#define CONFIG_USB_SM_FRAMEWORK
+#undef CONFIG_USB_TYPEC_SM
+#define CONFIG_USBC_VCONN
+#define PD_VCONN_SWAP_DELAY 5000 /* us */
+#endif
+
/* Common TypeC tests defines */
#if defined(TEST_USB_TYPEC_VPD) || \
defined(TEST_USB_TYPEC_CTVPD) || \
diff --git a/test/usb_pe.h b/test/usb_pe.h
new file mode 100644
index 0000000000..f54040e6a6
--- /dev/null
+++ b/test/usb_pe.h
@@ -0,0 +1,133 @@
+/* Copyright 2019 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 PE module.
+ */
+#ifndef __CROS_TEST_USB_PE_H
+#define __CROS_TEST_USB_PE_H
+
+#include "common.h"
+
+/*
+ * Test references to port
+ */
+#define PORT0 0
+
+/*
+ * Parameters for pe_run
+ *
+ * pe_run(port, evt, enable)
+ * evt - currently ignored in the implementation
+ * enable - 0 Disable/1 Enable
+ */
+#define EVT_IGNORED 0
+
+#define ENABLED 1
+#define DISABLED 0
+
+/**
+ * usb_pe_drp_sm.c locally defined. If it changes there, it must
+ * be changed here as well.
+ */
+
+/* Policy Engine Layer Flags */
+#define PE_FLAGS_PD_CONNECTION BIT(0)
+#define PE_FLAGS_ACCEPT BIT(1)
+#define PE_FLAGS_PS_READY BIT(2)
+#define PE_FLAGS_PROTOCOL_ERROR BIT(3)
+#define PE_FLAGS_MODAL_OPERATION BIT(4)
+#define PE_FLAGS_TX_COMPLETE BIT(5)
+#define PE_FLAGS_MSG_RECEIVED BIT(6)
+#define PE_FLAGS_HARD_RESET_PENDING BIT(7)
+#define PE_FLAGS_WAIT BIT(8)
+#define PE_FLAGS_EXPLICIT_CONTRACT BIT(9)
+#define PE_FLAGS_SNK_WAIT_CAP_TIMEOUT BIT(10)
+#define PE_FLAGS_PS_TRANSITION_TIMEOUT BIT(11)
+#define PE_FLAGS_INTERRUPTIBLE_AMS BIT(12)
+#define PE_FLAGS_PS_RESET_COMPLETE BIT(13)
+#define PE_FLAGS_SEND_SVDM BIT(14)
+#define PE_FLAGS_VCONN_SWAP_COMPLETE BIT(15)
+#define PE_FLAGS_DISCOVER_PORT_IDENTITY_DONE BIT(16)
+#define PE_FLAGS_DISCOVER_VDM_IDENTITY_DONE BIT(17)
+#define PE_FLAGS_RUN_SOURCE_START_TIMER BIT(19)
+#define PE_FLAGS_VDM_REQUEST_BUSY BIT(20)
+#define PE_FLAGS_VDM_REQUEST_NAKED BIT(21)
+#define PE_FLAGS_FAST_ROLE_SWAP_PATH BIT(22)/* FRS/PRS Exec Path */
+#define PE_FLAGS_FAST_ROLE_SWAP_ENABLED BIT(23)/* FRS Listening State */
+#define PE_FLAGS_FAST_ROLE_SWAP_SIGNALED BIT(24)/* FRS PPC/TCPC Signal */
+
+/* List of all Policy Engine level states */
+enum usb_pe_state {
+ /* Normal States */
+ PE_SRC_STARTUP,
+ PE_SRC_DISCOVERY,
+ PE_SRC_SEND_CAPABILITIES,
+ PE_SRC_NEGOTIATE_CAPABILITY,
+ PE_SRC_TRANSITION_SUPPLY,
+ PE_SRC_READY,
+ PE_SRC_DISABLED,
+ PE_SRC_CAPABILITY_RESPONSE,
+ PE_SRC_HARD_RESET,
+ PE_SRC_HARD_RESET_RECEIVED,
+ PE_SRC_TRANSITION_TO_DEFAULT,
+ PE_SRC_VDM_IDENTITY_REQUEST,
+ PE_SNK_STARTUP,
+ PE_SNK_DISCOVERY,
+ PE_SNK_WAIT_FOR_CAPABILITIES,
+ PE_SNK_EVALUATE_CAPABILITY,
+ PE_SNK_SELECT_CAPABILITY,
+ PE_SNK_READY,
+ PE_SNK_HARD_RESET,
+ PE_SNK_TRANSITION_TO_DEFAULT,
+ PE_SNK_GIVE_SINK_CAP,
+ PE_SNK_GET_SOURCE_CAP,
+ PE_SNK_TRANSITION_SINK,
+ PE_SEND_SOFT_RESET,
+ PE_SOFT_RESET,
+ PE_SEND_NOT_SUPPORTED,
+ PE_SRC_PING,
+ PE_GIVE_BATTERY_CAP,
+ PE_GIVE_BATTERY_STATUS,
+ PE_DRS_EVALUATE_SWAP,
+ PE_DRS_CHANGE,
+ PE_DRS_SEND_SWAP,
+ PE_PRS_SRC_SNK_EVALUATE_SWAP,
+ PE_PRS_SRC_SNK_TRANSITION_TO_OFF,
+ PE_PRS_SRC_SNK_WAIT_SOURCE_ON,
+ PE_PRS_SRC_SNK_SEND_SWAP,
+ PE_PRS_SNK_SRC_EVALUATE_SWAP,
+ PE_PRS_SNK_SRC_TRANSITION_TO_OFF,
+ PE_PRS_SNK_SRC_ASSERT_RP,
+ PE_PRS_SNK_SRC_SOURCE_ON,
+ PE_PRS_SNK_SRC_SEND_SWAP,
+ PE_FRS_SNK_SRC_START_AMS,
+ PE_VCS_EVALUATE_SWAP,
+ PE_VCS_SEND_SWAP,
+ PE_VCS_WAIT_FOR_VCONN_SWAP,
+ PE_VCS_TURN_ON_VCONN_SWAP,
+ PE_VCS_TURN_OFF_VCONN_SWAP,
+ PE_VCS_SEND_PS_RDY_SWAP,
+ PE_DO_PORT_DISCOVERY,
+ PE_VDM_REQUEST,
+ PE_VDM_ACKED,
+ PE_VDM_RESPONSE,
+ PE_HANDLE_CUSTOM_VDM_REQUEST,
+ PE_WAIT_FOR_ERROR_RECOVERY,
+ PE_BIST,
+ PE_DR_SNK_GET_SINK_CAP,
+
+ /* Super States */
+ PE_PRS_FRS_SHARED,
+};
+
+void set_state_pe(const int port, const enum usb_pe_state new_state);
+enum usb_pe_state get_state_pe(const int port);
+
+void pe_set_flag(int port, int flag);
+void pe_clr_flag(int port, int flag);
+int pe_chk_flag(int port, int flag);
+int pe_get_all_flags(int port);
+void pe_set_all_flags(int port, int flags);
+
+#endif /* __CROS_TEST_USB_PE_H */
diff --git a/test/usb_pe_drp.c b/test/usb_pe_drp.c
new file mode 100644
index 0000000000..b2457a8298
--- /dev/null
+++ b/test/usb_pe_drp.c
@@ -0,0 +1,134 @@
+/* Copyright 2019 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 PE module.
+ */
+#include "battery.h"
+#include "common.h"
+#include "task.h"
+#include "test_util.h"
+#include "timer.h"
+#include "usb_emsg.h"
+#include "usb_pe.h"
+#include "usb_pe_sm.h"
+#include "usb_prl_sm.h"
+#include "usb_sm_checks.h"
+#include "usb_tc_sm.h"
+
+/**
+ * STUB Section
+ */
+const struct svdm_response svdm_rsp = {
+ .identity = NULL,
+ .svids = NULL,
+ .modes = NULL,
+};
+
+/**
+ * Test section
+ */
+/* PE Fast Role Swap */
+static int test_pe_frs(void)
+{
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(pe_is_running(PORT0));
+
+ /*
+ * FRS will only trigger when we are SNK, with an Explicit
+ * contract. So set this state up manually
+ */
+ tc_prs_src_snk_assert_rd(PORT0);
+ pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT);
+ set_state_pe(PORT0, PE_SNK_READY);
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(get_state_pe(PORT0) == PE_SNK_READY);
+
+ /*
+ * Trigger the Fast Role Switch from simulated ISR
+ */
+ pe_got_frs_signal(PORT0);
+ TEST_ASSERT(pe_chk_flag(PORT0, PE_FLAGS_FAST_ROLE_SWAP_SIGNALED));
+
+ /*
+ * Verify we detected FRS and ready to start swap
+ */
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(get_state_pe(PORT0) == PE_PRS_SNK_SRC_SEND_SWAP);
+ TEST_ASSERT(pe_chk_flag(PORT0, PE_FLAGS_FAST_ROLE_SWAP_PATH));
+ TEST_ASSERT(!pe_chk_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT));
+
+ /*
+ * Make sure that we sent FR_Swap
+ */
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(fake_prl_get_last_sent_ctrl_msg(PORT0) == PD_CTRL_FR_SWAP);
+ TEST_ASSERT(get_state_pe(PORT0) == PE_PRS_SNK_SRC_SEND_SWAP);
+ TEST_ASSERT(pe_chk_flag(PORT0, PE_FLAGS_FAST_ROLE_SWAP_PATH));
+
+ /*
+ * Accept the partners PS_RDY control message
+ */
+ emsg[PORT0].header = PD_HEADER(PD_CTRL_ACCEPT, 0, 0, 0, 0, 0, 0);
+ pe_set_flag(PORT0, PE_FLAGS_MSG_RECEIVED);
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(!pe_chk_flag(PORT0, PE_FLAGS_MSG_RECEIVED));
+ TEST_ASSERT(get_state_pe(PORT0) == PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
+ TEST_ASSERT(pe_chk_flag(PORT0, PE_FLAGS_FAST_ROLE_SWAP_PATH));
+
+ /*
+ * Send back our PS_RDY
+ */
+ emsg[PORT0].header = PD_HEADER(PD_CTRL_PS_RDY, 0, 0, 0, 0, 0, 0);
+ pe_set_flag(PORT0, PE_FLAGS_MSG_RECEIVED);
+ TEST_ASSERT(!tc_is_attached_src(PORT0));
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(!pe_chk_flag(PORT0, PE_FLAGS_MSG_RECEIVED));
+ TEST_ASSERT(tc_is_attached_src(PORT0));
+ TEST_ASSERT(get_state_pe(PORT0) == PE_PRS_SNK_SRC_ASSERT_RP);
+ TEST_ASSERT(pe_chk_flag(PORT0, PE_FLAGS_FAST_ROLE_SWAP_PATH));
+
+ /*
+ * We are now attached source, so move to next state
+ */
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(get_state_pe(PORT0) == PE_PRS_SNK_SRC_SOURCE_ON);
+ TEST_ASSERT(pe_chk_flag(PORT0, PE_FLAGS_FAST_ROLE_SWAP_PATH));
+
+ /*
+ * Move the time to be after our wait time.
+ */
+ force_time((timestamp_t)(get_time().val +
+ PD_POWER_SUPPLY_TURN_ON_DELAY));
+
+ /*
+ * After delay we are ready to send our PS_RDY
+ */
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(get_state_pe(PORT0) == PE_PRS_SNK_SRC_SOURCE_ON);
+ TEST_ASSERT(pe_chk_flag(PORT0, PE_FLAGS_FAST_ROLE_SWAP_PATH));
+ TEST_ASSERT(fake_prl_get_last_sent_ctrl_msg(PORT0) == PD_CTRL_PS_RDY);
+
+ /*
+ * Fake the Transmit complete and this will bring us to Source Startup
+ */
+ pe_set_flag(PORT0, PE_FLAGS_TX_COMPLETE);
+ pe_run(PORT0, EVT_IGNORED, ENABLED);
+ TEST_ASSERT(get_state_pe(PORT0) == PE_SRC_STARTUP);
+ TEST_ASSERT(!pe_chk_flag(PORT0, PE_FLAGS_FAST_ROLE_SWAP_PATH));
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ test_reset();
+
+ RUN_TEST(test_pe_frs);
+
+ /* Do basic state machine sanity checks last. */
+ RUN_TEST(test_pe_no_parent_cycles);
+ RUN_TEST(test_pe_no_empty_state);
+
+ test_print_result();
+}
diff --git a/test/usb_pe_drp.tasklist b/test/usb_pe_drp.tasklist
new file mode 100644
index 0000000000..80b3135e56
--- /dev/null
+++ b/test/usb_pe_drp.tasklist
@@ -0,0 +1,9 @@
+/* Copyright 2019 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.
+ */
+
+/**
+ * See CONFIG_TEST_TASK_LIST in config.h for details.
+ */
+#define CONFIG_TEST_TASK_LIST