Skip to content

Commit 647cc43

Browse files
committed
Merge branch 'bugfix/usb_host_enumeration_delay_v4.4' into 'release/v4.4'
USB Host: SetAddress recovery interval + menuconfig configuration (backport v4.4) See merge request espressif/esp-idf!22703
2 parents 3b54c90 + 0f47fad commit 647cc43

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

components/usb/Kconfig

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,58 @@ menu "USB-OTG"
5353
bool "Periodic OUT"
5454
endchoice
5555

56+
menu "Root Hub configuration"
57+
58+
config USB_HOST_DEBOUNCE_DELAY_MS
59+
depends on USB_OTG_SUPPORTED
60+
int "Debounce delay in ms"
61+
default 250
62+
help
63+
On connection of a USB device, the USB 2.0 specification requires a "debounce interval with a minimum
64+
duration of 100ms" to allow the connection to stabilize (see USB 2.0 chapter 7.1.7.3 for more details).
65+
During the debounce interval, no new connection/disconnection events are registered.
66+
67+
The default value is set to 250 ms to be safe.
68+
69+
config USB_HOST_RESET_HOLD_MS
70+
depends on USB_OTG_SUPPORTED
71+
int "Reset hold in ms"
72+
default 30
73+
help
74+
The reset signaling can be generated on any Hub or Host Controller port by request from the USB System
75+
Software. The USB 2.0 specification requires that "the reset signaling must be driven for a minimum of
76+
10ms" (see USB 2.0 chapter 7.1.7.5 for more details). After the reset, the hub port will transition to
77+
the Enabled state (refer to Section 11.5).
78+
79+
The default value is set to 30 ms to be safe.
80+
81+
config USB_HOST_RESET_RECOVERY_MS
82+
depends on USB_OTG_SUPPORTED
83+
int "Reset recovery delay in ms"
84+
default 30
85+
help
86+
After a port stops driving the reset signal, the USB 2.0 specification requires that the "USB System
87+
Software guarantees a minimum of 10 ms for reset recovery" before the attached device is expected to
88+
respond to data transfers (see USB 2.0 chapter 7.1.7.3 for more details). The device may ignore any
89+
data transfers during the recovery interval.
90+
91+
The default value is set to 30 ms to be safe.
92+
93+
94+
config USB_HOST_SET_ADDR_RECOVERY_MS
95+
depends on USB_OTG_SUPPORTED
96+
int "SetAddress() recovery time in ms"
97+
default 10
98+
help
99+
"After successful completion of the Status stage, the device is allowed a SetAddress() recovery
100+
interval of 2 ms. At the end of this interval, the device must be able to accept Setup packets
101+
addressed to the new address. Also, at the end of the recovery interval, the device must not respond to
102+
tokens sent to the old address (unless, of course, the old and new address is the same)." See USB 2.0
103+
chapter 9.2.6.3 for more details.
104+
105+
The default value is set to 10 ms to be safe.
106+
107+
108+
endmenu #Root Hub configuration
109+
56110
endmenu #USB-OTG

components/usb/hcd_dwc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
// --------------------- Constants -------------------------
3030

3131
#define INIT_DELAY_MS 30 //A delay of at least 25ms to enter Host mode. Make it 30ms to be safe
32-
#define DEBOUNCE_DELAY_MS 250 //A debounce delay of 250ms
33-
#define RESET_HOLD_MS 30 //Spec requires at least 10ms. Make it 30ms to be safe
34-
#define RESET_RECOVERY_MS 30 //Reset recovery delay of 10ms (make it 30 ms to be safe) to allow for connected device to recover (and for port enabled interrupt to occur)
32+
#define DEBOUNCE_DELAY_MS CONFIG_USB_HOST_DEBOUNCE_DELAY_MS
33+
#define RESET_HOLD_MS CONFIG_USB_HOST_RESET_HOLD_MS
34+
#define RESET_RECOVERY_MS CONFIG_USB_HOST_RESET_RECOVERY_MS
3535
#define RESUME_HOLD_MS 30 //Spec requires at least 20ms, Make it 30ms to be safe
3636
#define RESUME_RECOVERY_MS 20 //Resume recovery of at least 10ms. Make it 20 ms to be safe. This will include the 3 LS bit times of the EOP
3737

