mirror of
https://github.com/gdsports/USBHost_t36
synced 2025-02-17 15:30:15 -05:00
Drivers claim interface & add Keyboard driver claim
This commit is contained in:
parent
7756f2f4b7
commit
57f958c368
@ -191,7 +191,7 @@ protected:
|
|||||||
// device has its vid&pid, class/subclass fields initialized
|
// device has its vid&pid, class/subclass fields initialized
|
||||||
// type is 0 for device level, 1 for interface level, 2 for IAD
|
// type is 0 for device level, 1 for interface level, 2 for IAD
|
||||||
// descriptors points to the specific descriptor data
|
// descriptors points to the specific descriptor data
|
||||||
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors);
|
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len);
|
||||||
|
|
||||||
// When an unknown (not chapter 9) control transfer completes, this
|
// When an unknown (not chapter 9) control transfer completes, this
|
||||||
// function is called for all drivers bound to the device. Return
|
// function is called for all drivers bound to the device. Return
|
||||||
@ -233,7 +233,7 @@ class USBHub : public USBDriver {
|
|||||||
public:
|
public:
|
||||||
USBHub();
|
USBHub();
|
||||||
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, uint32_t len);
|
||||||
virtual void control(const Transfer_t *transfer);
|
virtual void control(const Transfer_t *transfer);
|
||||||
virtual void disconnect();
|
virtual void disconnect();
|
||||||
void poweron(uint32_t port);
|
void poweron(uint32_t port);
|
||||||
@ -269,7 +269,7 @@ public:
|
|||||||
void attachPress(void (*keyPressed)());
|
void attachPress(void (*keyPressed)());
|
||||||
void attachRelease(void (*keyReleased)());
|
void attachRelease(void (*keyReleased)());
|
||||||
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, uint32_t len);
|
||||||
virtual void disconnect();
|
virtual void disconnect();
|
||||||
static void callback(const Transfer_t *transfer);
|
static void callback(const Transfer_t *transfer);
|
||||||
void new_data(const Transfer_t *transfer);
|
void new_data(const Transfer_t *transfer);
|
||||||
|
1
ehci.cpp
1
ehci.cpp
@ -58,6 +58,7 @@ void USBHost::begin()
|
|||||||
PORTE_PCR6 = PORT_PCR_MUX(1);
|
PORTE_PCR6 = PORT_PCR_MUX(1);
|
||||||
GPIOE_PDDR |= (1<<6);
|
GPIOE_PDDR |= (1<<6);
|
||||||
GPIOE_PSOR = (1<<6); // turn on USB host power
|
GPIOE_PSOR = (1<<6); // turn on USB host power
|
||||||
|
delay(10);
|
||||||
Serial.print("sizeof Device = ");
|
Serial.print("sizeof Device = ");
|
||||||
Serial.println(sizeof(Device_t));
|
Serial.println(sizeof(Device_t));
|
||||||
Serial.print("sizeof Pipe = ");
|
Serial.print("sizeof Pipe = ");
|
||||||
|
@ -28,6 +28,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 setup_t enumsetup __attribute__ ((aligned(16)));
|
||||||
|
static uint16_t enumlen;
|
||||||
|
|
||||||
|
|
||||||
static uint32_t assign_addr(void);
|
static uint32_t assign_addr(void);
|
||||||
@ -197,13 +198,13 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
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
|
||||||
len = enumbuf[2] | (enumbuf[3] << 8);
|
enumlen = enumbuf[2] | (enumbuf[3] << 8);
|
||||||
Serial.print("Config data length = ");
|
Serial.print("Config data length = ");
|
||||||
Serial.println(len);
|
Serial.println(enumlen);
|
||||||
if (len > sizeof(enumbuf)) {
|
if (enumlen > sizeof(enumbuf)) {
|
||||||
// TODO: how to handle device with too much config data
|
// TODO: how to handle device with too much config data
|
||||||
}
|
}
|
||||||
mk_setup(enumsetup, 0x80, 6, 0x0200, 0, len); // 6=GET_DESCRIPTOR
|
mk_setup(enumsetup, 0x80, 6, 0x0200, 0, enumlen); // 6=GET_DESCRIPTOR
|
||||||
queue_Control_Transfer(dev, &enumsetup, enumbuf, NULL);
|
queue_Control_Transfer(dev, &enumsetup, enumbuf, NULL);
|
||||||
dev->enum_state = 13;
|
dev->enum_state = 13;
|
||||||
return;
|
return;
|
||||||
@ -239,7 +240,7 @@ void USBHost::claim_drivers(Device_t *dev)
|
|||||||
|
|
||||||
// first check if any driver wishes to claim the entire device
|
// first check if any driver wishes to claim the entire device
|
||||||
for (driver=available_drivers; driver != NULL; driver = driver->next) {
|
for (driver=available_drivers; driver != NULL; driver = driver->next) {
|
||||||
if (driver->claim(dev, 0, enumbuf + 9)) {
|
if (driver->claim(dev, 0, enumbuf + 9, enumlen - 9)) {
|
||||||
if (prev) {
|
if (prev) {
|
||||||
prev->next = driver->next;
|
prev->next = driver->next;
|
||||||
} else {
|
} else {
|
||||||
@ -252,8 +253,52 @@ void USBHost::claim_drivers(Device_t *dev)
|
|||||||
}
|
}
|
||||||
prev = driver;
|
prev = driver;
|
||||||
}
|
}
|
||||||
// TODO: parse interfaces from config descriptor
|
// parse interfaces from config descriptor
|
||||||
// try claim_interface on drivers
|
const uint8_t *p = enumbuf + 9;
|
||||||
|
const uint8_t *end = enumbuf + enumlen;
|
||||||
|
while (p < end) {
|
||||||
|
uint8_t desclen = *p;
|
||||||
|
uint8_t desctype = *(p+1);
|
||||||
|
Serial.print("Descriptor ");
|
||||||
|
Serial.print(desctype);
|
||||||
|
Serial.print(" = ");
|
||||||
|
if (desctype == 4) Serial.println("INTERFACE");
|
||||||
|
else if (desctype == 5) Serial.println("ENDPOINT");
|
||||||
|
else if (desctype == 6) Serial.println("DEV_QUALIFIER");
|
||||||
|
else if (desctype == 7) Serial.println("OTHER_SPEED");
|
||||||
|
else if (desctype == 11) Serial.println("IAD");
|
||||||
|
else if (desctype == 33) Serial.println("HID");
|
||||||
|
else Serial.println(" ???");
|
||||||
|
if (desctype == 11 && desclen == 8) {
|
||||||
|
// TODO: parse IAD, ask drivers for claim
|
||||||
|
// TODO: how to skip over all interfaces IAD represented
|
||||||
|
}
|
||||||
|
if (desctype == 4 && desclen == 9) {
|
||||||
|
// found an interface, ask available drivers if they want it
|
||||||
|
prev = NULL;
|
||||||
|
for (driver=available_drivers; driver != NULL; driver = driver->next) {
|
||||||
|
if (driver->claim(dev, 1, p, end - p)) {
|
||||||
|
// this driver claims iface
|
||||||
|
// remove it from available_drivers list
|
||||||
|
if (prev) {
|
||||||
|
prev->next = driver->next;
|
||||||
|
} else {
|
||||||
|
available_drivers = driver->next;
|
||||||
|
}
|
||||||
|
// add to list of drivers using this device
|
||||||
|
if (dev->drivers) {
|
||||||
|
dev->drivers->next = driver;
|
||||||
|
}
|
||||||
|
dev->drivers = driver;
|
||||||
|
driver->next = NULL;
|
||||||
|
driver->device = dev;
|
||||||
|
// not done, may be more interface for more drivers
|
||||||
|
}
|
||||||
|
prev = driver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p += desclen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t assign_addr(void)
|
static uint32_t assign_addr(void)
|
||||||
|
2
hub.cpp
2
hub.cpp
@ -30,7 +30,7 @@ USBHub::USBHub()
|
|||||||
driver_ready_for_device(this);
|
driver_ready_for_device(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
|
bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
|
||||||
{
|
{
|
||||||
// only claim entire device, never at interface level
|
// only claim entire device, never at interface level
|
||||||
if (type != 0) return false;
|
if (type != 0) return false;
|
||||||
|
32
keyboard.cpp
32
keyboard.cpp
@ -31,18 +31,40 @@ KeyboardController::KeyboardController()
|
|||||||
driver_ready_for_device(this);
|
driver_ready_for_device(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardController::claim(Device_t *dev, int type, const uint8_t *descriptors)
|
bool KeyboardController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
|
||||||
{
|
{
|
||||||
Serial.print("KeyboardController claim this=");
|
Serial.print("KeyboardController claim this=");
|
||||||
Serial.println((uint32_t)this, HEX);
|
Serial.println((uint32_t)this, HEX);
|
||||||
|
|
||||||
// only claim at interface level
|
// only claim at interface level
|
||||||
if (type != 1) return false;
|
if (type != 1) return false;
|
||||||
|
if (len < 9+9+7) return false;
|
||||||
|
|
||||||
return false;
|
uint32_t numendpoint = descriptors[4];
|
||||||
|
if (numendpoint < 1) return false;
|
||||||
uint32_t endpoint=1;
|
if (descriptors[5] != 3) return false; // bInterfaceClass, 3 = HID
|
||||||
|
if (descriptors[6] != 1) return false; // bInterfaceSubClass, 1 = Boot Device
|
||||||
|
if (descriptors[7] != 1) return false; // bInterfaceProtocol, 1 = Keyboard
|
||||||
|
if (descriptors[9] != 9) return false;
|
||||||
|
if (descriptors[10] != 33) return false; // HID descriptor (ignored, Boot Protocol)
|
||||||
|
if (descriptors[18] != 7) return false;
|
||||||
|
if (descriptors[19] != 5) return false; // endpoint descriptor
|
||||||
|
uint32_t endpoint = descriptors[20];
|
||||||
|
Serial.print("ep = ");
|
||||||
|
Serial.println(endpoint, HEX);
|
||||||
|
if ((endpoint & 0xF0) != 0x80) return false; // must be IN direction
|
||||||
|
endpoint &= 0x0F;
|
||||||
|
if (endpoint == 0) return false;
|
||||||
|
if (descriptors[21] != 3) return false; // must be interrupt type
|
||||||
|
uint32_t size = descriptors[22] | (descriptors[23] << 8);
|
||||||
|
Serial.print("packet size = ");
|
||||||
|
Serial.println(size);
|
||||||
|
if (size != 8) return false; // must be 8 bytes for Keyboard Boot Protocol
|
||||||
|
uint32_t interval = descriptors[24];
|
||||||
|
Serial.print("polling interval = ");
|
||||||
|
Serial.println(interval);
|
||||||
datapipe = new_Pipe(dev, 3, endpoint, 1, 8, 64);
|
datapipe = new_Pipe(dev, 3, endpoint, 1, 8, 64);
|
||||||
|
datapipe->callback_function = callback;
|
||||||
queue_Data_Transfer(datapipe, report, 8, this);
|
queue_Data_Transfer(datapipe, report, 8, this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -58,6 +80,8 @@ void KeyboardController::callback(const Transfer_t *transfer)
|
|||||||
void KeyboardController::new_data(const Transfer_t *transfer)
|
void KeyboardController::new_data(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
Serial.println("KeyboardController Callback (member)");
|
Serial.println("KeyboardController Callback (member)");
|
||||||
|
Serial.print(" KB Data: ");
|
||||||
|
print_hexbytes(transfer->buffer, 8);
|
||||||
// TODO: parse the new data
|
// TODO: parse the new data
|
||||||
queue_Data_Transfer(datapipe, report, 8, this);
|
queue_Data_Transfer(datapipe, report, 8, this);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user