11/*
2- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 */
@@ -49,7 +49,7 @@ TEST_CASE("Test USB Host sudden disconnection (no client)", "[usb_host][low_spee
4949 connected = true;
5050 printf ("Forcing Sudden Disconnect\n" );
5151 // Trigger a disconnect by powering OFF the root port
52- usb_host_lib_set_root_port_power (false);
52+ TEST_ASSERT_EQUAL ( ESP_OK , usb_host_lib_set_root_port_power (false) );
5353 }
5454 }
5555 if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE ) {
@@ -59,7 +59,92 @@ TEST_CASE("Test USB Host sudden disconnection (no client)", "[usb_host][low_spee
5959 // Start next iteration
6060 connected = false;
6161 // Allow connections again by powering ON the root port
62- usb_host_lib_set_root_port_power (true);
62+ TEST_ASSERT_EQUAL (ESP_OK , usb_host_lib_set_root_port_power (true));
63+ } else {
64+ break ;
65+ }
66+ }
67+ }
68+ }
69+
70+ /*
71+ Test USB Host Library root port suspend with Sudden Disconnection Handling (no clients)
72+ Purpose:
73+ - Test that sudden disconnections after suspending are handled properly when there are no clients
74+ - Test that devices can reconnect after suspending with a sudden disconnection has been handled by the USB Host Library
75+
76+ Procedure:
77+ - Install USB Host Library:
78+ - Wait for connection to occur and suspend the root port
79+ - Let the usb_host lib to handle events caused by root port suspend call
80+ - Force a disconnection, then wait for disconnection to be handled (USB_HOST_LIB_EVENT_FLAGS_ALL_FREE)
81+ - Allow connections again, and repeat test for multiple iterations
82+ - Wait for connection to occur and suspend the root port
83+ - Don't handle events (just mark the root port for suspending)
84+ - Force a disconnection, then wait for disconnection to be handled (USB_HOST_LIB_EVENT_FLAGS_ALL_FREE)
85+ - Allow connections again, and repeat test for multiple iterations
86+ */
87+
88+ #define TEST_DCONN_SUSPEND_ITERATIONS 6
89+
90+ TEST_CASE ("Test USB Host suspend + disconnection (no client)" , "[usb_host][low_speed][full_speed][high_speed]" )
91+ {
92+ bool connected = false;
93+ bool suspended = false;
94+ int dconn_iter = 0 ;
95+ while (1 ) {
96+ // Start handling system events
97+ uint32_t event_flags ;
98+ usb_host_lib_handle_events (portMAX_DELAY , & event_flags );
99+
100+ if (!connected ) {
101+ usb_host_lib_info_t lib_info_connected ;
102+ TEST_ASSERT_EQUAL (ESP_OK , usb_host_lib_info (& lib_info_connected ));
103+ if (lib_info_connected .num_devices == 1 ) {
104+ // We've just connected. Trigger root port suspend
105+ connected = true;
106+
107+ printf ("Suspending the root port\n" );
108+ // Suspend the root port
109+ TEST_ASSERT_EQUAL (ESP_OK , usb_host_lib_root_port_suspend ());
110+
111+ // In first test variation, continue to the end of the loop, to handle events connected to the port suspend
112+ // In second variation don't handle port suspend, disconnect immediately
113+ if (dconn_iter < TEST_DCONN_SUSPEND_ITERATIONS / 2 ) {
114+ continue ;
115+ }
116+ }
117+ }
118+
119+ if (!suspended ) {
120+ usb_host_lib_info_t lib_info ;
121+ TEST_ASSERT_EQUAL (ESP_OK , usb_host_lib_info (& lib_info ));
122+ if (lib_info .num_devices == 1 ) {
123+ // We've started suspend sequence. Trigger a disconnect
124+ suspended = true;
125+
126+ if (dconn_iter < TEST_DCONN_SUSPEND_ITERATIONS / 2 ) {
127+ // Port suspend call has been handled, expect the port to be suspended
128+ TEST_ASSERT_MESSAGE (lib_info .root_port_suspended , "Root port should be suspended" );
129+ } else {
130+ // Port suspend call has not been handled, expect the port not to be suspended
131+ TEST_ASSERT_MESSAGE (!lib_info .root_port_suspended , "Root port should not be suspended" );
132+ }
133+ printf ("Forcing Sudden Disconnect\n" );
134+ // Trigger a disconnect by powering OFF the root port
135+ TEST_ASSERT_EQUAL (ESP_OK , usb_host_lib_set_root_port_power (false));
136+ }
137+ }
138+
139+ if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE ) {
140+ // The device has disconnected and it's disconnection has been handled
141+ printf ("Dconn iter %d done\n" , dconn_iter );
142+ if (++ dconn_iter < TEST_DCONN_SUSPEND_ITERATIONS ) {
143+ // Start next iteration
144+ connected = false;
145+ suspended = false;
146+ // Allow connections again by powering ON the root port
147+ TEST_ASSERT_EQUAL (ESP_OK , usb_host_lib_set_root_port_power (true));
63148 } else {
64149 break ;
65150 }
0 commit comments