mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-21 16:45:04 -05:00
Separate setup data for enumeration & drivers
This commit is contained in:
parent
4b2258e5a7
commit
de69cf9af2
15
USBHost.h
15
USBHost.h
@ -62,7 +62,6 @@ typedef union {
|
|||||||
struct Device_struct {
|
struct Device_struct {
|
||||||
Pipe_t *control_pipe;
|
Pipe_t *control_pipe;
|
||||||
Device_t *next;
|
Device_t *next;
|
||||||
setup_t setup; // TODO: move this to static in enumeration.cpp
|
|
||||||
USBDriver *drivers;
|
USBDriver *drivers;
|
||||||
uint8_t speed; // 0=12, 1=1.5, 2=480 Mbit/sec
|
uint8_t speed; // 0=12, 1=1.5, 2=480 Mbit/sec
|
||||||
uint8_t address;
|
uint8_t address;
|
||||||
@ -123,10 +122,12 @@ struct Transfer_struct {
|
|||||||
// of Transfer_t are created, these fields and the
|
// of Transfer_t are created, these fields and the
|
||||||
// interrupt-on-complete bit in the qTD token are only
|
// interrupt-on-complete bit in the qTD token are only
|
||||||
// set in the last Transfer_t of the list.
|
// set in the last Transfer_t of the list.
|
||||||
Pipe_t *pipe;
|
Pipe_t *pipe;
|
||||||
void *buffer;
|
void *buffer;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint32_t unused[3];
|
setup_t *setup;
|
||||||
|
USBDriver *driver;
|
||||||
|
uint32_t unused;
|
||||||
};
|
};
|
||||||
|
|
||||||
/************************************************/
|
/************************************************/
|
||||||
@ -140,7 +141,7 @@ protected:
|
|||||||
static Pipe_t * new_Pipe(Device_t *dev, uint32_t type, uint32_t endpoint,
|
static Pipe_t * new_Pipe(Device_t *dev, uint32_t type, uint32_t endpoint,
|
||||||
uint32_t direction, uint32_t max_packet_len);
|
uint32_t direction, uint32_t max_packet_len);
|
||||||
static bool new_Control_Transfer(Device_t *dev, setup_t *setup,
|
static bool new_Control_Transfer(Device_t *dev, setup_t *setup,
|
||||||
void *buf, USBDriver *driver=NULL);
|
void *buf, USBDriver *driver);
|
||||||
static bool new_Data_Transfer(Pipe_t *pipe, void *buffer,
|
static bool new_Data_Transfer(Pipe_t *pipe, void *buffer,
|
||||||
uint32_t len, USBDriver *driver);
|
uint32_t len, USBDriver *driver);
|
||||||
static Device_t * new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_port);
|
static Device_t * new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_port);
|
||||||
@ -231,7 +232,7 @@ 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);
|
void poweron(uint32_t port);
|
||||||
setup_t setup; // TODO: use this for our control transfers, not device's
|
setup_t setup;
|
||||||
uint8_t hub_desc[16];
|
uint8_t hub_desc[16];
|
||||||
uint8_t endpoint;
|
uint8_t endpoint;
|
||||||
uint8_t numports;
|
uint8_t numports;
|
||||||
|
10
ehci.cpp
10
ehci.cpp
@ -451,6 +451,8 @@ bool USBHost::new_Control_Transfer(Device_t *dev, setup_t *setup, void *buf, USB
|
|||||||
status->pipe = dev->control_pipe;
|
status->pipe = dev->control_pipe;
|
||||||
status->buffer = buf;
|
status->buffer = buf;
|
||||||
status->length = setup->wLength;
|
status->length = setup->wLength;
|
||||||
|
status->setup = setup;
|
||||||
|
status->driver = driver;
|
||||||
status->qtd.next = 1;
|
status->qtd.next = 1;
|
||||||
return queue_Transfer(dev->control_pipe, transfer);
|
return queue_Transfer(dev->control_pipe, transfer);
|
||||||
}
|
}
|
||||||
@ -479,12 +481,16 @@ bool USBHost::queue_Transfer(Pipe_t *pipe, Transfer_t *transfer)
|
|||||||
// copy transfer non-token fields to halt
|
// copy transfer non-token fields to halt
|
||||||
halt->qtd.next = transfer->qtd.next;
|
halt->qtd.next = transfer->qtd.next;
|
||||||
halt->qtd.alt_next = transfer->qtd.alt_next;
|
halt->qtd.alt_next = transfer->qtd.alt_next;
|
||||||
halt->qtd.buffer[0] = transfer->qtd.buffer[0]; // TODO: optimize...
|
halt->qtd.buffer[0] = transfer->qtd.buffer[0]; // TODO: optimize memcpy, all
|
||||||
halt->qtd.buffer[1] = transfer->qtd.buffer[1];
|
halt->qtd.buffer[1] = transfer->qtd.buffer[1]; // fields except token
|
||||||
halt->qtd.buffer[2] = transfer->qtd.buffer[2];
|
halt->qtd.buffer[2] = transfer->qtd.buffer[2];
|
||||||
halt->qtd.buffer[3] = transfer->qtd.buffer[3];
|
halt->qtd.buffer[3] = transfer->qtd.buffer[3];
|
||||||
halt->qtd.buffer[4] = transfer->qtd.buffer[4];
|
halt->qtd.buffer[4] = transfer->qtd.buffer[4];
|
||||||
halt->pipe = pipe;
|
halt->pipe = pipe;
|
||||||
|
halt->buffer = transfer->buffer;
|
||||||
|
halt->length = transfer->length;
|
||||||
|
halt->setup = transfer->setup;
|
||||||
|
halt->driver = transfer->driver;
|
||||||
// find the last qTD we're adding
|
// find the last qTD we're adding
|
||||||
Transfer_t *last = halt;
|
Transfer_t *last = halt;
|
||||||
while ((uint32_t)(last->qtd.next) != 1) last = (Transfer_t *)(last->qtd.next);
|
while ((uint32_t)(last->qtd.next) != 1) last = (Transfer_t *)(last->qtd.next);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
static USBDriver *available_drivers = NULL;
|
static USBDriver *available_drivers = NULL;
|
||||||
static uint8_t enumbuf[256] __attribute__ ((aligned(16)));
|
static uint8_t enumbuf[256] __attribute__ ((aligned(16)));
|
||||||
|
static setup_t enumsetup __attribute__ ((aligned(16)));
|
||||||
|
|
||||||
|
|
||||||
static uint32_t assign_addr(void);
|
static uint32_t assign_addr(void);
|
||||||
@ -80,8 +81,8 @@ Device_t * USBHost::new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_p
|
|||||||
// TODO: exclusive access to enumeration process
|
// TODO: exclusive access to enumeration process
|
||||||
// any new devices detected while enumerating would
|
// any new devices detected while enumerating would
|
||||||
// go onto a waiting list
|
// go onto a waiting list
|
||||||
mk_setup(dev->setup, 0x80, 6, 0x0100, 0, 8); // 6=GET_DESCRIPTOR
|
mk_setup(enumsetup, 0x80, 6, 0x0100, 0, 8); // 6=GET_DESCRIPTOR
|
||||||
new_Control_Transfer(dev, &dev->setup, enumbuf);
|
new_Control_Transfer(dev, &enumsetup, enumbuf, NULL);
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,14 +108,14 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
switch (dev->enum_state) {
|
switch (dev->enum_state) {
|
||||||
case 0: // read 8 bytes of device desc, set max packet, and send set address
|
case 0: // read 8 bytes of device desc, set max packet, and send set address
|
||||||
pipe_set_maxlen(dev->control_pipe, enumbuf[7]);
|
pipe_set_maxlen(dev->control_pipe, enumbuf[7]);
|
||||||
mk_setup(dev->setup, 0, 5, assign_addr(), 0, 0); // 5=SET_ADDRESS
|
mk_setup(enumsetup, 0, 5, assign_addr(), 0, 0); // 5=SET_ADDRESS
|
||||||
new_Control_Transfer(dev, &dev->setup, NULL);
|
new_Control_Transfer(dev, &enumsetup, NULL, NULL);
|
||||||
dev->enum_state = 1;
|
dev->enum_state = 1;
|
||||||
return;
|
return;
|
||||||
case 1: // request all 18 bytes of device descriptor
|
case 1: // request all 18 bytes of device descriptor
|
||||||
pipe_set_addr(dev->control_pipe, dev->setup.wValue);
|
pipe_set_addr(dev->control_pipe, enumsetup.wValue);
|
||||||
mk_setup(dev->setup, 0x80, 6, 0x0100, 0, 18); // 6=GET_DESCRIPTOR
|
mk_setup(enumsetup, 0x80, 6, 0x0100, 0, 18); // 6=GET_DESCRIPTOR
|
||||||
new_Control_Transfer(dev, &dev->setup, enumbuf);
|
new_Control_Transfer(dev, &enumsetup, enumbuf, NULL);
|
||||||
dev->enum_state = 2;
|
dev->enum_state = 2;
|
||||||
return;
|
return;
|
||||||
case 2: // parse 18 device desc bytes
|
case 2: // parse 18 device desc bytes
|
||||||
@ -134,8 +135,8 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
break;
|
break;
|
||||||
case 3: // request Language ID
|
case 3: // request Language ID
|
||||||
len = sizeof(enumbuf) - 4;
|
len = sizeof(enumbuf) - 4;
|
||||||
mk_setup(dev->setup, 0x80, 6, 0x0300, 0, len); // 6=GET_DESCRIPTOR
|
mk_setup(enumsetup, 0x80, 6, 0x0300, 0, len); // 6=GET_DESCRIPTOR
|
||||||
new_Control_Transfer(dev, &dev->setup, enumbuf + 4);
|
new_Control_Transfer(dev, &enumsetup, enumbuf + 4, NULL);
|
||||||
dev->enum_state = 4;
|
dev->enum_state = 4;
|
||||||
return;
|
return;
|
||||||
case 4: // parse Language ID
|
case 4: // parse Language ID
|
||||||
@ -151,8 +152,8 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
break;
|
break;
|
||||||
case 5: // request Manufacturer string
|
case 5: // request Manufacturer string
|
||||||
len = sizeof(enumbuf) - 4;
|
len = sizeof(enumbuf) - 4;
|
||||||
mk_setup(dev->setup, 0x80, 6, 0x0300 | enumbuf[0], dev->LanguageID, len);
|
mk_setup(enumsetup, 0x80, 6, 0x0300 | enumbuf[0], dev->LanguageID, len);
|
||||||
new_Control_Transfer(dev, &dev->setup, enumbuf + 4);
|
new_Control_Transfer(dev, &enumsetup, enumbuf + 4, NULL);
|
||||||
dev->enum_state = 6;
|
dev->enum_state = 6;
|
||||||
return;
|
return;
|
||||||
case 6: // parse Manufacturer string
|
case 6: // parse Manufacturer string
|
||||||
@ -163,8 +164,8 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
break;
|
break;
|
||||||
case 7: // request Product string
|
case 7: // request Product string
|
||||||
len = sizeof(enumbuf) - 4;
|
len = sizeof(enumbuf) - 4;
|
||||||
mk_setup(dev->setup, 0x80, 6, 0x0300 | enumbuf[1], dev->LanguageID, len);
|
mk_setup(enumsetup, 0x80, 6, 0x0300 | enumbuf[1], dev->LanguageID, len);
|
||||||
new_Control_Transfer(dev, &dev->setup, enumbuf + 4);
|
new_Control_Transfer(dev, &enumsetup, enumbuf + 4, NULL);
|
||||||
dev->enum_state = 8;
|
dev->enum_state = 8;
|
||||||
return;
|
return;
|
||||||
case 8: // parse Product string
|
case 8: // parse Product string
|
||||||
@ -174,8 +175,8 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
break;
|
break;
|
||||||
case 9: // request Serial Number string
|
case 9: // request Serial Number string
|
||||||
len = sizeof(enumbuf) - 4;
|
len = sizeof(enumbuf) - 4;
|
||||||
mk_setup(dev->setup, 0x80, 6, 0x0300 | enumbuf[2], dev->LanguageID, len);
|
mk_setup(enumsetup, 0x80, 6, 0x0300 | enumbuf[2], dev->LanguageID, len);
|
||||||
new_Control_Transfer(dev, &dev->setup, enumbuf + 4);
|
new_Control_Transfer(dev, &enumsetup, enumbuf + 4, NULL);
|
||||||
dev->enum_state = 10;
|
dev->enum_state = 10;
|
||||||
return;
|
return;
|
||||||
case 10: // parse Serial Number string
|
case 10: // parse Serial Number string
|
||||||
@ -183,8 +184,8 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
dev->enum_state = 11;
|
dev->enum_state = 11;
|
||||||
break;
|
break;
|
||||||
case 11: // request first 9 bytes of config desc
|
case 11: // request first 9 bytes of config desc
|
||||||
mk_setup(dev->setup, 0x80, 6, 0x0200, 0, 9); // 6=GET_DESCRIPTOR
|
mk_setup(enumsetup, 0x80, 6, 0x0200, 0, 9); // 6=GET_DESCRIPTOR
|
||||||
new_Control_Transfer(dev, &dev->setup, enumbuf);
|
new_Control_Transfer(dev, &enumsetup, enumbuf, NULL);
|
||||||
dev->enum_state = 12;
|
dev->enum_state = 12;
|
||||||
return;
|
return;
|
||||||
case 12: // read 9 bytes, request all of config desc
|
case 12: // read 9 bytes, request all of config desc
|
||||||
@ -194,8 +195,8 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
if (len > sizeof(enumbuf)) {
|
if (len > sizeof(enumbuf)) {
|
||||||
// TODO: how to handle device with too much config data
|
// TODO: how to handle device with too much config data
|
||||||
}
|
}
|
||||||
mk_setup(dev->setup, 0x80, 6, 0x0200, 0, len); // 6=GET_DESCRIPTOR
|
mk_setup(enumsetup, 0x80, 6, 0x0200, 0, len); // 6=GET_DESCRIPTOR
|
||||||
new_Control_Transfer(dev, &dev->setup, enumbuf);
|
new_Control_Transfer(dev, &enumsetup, enumbuf, NULL);
|
||||||
dev->enum_state = 13;
|
dev->enum_state = 13;
|
||||||
return;
|
return;
|
||||||
case 13: // read all config desc, send set config
|
case 13: // read all config desc, send set config
|
||||||
@ -206,8 +207,8 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
dev->bmAttributes = enumbuf[7];
|
dev->bmAttributes = enumbuf[7];
|
||||||
dev->bMaxPower = enumbuf[8];
|
dev->bMaxPower = enumbuf[8];
|
||||||
// TODO: actually do something with interface descriptor?
|
// TODO: actually do something with interface descriptor?
|
||||||
mk_setup(dev->setup, 0, 9, enumbuf[5], 0, 0); // 9=SET_CONFIGURATION
|
mk_setup(enumsetup, 0, 9, enumbuf[5], 0, 0); // 9=SET_CONFIGURATION
|
||||||
new_Control_Transfer(dev, &dev->setup, NULL);
|
new_Control_Transfer(dev, &enumsetup, NULL, NULL);
|
||||||
dev->enum_state = 14;
|
dev->enum_state = 14;
|
||||||
return;
|
return;
|
||||||
case 14: // device is now configured
|
case 14: // device is now configured
|
||||||
|
8
hub.cpp
8
hub.cpp
@ -76,8 +76,8 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
|
|||||||
state = 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(setup, 0xA0, 6, 0x2900, 0, sizeof(hub_desc));
|
||||||
new_Control_Transfer(dev, &dev->setup, hub_desc);
|
new_Control_Transfer(dev, &setup, hub_desc, this);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -85,8 +85,8 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
|
|||||||
void USBHub::poweron(uint32_t port)
|
void USBHub::poweron(uint32_t port)
|
||||||
{
|
{
|
||||||
// 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(device->setup, 0x23, 3, 8, port, 0);
|
mk_setup(setup, 0x23, 3, 8, port, 0);
|
||||||
new_Control_Transfer(device, &device->setup, NULL);
|
new_Control_Transfer(device, &setup, NULL, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBHub::control(const Transfer_t *transfer)
|
bool USBHub::control(const Transfer_t *transfer)
|
||||||
|
Loading…
Reference in New Issue
Block a user