Skip to content

Commit 1a783b3

Browse files
authored
Merge pull request #3104 from hathach/usbh-attach-debounce
Usbh attach debounce
2 parents a22e45b + 2abd3c5 commit 1a783b3

File tree

12 files changed

+49
-62
lines changed

12 files changed

+49
-62
lines changed

.idea/cmake.xml

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/debugServers/rt1060.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/debugServers/rt1064.xml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/debugServers/sam21.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/debugServers/sam51.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/debugServers/stm32f769.xml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/debugServers/stm32h563.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/debugServers/stm32h743.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/host/usbh.c

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ typedef struct {
275275
typedef struct {
276276
uint8_t controller_id; // controller ID
277277
uint8_t enumerating_daddr; // device address of the device being enumerated
278+
uint8_t attach_debouncing_bm; // bitmask for roothub port attach debouncing
278279
tuh_bus_info_t dev0_bus; // bus info for dev0 in enumeration
279280
usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer
280281
} usbh_data_t;
@@ -349,7 +350,7 @@ bool tuh_rhport_is_active(uint8_t rhport) {
349350

350351
bool tuh_rhport_reset_bus(uint8_t rhport, bool active) {
351352
TU_VERIFY(tuh_rhport_is_active(rhport));
352-
if ( active ) {
353+
if (active) {
353354
hcd_port_reset(rhport);
354355
} else {
355356
hcd_port_reset_end(rhport);
@@ -512,28 +513,19 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
512513
case HCD_EVENT_DEVICE_ATTACH:
513514
// due to the shared control buffer, we must fully complete enumerating one device first.
514515
// TODO better to have an separated queue for newly attached devices
515-
if (_usbh_data.enumerating_daddr != TUSB_INDEX_INVALID_8) {
516-
if (event.rhport == _usbh_data.dev0_bus.rhport &&
517-
event.connection.hub_addr == _usbh_data.dev0_bus.hub_addr && event.connection.hub_port == _usbh_data.dev0_bus.hub_port) {
518-
// Some device can cause multiple duplicated attach events
519-
// drop current enumerating and start over for a proper port reset
520-
// abort/cancel current enumeration and start new one
521-
TU_LOG1("[%u:] USBH Device Attach (duplicated)\r\n", event.rhport);
522-
tuh_edpt_abort_xfer(0, 0);
523-
enum_new_device(&event);
524-
} else {
525-
TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport);
526-
bool is_empty = osal_queue_empty(_usbh_q);
527-
queue_event(&event, in_isr);
528-
529-
if (is_empty) {
530-
// Exit if this is the only event in the queue, otherwise we may loop forever
531-
return;
532-
}
533-
}
534-
} else {
516+
if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) {
517+
// New device attached and we are ready
535518
TU_LOG1("[%u:] USBH Device Attach\r\n", event.rhport);
519+
_usbh_data.enumerating_daddr = 0; // enumerate new device with address 0
536520
enum_new_device(&event);
521+
} else {
522+
// currently enumerating another device
523+
TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport);
524+
const bool is_empty = osal_queue_empty(_usbh_q);
525+
queue_event(&event, in_isr);
526+
if (is_empty) {
527+
return; // Exit if this is the only event in the queue, otherwise we loop forever
528+
}
537529
}
538530
break;
539531

@@ -1021,10 +1013,18 @@ bool tuh_bus_info_get(uint8_t daddr, tuh_bus_info_t* bus_info) {
10211013
TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) {
10221014
switch (event->event_id) {
10231015
case HCD_EVENT_DEVICE_ATTACH:
1024-
1025-
break;
1026-
10271016
case HCD_EVENT_DEVICE_REMOVE:
1017+
// Attach debouncing on roothub: skip attach/remove while debouncing delay
1018+
if (event->connection.hub_addr == 0) {
1019+
if (tu_bit_test(_usbh_data.attach_debouncing_bm, event->rhport)) {
1020+
return;
1021+
}
1022+
1023+
if (event->event_id == HCD_EVENT_DEVICE_ATTACH) {
1024+
// No debouncing, set flag if attach event
1025+
_usbh_data.attach_debouncing_bm |= TU_BIT(event->rhport);
1026+
}
1027+
}
10281028
break;
10291029

10301030
default: break;
@@ -1363,6 +1363,7 @@ enum { // USB 2.0 specs 7.1.7 for timing
13631363
ENUM_RESET_ROOT_DELAY_MS = 50, // T(DRSTr) minimum 50 ms for reset from root port
13641364
ENUM_RESET_HUB_DELAY_MS = 20, // T(DRST) 10-20 ms for hub reset
13651365
ENUM_RESET_RECOVERY_DELAY_MS = 10, // T(RSTRCY) minimum 10 ms for reset recovery
1366+
ENUM_SET_ADDRESS_RECOVERY_DELAY_MS = 2, // USB 2.0 Spec 9.2.6.3 min is 2 ms
13661367
};
13671368

13681369
enum {
@@ -1401,11 +1402,14 @@ static bool enum_new_device(hcd_event_t* event) {
14011402
dev0_bus->hub_addr = event->connection.hub_addr;
14021403
dev0_bus->hub_port = event->connection.hub_port;
14031404

1404-
_usbh_data.enumerating_daddr = 0;
1405-
14061405
// wait until device connection is stable TODO non blocking
14071406
tusb_time_delay_ms_api(ENUM_DEBOUNCING_DELAY_MS);
14081407

1408+
// clear roothub debouncing delay
1409+
if (dev0_bus->hub_addr == 0) {
1410+
_usbh_data.attach_debouncing_bm &= (uint8_t) ~TU_BIT(dev0_bus->rhport);
1411+
}
1412+
14091413
if (dev0_bus->hub_addr == 0) {
14101414
// connected directly to roothub
14111415
// USB bus not active and frame number is not available yet.
@@ -1570,8 +1574,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
15701574
}
15711575

15721576
case ENUM_GET_DEVICE_DESC: {
1573-
// Allow 2ms for address recovery time, Ref USB Spec 9.2.6.3
1574-
tusb_time_delay_ms_api(2);
1577+
tusb_time_delay_ms_api(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS); // set address recovery
15751578

15761579
const uint8_t new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue);
15771580
usbh_device_t* new_dev = get_device(new_addr);

src/host/usbh.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ typedef struct {
8686
uint8_t speed;
8787
} tuh_bus_info_t;
8888

89+
// backward compatibility for hcd_devtree_info_t, maybe removed in the future
90+
#define hcd_devtree_info_t tuh_bus_info_t
91+
#define hcd_devtree_get_info(_daddr, _bus_info) tuh_bus_info_get(_daddr, _bus_info)
8992

9093
// ConfigID for tuh_configure()
9194
enum {

0 commit comments

Comments
 (0)