Procházet zdrojové kódy

Drivers claim interface & add Keyboard driver claim

main
PaulStoffregen před 7 roky
rodič
revize
57f958c368
5 změnil soubory, kde provedl 85 přidání a 15 odebrání
  1. +3
    -3
      USBHost.h
  2. +1
    -0
      ehci.cpp
  3. +52
    -7
      enumeration.cpp
  4. +1
    -1
      hub.cpp
  5. +28
    -4
      keyboard.cpp

+ 3
- 3
USBHost.h Zobrazit soubor

// 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
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);
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
- 0
ehci.cpp Zobrazit soubor

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

+ 52
- 7
enumeration.cpp Zobrazit soubor

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);
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);
if (len > sizeof(enumbuf)) {
Serial.println(enumlen);
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;


// 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 {
} }
prev = driver; prev = driver;
} }
// TODO: parse interfaces from config descriptor
// try claim_interface on drivers
// parse interfaces from config descriptor
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)

+ 1
- 1
hub.cpp Zobrazit soubor

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;

+ 28
- 4
keyboard.cpp Zobrazit soubor

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 endpoint=1;
uint32_t numendpoint = descriptors[4];
if (numendpoint < 1) return false;
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;
} }
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);
} }

Načítá se…
Zrušit
Uložit