diff options
| author | sakumisu <[email protected]> | 2022-02-18 17:53:46 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2022-02-18 17:53:46 +0800 |
| commit | c2d048f130af51efa3be42c1abdedcf0b3f21e43 (patch) | |
| tree | ffdd1db3346818b6784a97ab00b63a67db0daa69 /class | |
| parent | 7fdd66c632e52c92404ecc872e70da6f033e1433 (diff) | |
add debounce time for hub port change detect
Diffstat (limited to 'class')
| -rw-r--r-- | class/hub/usbh_hub.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/class/hub/usbh_hub.c b/class/hub/usbh_hub.c index 8eb875d9..77cf334e 100644 --- a/class/hub/usbh_hub.c +++ b/class/hub/usbh_hub.c @@ -401,12 +401,47 @@ static void usbh_extern_hub_psc_event(void *arg) /* Handle connect or disconnect, no power management */ if (change & HUB_PORT_STATUS_C_CONNECTION) { - ret = usbh_hub_get_portstatus(hub_class, port, hub_class->port_status); - if (ret < 0) { - USB_LOG_ERR("Failed to read port:%d status, errorcode: %d\r\n", port, ret); + uint16_t debouncetime = 0; + uint16_t debouncestable = 0; + uint16_t connection = 0xffff; + + /* Debounce */ + while (debouncetime < 1500) { + ret = usbh_hub_get_portstatus(hub_class, port, hub_class->port_status); + if (ret < 0) { + USB_LOG_ERR("Failed to read port:%d status, errorcode: %d\r\n", port, ret); + break; + } + status = hub_class->port_status->wPortStatus; + change = hub_class->port_status->wPortChange; + + if ((change & HUB_PORT_STATUS_C_CONNECTION) == 0 && + (status & HUB_PORT_STATUS_CONNECTION) == connection) { + debouncestable += 25; + if (debouncestable >= 100) { + USB_LOG_DBG("Port %d debouncestable=%d\r\n", + port, debouncestable); + break; + } + } else { + debouncestable = 0; + connection = status & HUB_PORT_STATUS_CONNECTION; + } + + if ((change & HUB_PORT_STATUS_C_CONNECTION) != 0) { + ret = usbh_hub_clear_feature(hub_class, port, HUB_PORT_FEATURE_C_CONNECTION); + if (ret < 0) { + USB_LOG_ERR("Failed to clear port:%d, change mask:%04x, errorcode:%d\r\n", port, mask, ret); + } + } + debouncetime += 25; + usb_osal_msleep(25); + } + + if (ret < 0 || debouncetime >= 1500) { + USB_LOG_ERR("ERROR: Failed to debounce port %d: %d\r\n", port, ret); + continue; } - status = hub_class->port_status->wPortStatus; - change = hub_class->port_status->wPortChange; if (status & HUB_PORT_STATUS_CONNECTION) { /* Device connected to a port on the hub */ |
