Read hub descriptor

This commit is contained in:
PaulStoffregen 2017-02-11 13:44:23 -08:00
parent eb807023db
commit 326ecbe228
3 changed files with 67 additions and 12 deletions

View File

@ -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];
};

View File

@ -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 ");

41
hub.cpp
View File

@ -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
*/