Browse Source

WIP - Add Strings to device structure

Added the ability to query the
Manufactur, product name and serial number strings from a device.

WIP - Eats up lots of memory, next up experiment move from Device_t object to maybe top level objects.  Probably fewer than them as each hub allocates something like 7 Device objects
main
Kurt Eckhardt 7 years ago
parent
commit
40cb6322ac
3 changed files with 49 additions and 2 deletions
  1. +9
    -0
      USBHost_t36.h
  2. +34
    -2
      enumeration.cpp
  3. +6
    -0
      examples/Mouse/Mouse.ino

+ 9
- 0
USBHost_t36.h View File

} setup_t; } setup_t;


// Device_t holds all the information about a USB device // Device_t holds all the information about a USB device
#define DEVICE_STRUCT_STRING_BUF_SIZE 48
struct Device_struct { struct Device_struct {
Pipe_t *control_pipe; Pipe_t *control_pipe;
Pipe_t *data_pipes; Pipe_t *data_pipes;
uint16_t idVendor; uint16_t idVendor;
uint16_t idProduct; uint16_t idProduct;
uint16_t LanguageID; uint16_t LanguageID;
uint8_t string_buf[DEVICE_STRUCT_STRING_BUF_SIZE]; // Probably want a place to allocate fewer of these...
uint8_t iStrings[3]; // 3 indexes - vendor string, product string, serial number.
}; };


// Pipe_t holes all information about each USB endpoint/pipe // Pipe_t holes all information about each USB endpoint/pipe
static volatile bool enumeration_busy; static volatile bool enumeration_busy;
private: private:
static void isr(); static void isr();
static void convertStringDescriptorToASCIIString(uint8_t string_index, Device_t *dev, const Transfer_t *transfer);
static void claim_drivers(Device_t *dev); static void claim_drivers(Device_t *dev);
static uint32_t assign_address(void); static uint32_t assign_address(void);
static bool queue_Transfer(Pipe_t *pipe, Transfer_t *transfer); static bool queue_Transfer(Pipe_t *pipe, Transfer_t *transfer);
operator bool() { return (device != nullptr); } operator bool() { return (device != nullptr); }
uint16_t idVendor() { return (device != nullptr) ? device->idVendor : 0; } uint16_t idVendor() { return (device != nullptr) ? device->idVendor : 0; }
uint16_t idProduct() { return (device != nullptr) ? device->idProduct : 0; } uint16_t idProduct() { return (device != nullptr) ? device->idProduct : 0; }

const uint8_t *manufacturer() { return (device != nullptr) ? &(device->string_buf[device->iStrings[0]]) : nullptr; }
const uint8_t *product() { return (device != nullptr) ? &(device->string_buf[device->iStrings[1]]) : nullptr; }
const uint8_t *serialNumber() { return (device != nullptr) ? &(device->string_buf[device->iStrings[2]]) : nullptr; }

// TODO: user-level functions // TODO: user-level functions
// check if device is bound/active/online // check if device is bound/active/online
// query vid, pid // query vid, pid

+ 34
- 2
enumeration.cpp View File

dev->enum_state = 4; dev->enum_state = 4;
return; return;
case 4: // parse Language ID case 4: // parse Language ID
dev->iStrings[0] = 0; // Set indexes into string buffer to say not there...
dev->iStrings[1] = 0;
dev->iStrings[2] = 0;
dev->string_buf[0] = 0; // have trailing NULL..
if (enumbuf[4] < 4 || enumbuf[5] != 3) { if (enumbuf[4] < 4 || enumbuf[5] != 3) {
dev->enum_state = 11; dev->enum_state = 11;
} else { } else {
dev->enum_state = 6; dev->enum_state = 6;
return; return;
case 6: // parse Manufacturer string case 6: // parse Manufacturer string
convertStringDescriptorToASCIIString(0, dev, transfer);
// TODO: receive the string... // TODO: receive the string...
if (enumbuf[1]) dev->enum_state = 7; if (enumbuf[1]) dev->enum_state = 7;
else if (enumbuf[2]) dev->enum_state = 9; else if (enumbuf[2]) dev->enum_state = 9;
dev->enum_state = 8; dev->enum_state = 8;
return; return;
case 8: // parse Product string case 8: // parse Product string
// TODO: receive the string...
convertStringDescriptorToASCIIString(1, dev, transfer);
if (enumbuf[2]) dev->enum_state = 9; if (enumbuf[2]) dev->enum_state = 9;
else dev->enum_state = 11; else dev->enum_state = 11;
break; break;
dev->enum_state = 10; dev->enum_state = 10;
return; return;
case 10: // parse Serial Number string case 10: // parse Serial Number string
// TODO: receive the string...
convertStringDescriptorToASCIIString(2, dev, 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
} }
} }


void USBHost::convertStringDescriptorToASCIIString(uint8_t string_index, Device_t *dev, const Transfer_t *transfer) {
uint8_t *buffer = (uint8_t*)transfer->buffer;
uint8_t buf_index = string_index? dev->iStrings[string_index]+1 : 0;

// Try to verify - The first byte should be length and the 2nd byte should be 0x3
if (!buffer || (buffer[1] != 0x3)) {
return; // No string so can simply return
}

dev->iStrings[string_index] = buf_index; // remember our starting positio
uint8_t count_bytes_returned = buffer[0];
if ((buf_index + count_bytes_returned/2) >= DEVICE_STRUCT_STRING_BUF_SIZE)
count_bytes_returned = (DEVICE_STRUCT_STRING_BUF_SIZE - buf_index) * 2;

// Now copy into our storage buffer.
for (uint8_t i = 2; (i < count_bytes_returned) && (buf_index < (DEVICE_STRUCT_STRING_BUF_SIZE -1)); i += 2) {
dev->string_buf[buf_index++] = buffer[i];
}
dev->string_buf[buf_index] = 0; // null terminate.

// Update other indexes to point to null character
while (++string_index < 3) {
dev->iStrings[string_index] = buf_index; // point to trailing NULL character
}
}


void USBHost::claim_drivers(Device_t *dev) void USBHost::claim_drivers(Device_t *dev)
{ {
USBDriver *driver, *prev=NULL; USBDriver *driver, *prev=NULL;

+ 6
- 0
examples/Mouse/Mouse.ino View File

Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct()); Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
driver_active[i] = true; driver_active[i] = true;


const uint8_t *psz = drivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = drivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
} }
} }
} }

Loading…
Cancel
Save