components/usb/hub.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ implement the bare minimum to control the root HCD port.
3232
#define HUB_ROOT_HCD_PORT_FIFO_BIAS HCD_PORT_FIFO_BIAS_BALANCED
3333
#endif
3434

35+
#define SET_ADDR_RECOVERY_INTERVAL_MS CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS
36+
3537
#define ENUM_CTRL_TRANSFER_MAX_DATA_LEN CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE
3638
#define ENUM_DEV_ADDR 1 //Device address used in enumeration
3739
#define ENUM_CONFIG_INDEX 0 //Index of the first configuration of the device
@@ -79,6 +81,7 @@ typedef enum {
7981
ENUM_STAGE_SECOND_RESET, /**< Reset the device again (Workaround for old USB devices that get confused by the previous short dev desc request). */
8082
ENUM_STAGE_SET_ADDR, /**< Send SET_ADDRESS request */
8183
ENUM_STAGE_CHECK_ADDR, /**< Update the enum pipe's target address */
84+
ENUM_STAGE_SET_ADDR_RECOVERY, /**< Wait SET ADDRESS recovery interval at least for 2ms due to usb_20, chapter 9.2.6.3 */
8285
ENUM_STAGE_GET_FULL_DEV_DESC, /**< Get the full dev desc */
8386
ENUM_STAGE_CHECK_FULL_DEV_DESC, /**< Check the full dev desc, fill it into the device object in USBH. Save the string descriptor indexes*/
8487
ENUM_STAGE_GET_SHORT_CONFIG_DESC, /**< Getting a short config desc (wLength is ENUM_SHORT_DESC_REQ_LEN) */
@@ -117,6 +120,7 @@ const char *const enum_stage_strings[] = {
117120
"SECOND_RESET",
118121
"SET_ADDR",
119122
"CHECK_ADDR",
123+
"SET_ADDR_RECOVERY",
120124
"GET_FULL_DEV_DESC",
121125
"CHECK_FULL_DEV_DESC",
122126
"GET_SHORT_CONFIG_DESC",
@@ -411,6 +415,22 @@ static bool enum_stage_transfer(enum_ctrl_t *enum_ctrl)
411415
return true;
412416
}
413417

418+
static bool enum_stage_wait(enum_ctrl_t *enum_ctrl)
419+
{
420+
switch (enum_ctrl->stage) {
421+
case ENUM_STAGE_SET_ADDR_RECOVERY: {
422+
vTaskDelay(pdMS_TO_TICKS(SET_ADDR_RECOVERY_INTERVAL_MS)); // Need a short delay before device is ready. Todo: IDF-7007
423+
return true;
424+
}
425+
426+
default: //Should never occur
427+
abort();
428+
break;
429+
}
430+
431+
return false;
432+
}
433+
414434
static bool enum_stage_transfer_check(enum_ctrl_t *enum_ctrl)
415435
{
416436
//Dequeue the URB
@@ -696,6 +716,7 @@ static void enum_set_next_stage(enum_ctrl_t *enum_ctrl, bool last_stage_pass)
696716
case ENUM_STAGE_GET_SHORT_DEV_DESC:
697717
case ENUM_STAGE_SECOND_RESET:
698718
case ENUM_STAGE_SET_ADDR:
719+
case ENUM_STAGE_SET_ADDR_RECOVERY:
699720
case ENUM_STAGE_GET_FULL_DEV_DESC:
700721
case ENUM_STAGE_GET_SHORT_CONFIG_DESC:
701722
case ENUM_STAGE_GET_FULL_CONFIG_DESC:
@@ -857,6 +878,10 @@ static void enum_handle_events(void)
857878
case ENUM_STAGE_GET_FULL_SER_STR_DESC:
858879
stage_pass = enum_stage_transfer(enum_ctrl);
859880
break;
881+
//Recovery interval
882+
case ENUM_STAGE_SET_ADDR_RECOVERY:
883+
stage_pass = enum_stage_wait(enum_ctrl);
884+
break;
860885
//Transfer check stages
861886
case ENUM_STAGE_CHECK_SHORT_DEV_DESC:
862887
case ENUM_STAGE_CHECK_ADDR:

0 commit comments

Comments
 (0)