Print USB descriptors in debug output
This commit is contained in:
rodič
fd4842d94b
revize
1494a02918
|
@ -309,6 +309,9 @@ protected:
|
|||
static void print_(const Pipe_t *pipe);
|
||||
static void print_driverlist(const char *name, const USBDriver *driver);
|
||||
static void print_qh_list(const Pipe_t *list);
|
||||
static void print_device_descriptor(const uint8_t *p);
|
||||
static void print_config_descriptor(const uint8_t *p, uint32_t maxlen);
|
||||
static void print_string_descriptor(const char *name, const uint8_t *p);
|
||||
static void print_hexbytes(const void *ptr, uint32_t len);
|
||||
static void print_(const char *s) { Serial.print(s); }
|
||||
static void print_(int n) { Serial.print(n); }
|
||||
|
@ -347,6 +350,9 @@ protected:
|
|||
static void print_(const Pipe_t *pipe) {}
|
||||
static void print_driverlist(const char *name, const USBDriver *driver) {}
|
||||
static void print_qh_list(const Pipe_t *list) {}
|
||||
static void print_device_descriptor(const uint8_t *p) {}
|
||||
static void print_config_descriptor(const uint8_t *p, uint32_t maxlen) {}
|
||||
static void print_string_descriptor(const char *name, const uint8_t *p) {}
|
||||
static void print_hexbytes(const void *ptr, uint32_t len) {}
|
||||
static void print_(const char *s) {}
|
||||
static void print_(int n) {}
|
||||
|
|
|
@ -183,6 +183,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||
dev->enum_state = 2;
|
||||
return;
|
||||
case 2: // parse 18 device desc bytes
|
||||
print_device_descriptor(enumbuf);
|
||||
dev->bDeviceClass = enumbuf[4];
|
||||
dev->bDeviceSubClass = enumbuf[5];
|
||||
dev->bDeviceProtocol = enumbuf[6];
|
||||
|
@ -221,6 +222,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||
dev->enum_state = 6;
|
||||
return;
|
||||
case 6: // parse Manufacturer string
|
||||
print_string_descriptor("Manufacturer: ", enumbuf + 4);
|
||||
convertStringDescriptorToASCIIString(0, dev, transfer);
|
||||
// TODO: receive the string...
|
||||
if (enumbuf[1]) dev->enum_state = 7;
|
||||
|
@ -234,6 +236,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||
dev->enum_state = 8;
|
||||
return;
|
||||
case 8: // parse Product string
|
||||
print_string_descriptor("Product: ", enumbuf + 4);
|
||||
convertStringDescriptorToASCIIString(1, dev, transfer);
|
||||
if (enumbuf[2]) dev->enum_state = 9;
|
||||
else dev->enum_state = 11;
|
||||
|
@ -245,6 +248,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||
dev->enum_state = 10;
|
||||
return;
|
||||
case 10: // parse Serial Number string
|
||||
print_string_descriptor("Serial Number: ", enumbuf + 4);
|
||||
convertStringDescriptorToASCIIString(2, dev, transfer);
|
||||
dev->enum_state = 11;
|
||||
break;
|
||||
|
@ -257,6 +261,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||
enumlen = enumbuf[2] | (enumbuf[3] << 8);
|
||||
println("Config data length = ", enumlen);
|
||||
if (enumlen > sizeof(enumbuf)) {
|
||||
enumlen = sizeof(enumbuf);
|
||||
// TODO: how to handle device with too much config data
|
||||
}
|
||||
mk_setup(enumsetup, 0x80, 6, 0x0200, 0, enumlen); // 6=GET_DESCRIPTOR
|
||||
|
@ -264,8 +269,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||
dev->enum_state = 13;
|
||||
return;
|
||||
case 13: // read all config desc, send set config
|
||||
println("bNumInterfaces = ", enumbuf[4]);
|
||||
println("bConfigurationValue = ", enumbuf[5]);
|
||||
print_config_descriptor(enumbuf, sizeof(enumbuf));
|
||||
dev->bmAttributes = enumbuf[7];
|
||||
dev->bMaxPower = enumbuf[8];
|
||||
// TODO: actually do something with interface descriptor?
|
||||
|
|
144
print.cpp
144
print.cpp
|
@ -172,6 +172,150 @@ void USBHost::print_qh_list(const Pipe_t *list)
|
|||
Serial.println();
|
||||
}
|
||||
|
||||
static void print_class_subclass_protocol(uint8_t c, uint8_t s, uint8_t p)
|
||||
{
|
||||
Serial.print(c);
|
||||
if (c == 3) Serial.print("(HID)");
|
||||
if (c == 8) Serial.print("(Mass Storage)");
|
||||
if (c == 9) Serial.print("(Hub)");
|
||||
Serial.print(" / ");
|
||||
Serial.print(s);
|
||||
if (c == 3 && s == 1) Serial.print("(Boot)");
|
||||
if (c == 8 && s == 6) Serial.print("(SCSI)");
|
||||
Serial.print(" / ");
|
||||
Serial.print(p);
|
||||
if (c == 3 && s == 1 && p == 1) Serial.print("(Keyboard)");
|
||||
if (c == 3 && s == 1 && p == 2) Serial.print("(Mouse)");
|
||||
if (c == 8 && s == 6 && p == 0x50) Serial.print("(Bulk Only)");
|
||||
if (c == 8 && s == 6 && p == 0x62) Serial.print("(UAS)");
|
||||
if (c == 9 && s == 0 && p == 1) Serial.print("(Single-TT)");
|
||||
if (c == 9 && s == 0 && p == 2) Serial.print("(Multi-TT)");
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void USBHost::print_device_descriptor(const uint8_t *p)
|
||||
{
|
||||
Serial.println("Device Descriptor:");
|
||||
Serial.print(" ");
|
||||
print_hexbytes(p, p[0]);
|
||||
if (p[0] != 18) {
|
||||
Serial.println("error: device must be 18 bytes");
|
||||
return;
|
||||
}
|
||||
if (p[1] != 1) {
|
||||
Serial.println("error: device must type 1");
|
||||
return;
|
||||
}
|
||||
Serial.printf(" VendorID = %04X, ProductID = %04X, Version = %04X",
|
||||
p[8] | (p[9] << 8), p[10] | (p[11] << 8), p[12] | (p[13] << 8));
|
||||
Serial.println();
|
||||
Serial.print(" Class/Subclass/Protocol = ");
|
||||
print_class_subclass_protocol(p[4], p[5], p[6]);
|
||||
Serial.print(" Number of Configurations = ");
|
||||
Serial.println(p[17]);
|
||||
}
|
||||
|
||||
void USBHost::print_config_descriptor(const uint8_t *p, uint32_t maxlen)
|
||||
{
|
||||
// Descriptor Types: (USB 2.0, page 251)
|
||||
Serial.println("Configuration Descriptor:");
|
||||
Serial.print(" ");
|
||||
print_hexbytes(p, p[0]);
|
||||
if (p[0] != 9) {
|
||||
Serial.println("error: config must be 9 bytes");
|
||||
return;
|
||||
}
|
||||
if (p[1] != 2) {
|
||||
Serial.println("error: config must type 2");
|
||||
return;
|
||||
}
|
||||
Serial.print(" NumInterfaces = ");
|
||||
Serial.println(p[4]);
|
||||
Serial.print(" ConfigurationValue = ");
|
||||
Serial.println(p[5]);
|
||||
|
||||
uint32_t len = p[2] | (p[3] << 8);
|
||||
if (len > maxlen) len = maxlen;
|
||||
len -= p[0];
|
||||
p += 9;
|
||||
|
||||
while (len > 0) {
|
||||
if (p[0] > len) {
|
||||
Serial.print(" ");
|
||||
print_hexbytes(p, len);
|
||||
Serial.println(" error: length beyond total data size");
|
||||
break;
|
||||
}
|
||||
Serial.print(" ");
|
||||
print_hexbytes(p, p[0]);
|
||||
if (p[0] == 9 && p[1] == 4) { // Interface Descriptor
|
||||
Serial.print(" Interface = ");
|
||||
Serial.println(p[2]);
|
||||
Serial.print(" Number of endpoints = ");
|
||||
Serial.println(p[4]);
|
||||
Serial.print(" Class/Subclass/Protocol = ");
|
||||
print_class_subclass_protocol(p[5], p[6], p[7]);
|
||||
} else if (p[0] >= 7 && p[0] <= 9 && p[1] == 5) { // Endpoint Descriptor
|
||||
Serial.print(" Endpoint = ");
|
||||
Serial.print(p[2] & 15);
|
||||
Serial.println((p[2] & 128) ? " IN" : " OUT");
|
||||
Serial.print(" Type = ");
|
||||
switch (p[3] & 3) {
|
||||
case 0: Serial.println("Control"); break;
|
||||
case 1: Serial.println("Isochronous"); break;
|
||||
case 2: Serial.println("Bulk"); break;
|
||||
case 3: Serial.println("Interrupt"); break;
|
||||
}
|
||||
Serial.print(" Max Size = ");
|
||||
Serial.println(p[4] | (p[5] << 8));
|
||||
Serial.print(" Polling Interval = ");
|
||||
Serial.println(p[6]);
|
||||
} else if (p[0] == 8 && p[1] == 11) { // IAD
|
||||
Serial.print(" Interface Association = ");
|
||||
Serial.print(p[2]);
|
||||
Serial.print(" through ");
|
||||
Serial.println(p[2] + p[3] - 1);
|
||||
Serial.print(" Class / Subclass / Protocol = ");
|
||||
print_class_subclass_protocol(p[4], p[5], p[7]);
|
||||
} else if (p[0] >= 9 && p[1] == 0x21) { // HID
|
||||
Serial.print(" HID, ");
|
||||
Serial.print(p[5]);
|
||||
Serial.print(" report descriptor");
|
||||
if (p[5] != 1) Serial.print('s');
|
||||
Serial.println();
|
||||
}
|
||||
len -= p[0];
|
||||
p += p[0];
|
||||
}
|
||||
}
|
||||
|
||||
void USBHost::print_string_descriptor(const char *name, const uint8_t *p)
|
||||
{
|
||||
uint32_t len = p[0];
|
||||
if (len < 4) return;
|
||||
Serial.print(name);
|
||||
len -= 2;
|
||||
p += 2;
|
||||
while (len >= 2) {
|
||||
uint32_t c = p[0] | (p[1] << 8);
|
||||
if (c < 0x80) {
|
||||
Serial.write(c);
|
||||
} else if (c < 0x800) {
|
||||
Serial.write((c >> 6) | 0xC0);
|
||||
Serial.write((c & 0x3F) | 0x80);
|
||||
} else {
|
||||
Serial.write((c >> 12) | 0xE0);
|
||||
Serial.write(((c >> 6) & 0x3F) | 0x80);
|
||||
Serial.write((c & 0x3F) | 0x80);
|
||||
}
|
||||
len -= 2;
|
||||
p += 2;
|
||||
}
|
||||
Serial.println();
|
||||
//print_hexbytes(p, p[0]);
|
||||
}
|
||||
|
||||
|
||||
void USBHost::print_hexbytes(const void *ptr, uint32_t len)
|
||||
{
|
||||
if (ptr == NULL || len == 0) return;
|
||||
|
|
Načítá se…
Odkázat v novém úkolu