mirror of
https://github.com/gdsports/USBHost_t36
synced 2025-02-16 06:50:14 -05:00
initialize hubs
This commit is contained in:
parent
a45a462931
commit
93c40091da
16
USBHost.h
16
USBHost.h
@ -96,7 +96,7 @@ struct Pipe_struct {
|
|||||||
uint8_t type; // 0=control, 1=isochronous, 2=bulk, 3=interrupt
|
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 direction; // 0=out, 1=in (changes for control, others fixed)
|
||||||
uint8_t unusedbyte[2];
|
uint8_t unusedbyte[2];
|
||||||
void *callback_object; // TODO: C++ callbacks??
|
USBDriver *callback_object;
|
||||||
void (*callback_function)(const Transfer_t *);
|
void (*callback_function)(const Transfer_t *);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ protected:
|
|||||||
}
|
}
|
||||||
// Drivers are managed by this single-linked list. All inactive
|
// Drivers are managed by this single-linked list. All inactive
|
||||||
// (not bound to any device) drivers are linked from
|
// (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.
|
// drivers are linked from that Device_t drivers list.
|
||||||
USBDriver *next;
|
USBDriver *next;
|
||||||
// When not bound to any device, this must be NULL.
|
// When not bound to any device, this must be NULL.
|
||||||
@ -226,9 +226,17 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors);
|
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors);
|
||||||
virtual bool control(const Transfer_t *transfer);
|
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
|
setup_t setup; // TODO: use this for our control transfers, not device's
|
||||||
uint8_t hub_desc[12];
|
uint8_t hub_desc[16];
|
||||||
uint32_t change;
|
uint8_t endpoint;
|
||||||
|
uint8_t numports;
|
||||||
|
uint8_t characteristics;
|
||||||
|
uint8_t powertime;
|
||||||
|
uint8_t state;
|
||||||
|
Pipe_t *changepipe;
|
||||||
|
uint32_t changebits;
|
||||||
|
uint32_t status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ static void pipe_set_addr(Pipe_t *pipe, uint32_t addr);
|
|||||||
|
|
||||||
void USBHost::driver_ready_for_device(USBDriver *driver)
|
void USBHost::driver_ready_for_device(USBDriver *driver)
|
||||||
{
|
{
|
||||||
|
driver->device = NULL;
|
||||||
driver->next = NULL;
|
driver->next = NULL;
|
||||||
if (available_drivers == NULL) {
|
if (available_drivers == NULL) {
|
||||||
available_drivers = driver;
|
available_drivers = driver;
|
||||||
|
50
hub.cpp
50
hub.cpp
@ -49,10 +49,12 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
|
|||||||
// endpoint type must be interrupt
|
// endpoint type must be interrupt
|
||||||
if (descriptors[12] != 3) return false;
|
if (descriptors[12] != 3) return false;
|
||||||
// get the endpoint number, must not be zero
|
// get the endpoint number, must not be zero
|
||||||
uint32_t endpoint = descriptors[11] & 0x0F;
|
endpoint = descriptors[11] & 0x0F;
|
||||||
if (endpoint == 0) return false;
|
if (endpoint == 0) return false;
|
||||||
// get the maximum packet size
|
// get the maximum packet size
|
||||||
uint32_t maxsize = descriptors[13] | (descriptors[14] << 8);
|
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[9]);
|
||||||
Serial.println(descriptors[10]);
|
Serial.println(descriptors[10]);
|
||||||
@ -69,6 +71,10 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
|
|||||||
Serial.print("bDeviceProtocol = ");
|
Serial.print("bDeviceProtocol = ");
|
||||||
Serial.println(dev->bDeviceProtocol);
|
Serial.println(dev->bDeviceProtocol);
|
||||||
|
|
||||||
|
changepipe = NULL;
|
||||||
|
changebits = 0;
|
||||||
|
state = 0;
|
||||||
|
|
||||||
// TODO: need a way to do control transfers with our own setup data.
|
// TODO: need a way to do control transfers with our own setup data.
|
||||||
mk_setup(dev->setup, 0xA0, 6, 0x2900, 0, sizeof(hub_desc));
|
mk_setup(dev->setup, 0xA0, 6, 0x2900, 0, sizeof(hub_desc));
|
||||||
new_Transfer(dev->control_pipe, hub_desc, 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;
|
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)
|
bool USBHub::control(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
if (transfer->buffer == hub_desc) {
|
Serial.println("USBHub control callback");
|
||||||
Serial.println("USBHub control callback");
|
print_hexbytes(transfer->buffer, transfer->length);
|
||||||
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) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user