mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-13 12:45:04 -05:00
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
This commit is contained in:
parent
03a7150872
commit
40cb6322ac
@ -141,6 +141,7 @@ typedef union {
|
||||
} setup_t;
|
||||
|
||||
// Device_t holds all the information about a USB device
|
||||
#define DEVICE_STRUCT_STRING_BUF_SIZE 48
|
||||
struct Device_struct {
|
||||
Pipe_t *control_pipe;
|
||||
Pipe_t *data_pipes;
|
||||
@ -159,6 +160,8 @@ struct Device_struct {
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
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
|
||||
@ -248,6 +251,7 @@ protected:
|
||||
static volatile bool enumeration_busy;
|
||||
private:
|
||||
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 uint32_t assign_address(void);
|
||||
static bool queue_Transfer(Pipe_t *pipe, Transfer_t *transfer);
|
||||
@ -350,6 +354,11 @@ public:
|
||||
operator bool() { return (device != nullptr); }
|
||||
uint16_t idVendor() { return (device != nullptr) ? device->idVendor : 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
|
||||
// check if device is bound/active/online
|
||||
// query vid, pid
|
||||
|
@ -201,6 +201,10 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
||||
dev->enum_state = 4;
|
||||
return;
|
||||
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) {
|
||||
dev->enum_state = 11;
|
||||
} else {
|
||||
@ -218,6 +222,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
||||
dev->enum_state = 6;
|
||||
return;
|
||||
case 6: // parse Manufacturer string
|
||||
convertStringDescriptorToASCIIString(0, dev, transfer);
|
||||
// TODO: receive the string...
|
||||
if (enumbuf[1]) dev->enum_state = 7;
|
||||
else if (enumbuf[2]) dev->enum_state = 9;
|
||||
@ -230,7 +235,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
||||
dev->enum_state = 8;
|
||||
return;
|
||||
case 8: // parse Product string
|
||||
// TODO: receive the string...
|
||||
convertStringDescriptorToASCIIString(1, dev, transfer);
|
||||
if (enumbuf[2]) dev->enum_state = 9;
|
||||
else dev->enum_state = 11;
|
||||
break;
|
||||
@ -241,7 +246,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
||||
dev->enum_state = 10;
|
||||
return;
|
||||
case 10: // parse Serial Number string
|
||||
// TODO: receive the string...
|
||||
convertStringDescriptorToASCIIString(2, dev, transfer);
|
||||
dev->enum_state = 11;
|
||||
break;
|
||||
case 11: // request first 9 bytes of config desc
|
||||
@ -286,6 +291,33 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
USBDriver *driver, *prev=NULL;
|
||||
|
@ -49,6 +49,12 @@ void loop()
|
||||
Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
|
||||
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…
Reference in New Issue
Block a user