summaryrefslogtreecommitdiff
path: root/class
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2022-02-18 17:53:46 +0800
committersakumisu <[email protected]>2022-02-18 17:53:46 +0800
commitc2d048f130af51efa3be42c1abdedcf0b3f21e43 (patch)
treeffdd1db3346818b6784a97ab00b63a67db0daa69 /class
parent7fdd66c632e52c92404ecc872e70da6f033e1433 (diff)
add debounce time for hub port change detect
Diffstat (limited to 'class')
-rw-r--r--class/hub/usbh_hub.c45
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 */