diff --git a/USBHost.h b/USBHost.h index c30d296..ae28786 100644 --- a/USBHost.h +++ b/USBHost.h @@ -63,6 +63,7 @@ struct Device_struct { Pipe_t *control_pipe; Device_t *next; setup_t setup; + USBHostDriver *driver[6]; uint8_t speed; // 0=12, 1=1.5, 2=480 Mbit/sec uint8_t address; uint8_t hub_address; @@ -159,6 +160,12 @@ protected: static void print_hexbytes(const void *ptr, uint32_t len); static void print(const char *s); static void print(const char *s, int num); + static void mk_setup(setup_t &s, uint32_t bmRequestType, uint32_t bRequest, + uint32_t wValue, uint32_t wIndex, uint32_t wLength) { + s.word1 = bmRequestType | (bRequest << 8) | (wValue << 16); + s.word2 = wIndex | (wLength << 16); + } + }; @@ -174,6 +181,9 @@ public: virtual bool claim_interface(Device_t *device, const uint8_t *descriptors) { return false; } + virtual bool control_callback(const Transfer_t *transfer) { + return false; + } virtual void disconnect() { } @@ -182,9 +192,11 @@ public: class USBHub : public USBHostDriver { public: - USBHub(); // { driver_ready_for_device(this); } + USBHub(); virtual bool claim_device(Device_t *device, const uint8_t *descriptors); - + virtual bool control_callback(const Transfer_t *transfer); + setup_t setup; + uint8_t hub_desc[12]; }; diff --git a/enumeration.cpp b/enumeration.cpp index 9a9ef66..12b29c9 100644 --- a/enumeration.cpp +++ b/enumeration.cpp @@ -29,8 +29,6 @@ static USBHostDriver *available_drivers = NULL; static uint8_t enumbuf[256] __attribute__ ((aligned(16))); -static void mk_setup(setup_t &s, uint32_t bmRequestType, uint32_t bRequest, - uint32_t wValue, uint32_t wIndex, uint32_t wLength); static void claim_drivers(Device_t *dev); static uint32_t assign_addr(void); static void pipe_set_maxlen(Pipe_t *pipe, uint32_t maxlen); @@ -206,6 +204,8 @@ void USBHost::enumeration(const Transfer_t *transfer) Serial.println(enumbuf[4]); Serial.print("bConfigurationValue = "); Serial.println(enumbuf[5]); + dev->bmAttributes = enumbuf[7]; + dev->bMaxPower = enumbuf[8]; // TODO: actually do something with interface descriptor? mk_setup(dev->setup, 0, 9, enumbuf[5], 0, 0); // 9=SET_CONFIGURATION new_Transfer(dev->control_pipe, NULL, 0); @@ -217,7 +217,15 @@ void USBHost::enumeration(const Transfer_t *transfer) // TODO: unlock exclusive access to enumeration process // if any detected devices are waiting, start the first return; - case 15: // control transfers for other stuff?? + case 15: // control transfers for other stuff? + // TODO: handle other standard control: set/clear feature, etc + for (unsigned int i=0; i < 6; i++) { + if (dev->driver[i] == NULL) break; // no more drivers + if (dev->driver[i]->control_callback(transfer)) { + // this driver processed the control transfer reply + return; + } + } default: return; } @@ -237,6 +245,7 @@ static void claim_drivers(Device_t *dev) available_drivers = driver->next; } driver->next = NULL; + dev->driver[0] = driver; return; } prev = driver; @@ -250,13 +259,6 @@ static uint32_t assign_addr(void) return 29; // TODO: when multiple devices, assign a unique address } -static void mk_setup(setup_t &s, uint32_t bmRequestType, uint32_t bRequest, - uint32_t wValue, uint32_t wIndex, uint32_t wLength) -{ - s.word1 = bmRequestType | (bRequest << 8) | (wValue << 16); - s.word2 = wIndex | (wLength << 16); -} - static void pipe_set_maxlen(Pipe_t *pipe, uint32_t maxlen) { Serial.print("pipe_set_maxlen "); diff --git a/hub.cpp b/hub.cpp index 57b561f..a3cc7e9 100644 --- a/hub.cpp +++ b/hub.cpp @@ -35,8 +35,26 @@ bool USBHub::claim_device(Device_t *dev, const uint8_t *descriptors) Serial.print("USBHub claim_device this="); Serial.println((uint32_t)this, HEX); + // check for HUB type if (dev->bDeviceClass != 9 || dev->bDeviceSubClass != 0) return false; + // protocol must be 0=FS, 1=HS Single-TT, or 2=HS Multi-TT + if (dev->bDeviceProtocol > 2) return false; + // check for endpoint descriptor + if (descriptors[9] != 7 || descriptors[10] != 5) return false; + // endpoint must be IN direction + if ((descriptors[11] & 0xF0) != 0x80) return false; + // endpoint type must be interrupt + if (descriptors[12] != 3) return false; + // get the endpoint number, must not be zero + uint32_t endpoint = descriptors[11] & 0x0F; + if (endpoint == 0) return false; + // get the maximum packet size + uint32_t maxsize = descriptors[13] | (descriptors[14] << 8); + Serial.println(descriptors[9]); + Serial.println(descriptors[10]); + Serial.println(descriptors[11], HEX); + Serial.println(maxsize); // bDeviceProtocol = 0 is full speed // bDeviceProtocol = 1 is high speed single TT // bDeviceProtocol = 2 is high speed multiple TT @@ -48,6 +66,29 @@ bool USBHub::claim_device(Device_t *dev, const uint8_t *descriptors) Serial.print("bDeviceProtocol = "); Serial.println(dev->bDeviceProtocol); + mk_setup(dev->setup, 0xA0, 6, 0x2900, 0, sizeof(hub_desc)); + new_Transfer(dev->control_pipe, hub_desc, sizeof(hub_desc)); + // TODO: need to arrange for callback to this driver from enumeration.cpp + return true; } +bool USBHub::control_callback(const Transfer_t *transfer) +{ + Serial.println("USBHub control callback"); + print_hexbytes(transfer->buffer, transfer->length); + + return true; +} + + +/* +config descriptor from a Multi-TT hub +09 02 29 00 01 01 00 E0 32 +09 04 00 00 01 09 00 01 00 +07 05 81 03 01 00 0C +09 04 00 01 01 09 00 02 00 +07 05 81 03 01 00 0C +*/ + +