optimise hub debounce process
This commit is contained in:
@@ -7,8 +7,9 @@
|
|||||||
|
|
||||||
#define DEV_FORMAT "/dev/hub%d"
|
#define DEV_FORMAT "/dev/hub%d"
|
||||||
|
|
||||||
#define DEBOUNCE_TIMEOUT 400
|
#define HUB_DEBOUNCE_TIMEOUT 1500
|
||||||
#define DEBOUNCE_TIME_STEP 25
|
#define HUB_DEBOUNCE_STEP 25
|
||||||
|
#define HUB_DEBOUNCE_STABLE 100
|
||||||
#define DELAY_TIME_AFTER_RESET 200
|
#define DELAY_TIME_AFTER_RESET 200
|
||||||
|
|
||||||
#define EXTHUB_FIRST_INDEX 2
|
#define EXTHUB_FIRST_INDEX 2
|
||||||
@@ -351,6 +352,20 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void usbh_hubport_release(struct usbh_hubport *child)
|
||||||
|
{
|
||||||
|
if (child->connected) {
|
||||||
|
child->connected = false;
|
||||||
|
usbh_hport_deactivate_ep0(child);
|
||||||
|
for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
|
||||||
|
if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
|
||||||
|
CLASS_DISCONNECT(child, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child->config.config_desc.bNumInterfaces = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void usbh_hub_events(struct usbh_hub *hub)
|
static void usbh_hub_events(struct usbh_hub *hub)
|
||||||
{
|
{
|
||||||
struct usbh_hubport *child;
|
struct usbh_hubport *child;
|
||||||
@@ -412,8 +427,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
|||||||
if (portchange & HUB_PORT_STATUS_C_CONNECTION) {
|
if (portchange & HUB_PORT_STATUS_C_CONNECTION) {
|
||||||
uint16_t connection = 0;
|
uint16_t connection = 0;
|
||||||
uint16_t debouncestable = 0;
|
uint16_t debouncestable = 0;
|
||||||
for (uint32_t debouncetime = 0; debouncetime < DEBOUNCE_TIMEOUT; debouncetime += DEBOUNCE_TIME_STEP) {
|
for (uint32_t debouncetime = 0; debouncetime < HUB_DEBOUNCE_TIMEOUT; debouncetime += HUB_DEBOUNCE_STEP) {
|
||||||
usb_osal_msleep(DEBOUNCE_TIME_STEP);
|
|
||||||
/* Read hub port status */
|
/* Read hub port status */
|
||||||
ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
|
ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -425,21 +439,29 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
|||||||
portchange = port_status.wPortChange;
|
portchange = port_status.wPortChange;
|
||||||
|
|
||||||
USB_LOG_DBG("Port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
USB_LOG_DBG("Port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||||
if ((portstatus & HUB_PORT_STATUS_CONNECTION) == connection) {
|
|
||||||
if (connection) {
|
if (!(portchange & HUB_PORT_STATUS_C_CONNECTION) &&
|
||||||
if (++debouncestable == 4) {
|
((portstatus & HUB_PORT_STATUS_CONNECTION) == connection)) {
|
||||||
break;
|
debouncestable += HUB_DEBOUNCE_STEP;
|
||||||
}
|
if (debouncestable >= HUB_DEBOUNCE_STABLE) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debouncestable = 0;
|
debouncestable = 0;
|
||||||
|
connection = portstatus & HUB_PORT_STATUS_CONNECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection = portstatus & HUB_PORT_STATUS_CONNECTION;
|
|
||||||
|
|
||||||
if (portchange & HUB_PORT_STATUS_C_CONNECTION) {
|
if (portchange & HUB_PORT_STATUS_C_CONNECTION) {
|
||||||
usbh_hub_clear_feature(hub, port + 1, HUB_PORT_FEATURE_C_CONNECTION);
|
usbh_hub_clear_feature(hub, port + 1, HUB_PORT_FEATURE_C_CONNECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usb_osal_msleep(HUB_DEBOUNCE_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** check if debounce ok */
|
||||||
|
if (debouncestable < HUB_DEBOUNCE_STABLE) {
|
||||||
|
USB_LOG_ERR("Failed to debounce port %u\r\n", port + 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Last, check connect status */
|
/* Last, check connect status */
|
||||||
@@ -477,16 +499,8 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
|||||||
}
|
}
|
||||||
|
|
||||||
child = &hub->child[port];
|
child = &hub->child[port];
|
||||||
if (child->connected) {
|
/** release child sources first */
|
||||||
child->connected = false;
|
usbh_hubport_release(child);
|
||||||
usbh_hport_deactivate_ep0(child);
|
|
||||||
for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
|
|
||||||
if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
|
|
||||||
CLASS_DISCONNECT(child, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
child->config.config_desc.bNumInterfaces = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(child, 0, sizeof(struct usbh_hubport));
|
memset(child, 0, sizeof(struct usbh_hubport));
|
||||||
child->parent = hub;
|
child->parent = hub;
|
||||||
@@ -503,30 +517,15 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
|||||||
USB_LOG_ERR("Failed to enable port %u\r\n", port + 1);
|
USB_LOG_ERR("Failed to enable port %u\r\n", port + 1);
|
||||||
|
|
||||||
child = &hub->child[port];
|
child = &hub->child[port];
|
||||||
if (child->connected) {
|
/** release child sources */
|
||||||
child->connected = false;
|
usbh_hubport_release(child);
|
||||||
usbh_hport_deactivate_ep0(child);
|
|
||||||
for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
|
|
||||||
if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
|
|
||||||
CLASS_DISCONNECT(child, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
child->config.config_desc.bNumInterfaces = 0;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
child = &hub->child[port];
|
child = &hub->child[port];
|
||||||
child->connected = false;
|
/** release child sources */
|
||||||
usbh_hport_deactivate_ep0(child);
|
usbh_hubport_release(child);
|
||||||
for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
|
|
||||||
if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
|
|
||||||
CLASS_DISCONNECT(child, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
USB_LOG_INFO("Device on Hub %u, Port %u disconnected\r\n", hub->index, port + 1);
|
|
||||||
child->config.config_desc.bNumInterfaces = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user