Skip to content

Commit

Permalink
Merge branch 'bugfix/usb_host_enumeration_delay' into 'master'
Browse files Browse the repository at this point in the history
USB Host: SetAddress recovery interval + menuconfig configuration

Closes IDFGH-9036, IDFGH-9340

See merge request espressif/esp-idf!22607
  • Loading branch information
roma-jam committed Mar 10, 2023
2 parents b0b99a9 + be899f6 commit 6777579
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
54 changes: 54 additions & 0 deletions components/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,58 @@ menu "USB-OTG"
bool "Periodic OUT"
endchoice

menu "Root Hub configuration"

config USB_HOST_DEBOUNCE_DELAY_MS
depends on USB_OTG_SUPPORTED
int "Debounce delay in ms"
default 250
help
On connection of a USB device, the USB 2.0 specification requires a "debounce interval with a minimum
duration of 100ms" to allow the connection to stabilize (see USB 2.0 chapter 7.1.7.3 for more details).
During the debounce interval, no new connection/disconnection events are registered.

The default value is set to 250 ms to be safe.

config USB_HOST_RESET_HOLD_MS
depends on USB_OTG_SUPPORTED
int "Reset hold in ms"
default 30
help
The reset signaling can be generated on any Hub or Host Controller port by request from the USB System
Software. The USB 2.0 specification requires that "the reset signaling must be driven for a minimum of
10ms" (see USB 2.0 chapter 7.1.7.5 for more details). After the reset, the hub port will transition to
the Enabled state (refer to Section 11.5).

The default value is set to 30 ms to be safe.

config USB_HOST_RESET_RECOVERY_MS
depends on USB_OTG_SUPPORTED
int "Reset recovery delay in ms"
default 30
help
After a port stops driving the reset signal, the USB 2.0 specification requires that the "USB System
Software guarantees a minimum of 10 ms for reset recovery" before the attached device is expected to
respond to data transfers (see USB 2.0 chapter 7.1.7.3 for more details). The device may ignore any
data transfers during the recovery interval.

The default value is set to 30 ms to be safe.


config USB_HOST_SET_ADDR_RECOVERY_MS
depends on USB_OTG_SUPPORTED
int "SetAddress() recovery time in ms"
default 10
help
"After successful completion of the Status stage, the device is allowed a SetAddress() recovery
interval of 2 ms. At the end of this interval, the device must be able to accept Setup packets
addressed to the new address. Also, at the end of the recovery interval, the device must not respond to
tokens sent to the old address (unless, of course, the old and new address is the same)." See USB 2.0
chapter 9.2.6.3 for more details.

The default value is set to 10 ms to be safe.


endmenu #Root Hub configuration

endmenu #USB-OTG
6 changes: 3 additions & 3 deletions components/usb/hcd_dwc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
// --------------------- Constants -------------------------

#define INIT_DELAY_MS 30 //A delay of at least 25ms to enter Host mode. Make it 30ms to be safe
#define DEBOUNCE_DELAY_MS 250 //A debounce delay of 250ms
#define RESET_HOLD_MS 30 //Spec requires at least 10ms. Make it 30ms to be safe
#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)
#define DEBOUNCE_DELAY_MS CONFIG_USB_HOST_DEBOUNCE_DELAY_MS
#define RESET_HOLD_MS CONFIG_USB_HOST_RESET_HOLD_MS
#define RESET_RECOVERY_MS CONFIG_USB_HOST_RESET_RECOVERY_MS
#define RESUME_HOLD_MS 30 //Spec requires at least 20ms, Make it 30ms to be safe
#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

Expand Down
25 changes: 25 additions & 0 deletions components/usb/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ implement the bare minimum to control the root HCD port.
#define HUB_ROOT_HCD_PORT_FIFO_BIAS HCD_PORT_FIFO_BIAS_BALANCED
#endif

#define SET_ADDR_RECOVERY_INTERVAL_MS CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS

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

static bool enum_stage_wait(enum_ctrl_t *enum_ctrl)
{
switch (enum_ctrl->stage) {
case ENUM_STAGE_SET_ADDR_RECOVERY: {
vTaskDelay(pdMS_TO_TICKS(SET_ADDR_RECOVERY_INTERVAL_MS)); // Need a short delay before device is ready. Todo: IDF-7007
return true;
}

default: //Should never occur
abort();
break;
}

return false;
}

static bool enum_stage_transfer_check(enum_ctrl_t *enum_ctrl)
{
//Dequeue the URB
Expand Down Expand Up @@ -696,6 +716,7 @@ static void enum_set_next_stage(enum_ctrl_t *enum_ctrl, bool last_stage_pass)
case ENUM_STAGE_GET_SHORT_DEV_DESC:
case ENUM_STAGE_SECOND_RESET:
case ENUM_STAGE_SET_ADDR:
case ENUM_STAGE_SET_ADDR_RECOVERY:
case ENUM_STAGE_GET_FULL_DEV_DESC:
case ENUM_STAGE_GET_SHORT_CONFIG_DESC:
case ENUM_STAGE_GET_FULL_CONFIG_DESC:
Expand Down Expand Up @@ -857,6 +878,10 @@ static void enum_handle_events(void)
case ENUM_STAGE_GET_FULL_SER_STR_DESC:
stage_pass = enum_stage_transfer(enum_ctrl);
break;
//Recovery interval
case ENUM_STAGE_SET_ADDR_RECOVERY:
stage_pass = enum_stage_wait(enum_ctrl);
break;
//Transfer check stages
case ENUM_STAGE_CHECK_SHORT_DEV_DESC:
case ENUM_STAGE_CHECK_ADDR:
Expand Down

0 comments on commit 6777579

Please sign in to comment.