29 #include "sw/device/lib/base/status.h"
35 #include "sw/device/lib/testing/pinmux_testutils.h"
36 #include "sw/device/lib/testing/test_framework/check.h"
39 #define USBDEV_BASE_ADDR TOP_EARLGREY_USBDEV_BASE_ADDR
45 static const bool kCheckLowFirst =
false;
50 static dif_usbdev_t usbdev;
56 static dif_pinmux_t pinmux;
60 static status_t config_set(
bool pinflip) {
75 static status_t vbus_wait(
bool expected, uint32_t timeout_micros) {
81 if (vbus == expected) {
86 return DEADLINE_EXCEEDED();
91 static status_t line_wait(
bool dp,
bool expected, uint32_t timeout_micros) {
98 if ((dp &&
status.rx_dp == expected) || (!dp &&
status.rx_dn == expected)) {
103 return DEADLINE_EXCEEDED();
108 static status_t line_check(
bool dp,
bool expected, uint32_t interval_micros) {
113 uint32_t mismatched = 0u;
120 mismatched += (dp ?
status.rx_dp :
status.rx_dn) ^ expected;
124 if ((mismatched << 3) > count) {
134 static status_t delay(
bool prompt, uint32_t timeout_micros) {
149 TRY(delay(prompt, 15u));
164 return DEADLINE_EXCEEDED();
167 OTTF_DEFINE_TEST_CONFIG();
172 uint32_t timeout_micros = 1000u;
173 uint32_t delay_micros = 1u;
174 uint32_t hold_micros = 50u;
175 bool can_flip =
true;
180 timeout_micros = 30 * 1000 * 1000u;
183 delay_micros = 2 * 1000 * 1000u;
186 hold_micros = 2 * 1000;
195 CHECK_DIF_OK(dif_pinmux_init(
197 pinmux_testutils_init(&pinmux);
209 CHECK_STATUS_OK(config_set(!dp));
213 if (kCheckLowFirst) {
218 LOG_INFO(
"Disconnect or power down the USB");
222 CHECK_STATUS_OK(vbus_wait(
false, timeout_micros));
225 LOG_INFO(
"Connect or power up the USB");
230 CHECK_STATUS_OK(vbus_wait(
true, timeout_micros));
237 LOG_INFO(
"Testing AON can hold %s %s", dp ?
"DP" :
"DN",
238 desired ?
"High" :
"Low");
241 CHECK_STATUS_OK(line_wait(dp, !desired, 1000u));
245 CHECK_STATUS_OK(delay(prompt, delay_micros));
255 LOG_INFO(
" - Attempting to drive %s %s", dp ?
"DP" :
"DN",
256 desired ?
"Low" :
"High");
262 CHECK_STATUS_OK(line_check(dp, desired, hold_micros));
272 CHECK_STATUS_OK(line_wait(dp, desired, 1000u));
278 }
while (can_flip && !dp);