1
0
mirror of https://github.com/gdsports/USBHost_t36 synced 2024-08-13 16:53:54 -04:00

initialize hubs

This commit is contained in:
PaulStoffregen 2017-02-12 12:03:26 -08:00
parent a45a462931
commit 93c40091da
3 changed files with 54 additions and 13 deletions

View File

@ -96,7 +96,7 @@ struct Pipe_struct {
uint8_t type; // 0=control, 1=isochronous, 2=bulk, 3=interrupt
uint8_t direction; // 0=out, 1=in (changes for control, others fixed)
uint8_t unusedbyte[2];
void *callback_object; // TODO: C++ callbacks??
USBDriver *callback_object;
void (*callback_function)(const Transfer_t *);
};
@ -202,7 +202,7 @@ protected:
}
// Drivers are managed by this single-linked list. All inactive
// (not bound to any device) drivers are linked from
// available_drivers is enumeration.cpp. When bound to a device,
// available_drivers in enumeration.cpp. When bound to a device,
// drivers are linked from that Device_t drivers list.
USBDriver *next;
// When not bound to any device, this must be NULL.
@ -226,9 +226,17 @@ public:
protected:
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors);
virtual bool control(const Transfer_t *transfer);
void poweron(uint32_t port);
setup_t setup; // TODO: use this for our control transfers, not device's
uint8_t hub_desc[12];
uint32_t change;
uint8_t hub_desc[16];
uint8_t endpoint;
uint8_t numports;
uint8_t characteristics;
uint8_t powertime;
uint8_t state;
Pipe_t *changepipe;
uint32_t changebits;
uint32_t status;
};

View File

@ -37,6 +37,7 @@ static void pipe_set_addr(Pipe_t *pipe, uint32_t addr);
void USBHost::driver_ready_for_device(USBDriver *driver)
{
driver->device = NULL;
driver->next = NULL;
if (available_drivers == NULL) {
available_drivers = driver;

50
hub.cpp
View File

@ -49,10 +49,12 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
// 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;
endpoint = descriptors[11] & 0x0F;
if (endpoint == 0) return false;
// get the maximum packet size
uint32_t maxsize = descriptors[13] | (descriptors[14] << 8);
if (maxsize == 0) return false;
if (maxsize > 1) return false; // do hub chips with > 7 ports exist?
Serial.println(descriptors[9]);
Serial.println(descriptors[10]);
@ -69,6 +71,10 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
Serial.print("bDeviceProtocol = ");
Serial.println(dev->bDeviceProtocol);
changepipe = NULL;
changebits = 0;
state = 0;
// TODO: need a way to do control transfers with our own setup data.
mk_setup(dev->setup, 0xA0, 6, 0x2900, 0, sizeof(hub_desc));
new_Transfer(dev->control_pipe, hub_desc, sizeof(hub_desc));
@ -76,19 +82,45 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
return true;
}
void USBHub::poweron(uint32_t port)
{
// TODO: need a way to do control transfers with our own setup data.
mk_setup(device->setup, 0x23, 3, 8, port, 0);
new_Transfer(device->control_pipe, NULL, 0);
}
bool USBHub::control(const Transfer_t *transfer)
{
if (transfer->buffer == hub_desc) {
Serial.println("USBHub control callback");
print_hexbytes(transfer->buffer, transfer->length);
Serial.println("USBHub control callback");
print_hexbytes(transfer->buffer, transfer->length);
if (state == 0) {
// read hub descriptor to learn hub's capabilities
if (transfer->buffer != hub_desc) return false;
// Hub Descriptor, USB 2.0, 11.23.2.1 page 417
if (hub_desc[0] == 9 && hub_desc[1] == 0x29) {
numports = hub_desc[2];
characteristics = hub_desc[3];
powertime = hub_desc[5];
// TODO: do we need to use the DeviceRemovable
// bits to mke synthetic device connect events?
Serial.print("Hub has ");
Serial.print(numports);
Serial.println(" ports");
state = 1;
poweron(1);
}
} else if (state < numports) {
// turn on power to all ports
poweron(++state);
} else if (state == numports) {
Serial.println("power turned on to all ports");
// TODO: create interrupt pipe for status change notifications
changepipe = new_Pipe(device, 3, endpoint, 1, 1);
state = 255;
} else if (state == 255) {
// parse a status response
}
return true;
}