summaryrefslogtreecommitdiff
path: root/src/usbh_driver_hub.c
diff options
context:
space:
mode:
authorAmir Hammad <amirhammad@users.noreply.github.com>2016-09-11 13:40:59 +0200
committerGitHub <noreply@github.com>2016-09-11 13:40:59 +0200
commit5e714edfa65f2f0d18fe9dc722ccd564a04e152a (patch)
tree5e310e07bdfb28e36d663ccdffbe65f78081187e /src/usbh_driver_hub.c
parent5615b9c938f6e4d05f7fae68b5329346df1238f9 (diff)
parentb7167bf2aff1a7c9cf223dc2a1d2e401f599d5d8 (diff)
downloadsecure-hid-5e714edfa65f2f0d18fe9dc722ccd564a04e152a.tar.gz
secure-hid-5e714edfa65f2f0d18fe9dc722ccd564a04e152a.tar.bz2
secure-hid-5e714edfa65f2f0d18fe9dc722ccd564a04e152a.zip
Merge pull request #4 from amirhammad/core-refactor
Major rework
Diffstat (limited to 'src/usbh_driver_hub.c')
-rw-r--r--src/usbh_driver_hub.c433
1 files changed, 116 insertions, 317 deletions
diff --git a/src/usbh_driver_hub.c b/src/usbh_driver_hub.c
index a7448f5..3f51c68 100644
--- a/src/usbh_driver_hub.c
+++ b/src/usbh_driver_hub.c
@@ -25,9 +25,9 @@
#include "usart_helpers.h"
#include "usbh_config.h"
+#include <stddef.h>
#include <stdint.h>
-
static hub_device_t hub_device[USBH_MAX_HUBS];
static bool initialized = false;
@@ -41,11 +41,11 @@ void hub_driver_init(void)
for (i = 0; i < USBH_MAX_HUBS; i++) {
hub_device[i].device[0] = 0;
hub_device[i].ports_num = 0;
- hub_device[i].current_port = -1;
+ hub_device[i].current_port = CURRENT_PORT_NONE;
}
}
-static void *init(void *usbh_dev)
+static void *init(usbh_device_t *usbh_dev)
{
if (!initialized) {
LOG_PRINTF("\n%s/%d : driver not initialized\n", __FILE__, __LINE__);
@@ -53,24 +53,23 @@ static void *init(void *usbh_dev)
}
uint32_t i;
- hub_device_t *drvdata = 0;
+ hub_device_t *drvdata = NULL;
// find free data space for hub device
for (i = 0; i < USBH_MAX_HUBS; i++) {
if (hub_device[i].device[0] == 0) {
break;
}
}
- LOG_PRINTF("%{%d}",i);
- LOG_FLUSH();
+ LOG_PRINTF("{%d}",i);
if (i == USBH_MAX_HUBS) {
- LOG_PRINTF("ERRRRRRR");
+ LOG_PRINTF("Unable to initialize hub driver");
return 0;
}
drvdata = &hub_device[i];
- drvdata->state = 0;
+ drvdata->state = EVENT_STATE_NONE;
drvdata->ports_num = 0;
- drvdata->device[0] = (usbh_device_t *)usbh_dev;
+ drvdata->device[0] = usbh_dev;
drvdata->busy = 0;
drvdata->endpoint_in_address = 0;
drvdata->endpoint_in_maxpacketsize = 0;
@@ -86,13 +85,6 @@ static bool analyze_descriptor(void *drvdata, void *descriptor)
hub_device_t *hub = (hub_device_t *)drvdata;
uint8_t desc_type = ((uint8_t *)descriptor)[1];
switch (desc_type) {
- case USB_DT_CONFIGURATION:
- {
- struct usb_config_descriptor *cfg = (struct usb_config_descriptor*)descriptor;
- hub->buffer[0] = cfg->bConfigurationValue;
- }
- break;
-
case USB_DT_ENDPOINT:
{
struct usb_endpoint_descriptor *ep = (struct usb_endpoint_descriptor *)descriptor;
@@ -110,7 +102,6 @@ static bool analyze_descriptor(void *drvdata, void *descriptor)
case USB_DT_HUB:
{
struct usb_hub_descriptor *desc = (struct usb_hub_descriptor *)descriptor;
- //~ hub->ports_num = desc->head.bNbrPorts;
if ( desc->head.bNbrPorts <= USBH_HUB_MAX_DEVICES) {
hub->ports_num = desc->head.bNbrPorts;
} else {
@@ -127,7 +118,7 @@ static bool analyze_descriptor(void *drvdata, void *descriptor)
}
if (hub->endpoint_in_address) {
- hub->state = 1;
+ hub->state = EVENT_STATE_INITIAL;
LOG_PRINTF("end enum");
return true;
}
@@ -141,7 +132,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
LOG_PRINTF("\nHUB->STATE = %d\n", hub->state);
switch (hub->state) {
- case 26:
+ case EVENT_STATE_POLL:
switch (cb_data.status) {
case USBH_PACKET_CALLBACK_STATUS_OK:
{
@@ -157,7 +148,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
// Driver error... port not found
if (!psc) {
// Continue reading status change endpoint
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
break;
}
@@ -172,119 +163,45 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
if (hub->current_port >= 1) {
if (hub->current_port != port) {
LOG_PRINTF("X");
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
break;
}
}
struct usb_setup_data setup_data;
// If regular port event, else hub event
if (port) {
- setup_data.bmRequestType = 0b10100011;
+ setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT;
} else {
- setup_data.bmRequestType = 0b10100000;
+ setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE;
}
setup_data.bRequest = USB_REQ_GET_STATUS;
setup_data.wValue = 0;
setup_data.wIndex = port;
setup_data.wLength = 4;
- hub->state = 31;
+ hub->state = EVENT_STATE_GET_STATUS_COMPLETE;
hub->current_port = port;
LOG_PRINTF("\n\nPORT FOUND: %d\n", port);
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ device_control(dev, event, &setup_data, &hub->hub_and_port_status[port]);
}
break;
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
+ default:
ERROR(cb_data.status);
- hub->state = 0;
+ hub->state = EVENT_STATE_NONE;
break;
case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
// In case of EAGAIN error, retry read on status endpoint
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
LOG_PRINTF("HUB: Retrying...\n");
break;
}
break;
- case EMPTY_PACKET_READ_STATE:
- {
- LOG_PRINTF("|empty packet read|");
- switch (cb_data.status) {
- case USBH_PACKET_CALLBACK_STATUS_OK:
- device_xfer_control_read(0, 0, event, dev);
- hub->state = hub->state_after_empty_read;
- hub->state_after_empty_read = 0;
- break;
-
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
- hub->state = hub->state_after_empty_read;
- event(dev, cb_data);
- break;
- }
- }
- break;
-
- case 3: // Get HUB Descriptor write
- {
- switch (cb_data.status) {
- case USBH_PACKET_CALLBACK_STATUS_OK:
- if (hub->ports_num) {
- hub->index = 0;
- hub->state = 6;
- LOG_PRINTF("No need to get HUB DESC\n");
- event(dev, cb_data);
- } else {
- hub->endpoint_in_toggle = 0;
-
- struct usb_setup_data setup_data;
- hub->desc_len = hub->device[0]->packet_size_max0;
-
- setup_data.bmRequestType = 0b10100000;
- setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
- setup_data.wValue = 0x29<<8;
- setup_data.wIndex = 0;
- setup_data.wLength = hub->desc_len;
-
- hub->state++;
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
- LOG_PRINTF("DO Need to get HUB DESC\n");
- }
- break;
-
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
- ERROR(cb_data.status);
- break;
- }
- }
- break;
-
- case 4: // Get HUB Descriptor read
- {
- switch (cb_data.status) {
- case USBH_PACKET_CALLBACK_STATUS_OK:
- hub->state++;
- device_xfer_control_read(hub->buffer, hub->desc_len, event, dev); // "error dynamic size" - bad comment, investigate
- break;
-
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
- ERROR(cb_data.status);
- break;
- }
- }
- break;
-
- case 5:// Hub descriptor found
+ case EVENT_STATE_READ_HUB_DESCRIPTOR_COMPLETE:// Hub descriptor found
{
switch (cb_data.status) {
case USBH_PACKET_CALLBACK_STATUS_OK:
@@ -297,19 +214,19 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
struct usb_setup_data setup_data;
hub->desc_len = hub_descriptor->head.bDescLength;
- setup_data.bmRequestType = 0b10100000;
+ setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE;
setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
setup_data.wValue = 0x29<<8;
setup_data.wIndex = 0;
setup_data.wLength = hub->desc_len;
- hub->state = 4;
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ hub->state = EVENT_STATE_READ_HUB_DESCRIPTOR_COMPLETE;
+ device_control(dev, event, &setup_data, hub->buffer);
break;
} else if (hub_descriptor->head.bDescLength == hub->desc_len) {
hub->ports_num = hub_descriptor->head.bNbrPorts;
- hub->state++;
+ hub->state = EVENT_STATE_ENABLE_PORTS;
hub->index = 0;
cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
event(dev, cb_data);
@@ -334,7 +251,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
LOG_PRINTF("INCREASE NUMBER OF ENABLED PORTS\n");
hub->ports_num = USBH_HUB_MAX_DEVICES;
}
- hub->state++;
+ hub->state = EVENT_STATE_ENABLE_PORTS;
hub->index = 0;
cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
@@ -344,15 +261,14 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
}
break;
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
+ default:
ERROR(cb_data.status);
break;
}
}
break;
- case 6:// enable ports
+ case EVENT_STATE_ENABLE_PORTS:// enable ports
{
switch (cb_data.status) {
case USBH_PACKET_CALLBACK_STATUS_OK:
@@ -361,182 +277,76 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
struct usb_setup_data setup_data;
LOG_PRINTF("[!%d!]",hub->index);
- setup_data.bmRequestType = 0b00100011;
+ setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT;
setup_data.bRequest = HUB_REQ_SET_FEATURE;
setup_data.wValue = HUB_FEATURE_PORT_POWER;
setup_data.wIndex = hub->index;
setup_data.wLength = 0;
- hub->state_after_empty_read = hub->state;
- hub->state = EMPTY_PACKET_READ_STATE;
-
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ device_control(dev, event, &setup_data, 0);
} else {
- hub->state++;
// TODO:
// Delay Based on hub descriptor field bPwr2PwrGood
// delay_ms_busy_loop(200);
LOG_PRINTF("\nHUB CONFIGURED & PORTS POWERED\n");
- cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
- event(dev, cb_data);
- }
- break;
-
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
- ERROR(cb_data.status);
- break;
- }
- }
- break;
-
- case 7:
- {
- switch (cb_data.status) {
- case USBH_PACKET_CALLBACK_STATUS_OK:
- {
+ // get device status
struct usb_setup_data setup_data;
- setup_data.bmRequestType = 0b10100000;
+ setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE;
setup_data.bRequest = USB_REQ_GET_STATUS;
setup_data.wValue = 0;
setup_data.wIndex = 0;
setup_data.wLength = 4;
- hub->state++;
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ hub->state = EVENT_STATE_GET_PORT_STATUS;
+ hub->index = 0;
+ device_control(dev, event, &setup_data, hub->buffer);
}
break;
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
- ERROR(cb_data.status);
- break;
- }
-
- }
- break;
- case 8:
- {
- switch (cb_data.status) {
- case USBH_PACKET_CALLBACK_STATUS_OK:
- device_xfer_control_read(hub->buffer, 4, event, dev);
- hub->index = 0;
- hub->state++;
- break;
-
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
+ default:
ERROR(cb_data.status);
break;
}
}
break;
- case 9:
+ case EVENT_STATE_GET_PORT_STATUS:
{
switch (cb_data.status) {
case USBH_PACKET_CALLBACK_STATUS_OK:
{
- struct usb_setup_data setup_data;
-
- setup_data.bmRequestType = 0b10100011;
- setup_data.bRequest = USB_REQ_GET_STATUS;
- setup_data.wValue = 0;
- setup_data.wIndex = ++hub->index;
- setup_data.wLength = 4;
-
- hub->state++;
+ if (hub->index < hub->ports_num) {
+ //TODO: process data contained in hub->buffer
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
- }
- break;
-
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
- ERROR(cb_data.status);
- break;
- }
- }
- break;
+ struct usb_setup_data setup_data;
- case 10:
- {
- switch (cb_data.status) {
- case USBH_PACKET_CALLBACK_STATUS_OK:
- device_xfer_control_read(hub->buffer, 4, event, dev);
- hub->state++;
- break;
+ setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT;
+ setup_data.bRequest = USB_REQ_GET_STATUS;
+ setup_data.wValue = 0;
+ setup_data.wIndex = ++hub->index;
+ setup_data.wLength = 4;
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
- ERROR(cb_data.status);
- break;
- }
- }
- break;
+ hub->state = EVENT_STATE_GET_PORT_STATUS;
+ device_control(dev, event, &setup_data, hub->buffer);
+ } else {
+ hub->busy = 0;
+ hub->state = EVENT_STATE_POLL_REQ;
+ }
- case 11:
- {
- switch (cb_data.status) {
- case USBH_PACKET_CALLBACK_STATUS_OK:
- if (hub->index < hub->ports_num) {
- hub->state = 9;
- // process data contained in hub->buffer
- // TODO:
- cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
- event(dev, cb_data);
- } else {
- hub->busy = 0;
- hub->state = 25;
}
break;
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
+ default:
ERROR(cb_data.status);
break;
}
}
break;
- case 31: // Read port status
- {
- switch (cb_data.status) {
- case USBH_PACKET_CALLBACK_STATUS_OK:
- {
- int8_t port = hub->current_port;
- hub->state++;
-
- // TODO: rework to endianess aware,
- // (maybe whole library is affected by this)
- // Detail:
- // Isn't universal. Here is endianess ok,
- // but on another architecture may be incorrect
- device_xfer_control_read(&hub->hub_and_port_status[port], 4, event, dev);
- }
- break;
-
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
- ERROR(cb_data.status);
- // continue
- hub->state = 25;
- break;
- }
-
- }
- break;
- case 32:
+ case EVENT_STATE_GET_STATUS_COMPLETE:
{
switch (cb_data.status) {
case USBH_PACKET_CALLBACK_STATUS_OK:
@@ -556,7 +366,7 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
if (!hub->device[port]) {
if (!usbh_enum_available() || hub->busy) {
LOG_PRINTF("\n\t\t\tCannot enumerate %d %d\n", !usbh_enum_available(), hub->busy);
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
break;
}
}
@@ -564,54 +374,49 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
// clear feature C_PORT_CONNECTION
struct usb_setup_data setup_data;
- setup_data.bmRequestType = 0b00100011;
+ setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT;
setup_data.bRequest = HUB_REQ_CLEAR_FEATURE;
setup_data.wValue = HUB_FEATURE_C_PORT_CONNECTION;
setup_data.wIndex = port;
setup_data.wLength = 0;
- hub->state_after_empty_read = 33;
- hub->state = EMPTY_PACKET_READ_STATE;
-
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ hub->state = EVENT_STATE_PORT_RESET_REQ;
+ device_control(dev, event, &setup_data, 0);
} else if(stc & (1<<HUB_FEATURE_PORT_RESET)) {
// clear feature C_PORT_RESET
// Reset processing is complete, enumerate device
struct usb_setup_data setup_data;
- setup_data.bmRequestType = 0b00100011;
+ setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT;
setup_data.bRequest = HUB_REQ_CLEAR_FEATURE;
setup_data.wValue = HUB_FEATURE_C_PORT_RESET;
setup_data.wIndex = port;
setup_data.wLength = 0;
- hub->state_after_empty_read = 35;
- hub->state = EMPTY_PACKET_READ_STATE;
+ hub->state = EVENT_STATE_PORT_RESET_COMPLETE;
LOG_PRINTF("RESET");
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ device_control(dev, event, &setup_data, 0);
} else {
LOG_PRINTF("another STC %d\n", stc);
}
} else {
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
LOG_PRINTF("HUB status change\n");
}
}
break;
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
+ default:
ERROR(cb_data.status);
// continue
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
break;
}
}
break;
- case 33:
+ case EVENT_STATE_PORT_RESET_REQ:
{
switch (cb_data.status) {
case USBH_PACKET_CALLBACK_STATUS_OK:
@@ -622,48 +427,40 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
if ((stc) & (1<<HUB_FEATURE_PORT_CONNECTION)) {
struct usb_setup_data setup_data;
- setup_data.bmRequestType = 0b00100011;
+ setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT;
setup_data.bRequest = HUB_REQ_SET_FEATURE;
setup_data.wValue = HUB_FEATURE_PORT_RESET;
setup_data.wIndex = port;
setup_data.wLength = 0;
- hub->state_after_empty_read = 11;
- hub->state = EMPTY_PACKET_READ_STATE;
+ hub->state = EVENT_STATE_GET_PORT_STATUS;
LOG_PRINTF("CONN");
hub->busy = 1;
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ device_control(dev, event, &setup_data, 0);
}
} else {
LOG_PRINTF("\t\t\t\tDISCONNECT EVENT\n");
- if (hub->device[port]->drv && hub->device[port]->drvdata) {
- hub->device[port]->drv->remove(hub->device[port]->drvdata);
- }
- hub->device[port]->address = -1;
+ device_remove(hub->device[port]);
- hub->device[port]->drv = 0;
- hub->device[port]->drvdata = 0;
hub->device[port] = 0;
hub->current_port = CURRENT_PORT_NONE;
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
hub->busy = 0;
}
}
break;
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
+ default:
ERROR(cb_data.status);
// continue
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
break;
}
}
break;
- case 35: // RESET COMPLETE, start enumeration
+ case EVENT_STATE_PORT_RESET_COMPLETE: // RESET COMPLETE, start enumeration
{
switch (cb_data.status) {
case USBH_PACKET_CALLBACK_STATUS_OK:
@@ -682,46 +479,52 @@ static void event(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
}
if ((sts & (1<<(HUB_FEATURE_PORT_LOWSPEED))) &&
!(sts & (1<<(HUB_FEATURE_PORT_HIGHSPEED)))) {
+#define DISABLE_LOW_SPEED
+#ifdef DISABLE_LOW_SPEED
LOG_PRINTF("Low speed device");
// Disable Low speed device immediately
struct usb_setup_data setup_data;
- setup_data.bmRequestType = 0b00100011;
+ setup_data.bmRequestType = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE | USB_REQ_TYPE_ENDPOINT;
setup_data.bRequest = HUB_REQ_CLEAR_FEATURE;
setup_data.wValue = HUB_FEATURE_PORT_ENABLE;
setup_data.wIndex = port;
setup_data.wLength = 0;
// After write process another devices, poll for events
- hub->state_after_empty_read = 11;//Expecting all ports are powered (constant/non-changeable after init)
- hub->state = EMPTY_PACKET_READ_STATE;
+ //Expecting all ports are powered (constant/non-changeable after init)
+ hub->state = EVENT_STATE_GET_PORT_STATUS;
hub->current_port = CURRENT_PORT_NONE;
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ device_control(dev, event, &setup_data, 0);
+#else
+ hub->device[port]->speed = USBH_SPEED_LOW;
+ LOG_PRINTF("Low speed device");
+ hub->timestamp_us = hub->time_curr_us;
+ hub->state = EVENT_STATE_SLEEP_500_MS; // schedule wait for 500ms
+#endif
} else if (!(sts & (1<<(HUB_FEATURE_PORT_LOWSPEED))) &&
!(sts & (1<<(HUB_FEATURE_PORT_HIGHSPEED)))) {
hub->device[port]->speed = USBH_SPEED_FULL;
LOG_PRINTF("Full speed device");
hub->timestamp_us = hub->time_curr_us;
- hub->state = 100; // schedule wait for 500ms
+ hub->state = EVENT_STATE_SLEEP_500_MS; // schedule wait for 500ms
}
} else {
LOG_PRINTF("%s:%d Do not know what to do, when device is disabled after reset\n", __FILE__, __LINE__);
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
return;
}
}
break;
- case USBH_PACKET_CALLBACK_STATUS_EFATAL:
- case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
- case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
+ default:
ERROR(cb_data.status);
// continue
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
break;
}
}
@@ -738,7 +541,7 @@ static void read_ep1(void *drvdata)
usbh_packet_t packet;
packet.address = hub->device[0]->address;
- packet.data = hub->buffer;
+ packet.data.in = hub->buffer;
packet.datalen = hub->endpoint_in_maxpacketsize;
packet.endpoint_address = hub->endpoint_in_address;
packet.endpoint_size_max = hub->endpoint_in_maxpacketsize;
@@ -748,7 +551,7 @@ static void read_ep1(void *drvdata)
packet.callback_arg = hub->device[0];
packet.toggle = &hub->endpoint_in_toggle;
- hub->state = 26;
+ hub->state = EVENT_STATE_POLL;
usbh_read(hub->device[0], &packet);
LOG_PRINTF("@hub %d/EP1 | \n", hub->device[0]->address);
@@ -767,7 +570,7 @@ static void poll(void *drvdata, uint32_t time_curr_us)
hub->time_curr_us = time_curr_us;
switch (hub->state) {
- case 25:
+ case EVENT_STATE_POLL_REQ:
{
if (usbh_enum_available()) {
read_ep1(hub);
@@ -777,28 +580,36 @@ static void poll(void *drvdata, uint32_t time_curr_us)
}
break;
- case 1:
+ case EVENT_STATE_INITIAL:
{
- LOG_PRINTF("CFGVAL: %d\n", hub->buffer[0]);
- struct usb_setup_data setup_data;
+ if (hub->ports_num) {
+ hub->index = 0;
+ hub->state = EVENT_STATE_ENABLE_PORTS;
+ LOG_PRINTF("No need to get HUB DESC\n");
+ event(dev, (usbh_packet_callback_data_t){0, 0});
+ } else {
+ hub->endpoint_in_toggle = 0;
- setup_data.bmRequestType = 0b00000000;
- setup_data.bRequest = USB_REQ_SET_CONFIGURATION;
- setup_data.wValue = hub->buffer[0];
- setup_data.wIndex = 0;
- setup_data.wLength = 0;
+ struct usb_setup_data setup_data;
+ hub->desc_len = hub->device[0]->packet_size_max0;
- hub->state = EMPTY_PACKET_READ_STATE;
- hub->state_after_empty_read = 3;
- device_xfer_control_write_setup(&setup_data, sizeof(setup_data), event, dev);
+ setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE;
+ setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
+ setup_data.wValue = 0x29 << 8;
+ setup_data.wIndex = 0;
+ setup_data.wLength = hub->desc_len;
+ hub->state = EVENT_STATE_READ_HUB_DESCRIPTOR_COMPLETE;
+ device_control(dev, event, &setup_data, hub->buffer);
+ LOG_PRINTF("DO Need to get HUB DESC\n");
+ }
}
break;
- case 100:
+ case EVENT_STATE_SLEEP_500_MS:
if (hub->time_curr_us - hub->timestamp_us > 500000) {
int8_t port = hub->current_port;
- LOG_PRINTF("PORT: %d", port);
- LOG_PRINTF("\nNEW device at address: %d\n", hub->device[port]->address);
+ LOG_PRINTF("PORT: %d\n", port);
+ LOG_PRINTF("NEW device at address: %d\n", hub->device[port]->address);
hub->device[port]->lld = hub->device[0]->lld;
device_enumeration_start(hub->device[port]);
@@ -812,7 +623,7 @@ static void poll(void *drvdata, uint32_t time_curr_us)
// Only one device on bus can have address==0
hub->busy = 0;
- hub->state = 25;
+ hub->state = EVENT_STATE_POLL_REQ;
}
break;
default:
@@ -835,23 +646,11 @@ static void remove(void *drvdata)
hub_device_t *hub = (hub_device_t *)drvdata;
uint8_t i;
- // Call fast... to avoid polling
- hub->state = 0;
+ hub->state = EVENT_STATE_NONE;
hub->endpoint_in_address = 0;
hub->busy = 0;
- for (i = 1; i < USBH_HUB_MAX_DEVICES + 1; i++) {
- if (hub->device[i]) {
- if (hub->device[i]->drv && hub->device[i]->drvdata) {
- if (hub->device[i]->drv->remove != remove) {
- LOG_PRINTF("\t\t\t\tHUB REMOVE %d\n",hub->device[i]->address);
- hub->device[i]->drv->remove(hub->device[i]->drvdata);
- }
- }
- hub->device[i] = 0;
- }
- hub->device[0]->drv = 0;
- hub->device[0]->drvdata = 0;
- hub->device[0] = 0;
+ for (i = 0; i < USBH_HUB_MAX_DEVICES + 1; i++) {
+ hub->device[i] = 0;
}
}