diff --git a/examples/DualRole/device_info_rp2040/.feather_rp2040_tinyusb.test.only b/examples/DualRole/Simple/device_info/.feather_rp2040_tinyusb.test.only similarity index 100% rename from examples/DualRole/device_info_rp2040/.feather_rp2040_tinyusb.test.only rename to examples/DualRole/Simple/device_info/.feather_rp2040_tinyusb.test.only diff --git a/examples/DualRole/device_info_rp2040/device_info_rp2040.ino b/examples/DualRole/Simple/device_info/device_info.ino similarity index 69% rename from examples/DualRole/device_info_rp2040/device_info_rp2040.ino rename to examples/DualRole/Simple/device_info/device_info.ino index c793c45f..d15c2df2 100644 --- a/examples/DualRole/device_info_rp2040/device_info_rp2040.ino +++ b/examples/DualRole/Simple/device_info/device_info.ino @@ -65,16 +65,23 @@ // USB Host object Adafruit_USBH_Host USBHost; -// holding device descriptor -tusb_desc_device_t desc_device; +typedef struct { + tusb_desc_device_t desc_device; + uint16_t manufacturer[32]; + uint16_t product[32]; + uint16_t serial[16]; + bool mounted; +} dev_info_t; + +// CFG_TUH_DEVICE_MAX is defined by tusb_config header +dev_info_t dev_info[CFG_TUH_DEVICE_MAX] = { 0 }; //--------------------------------------------------------------------+ // Setup and Loop on Core0 //--------------------------------------------------------------------+ // the setup function runs once when you press reset or power the board -void setup() -{ +void setup() { Serial1.begin(115200); Serial.begin(115200); @@ -83,8 +90,7 @@ void setup() Serial.println("TinyUSB Dual Device Info Example"); } -void loop() -{ +void loop() { } //--------------------------------------------------------------------+ @@ -144,20 +150,50 @@ void loop1() //--------------------------------------------------------------------+ // TinyUSB Host callbacks //--------------------------------------------------------------------+ +void print_device_descriptor(tuh_xfer_t* xfer); +void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len); + +void print_lsusb(void) { + bool no_device = true; + for ( uint8_t daddr = 1; daddr < CFG_TUH_DEVICE_MAX+1; daddr++ ) { + // TODO can use tuh_mounted(daddr), but tinyusb has an bug + // use local connected flag instead + dev_info_t* dev = &dev_info[daddr-1]; + if ( dev->mounted ) { + Serial.printf("Device %u: ID %04x:%04x %s %s\r\n", daddr, + dev->desc_device.idVendor, dev->desc_device.idProduct, + (char*) dev->manufacturer, (char*) dev->product); + + no_device = false; + } + } + + if (no_device) { + Serial.println("No device connected (except hub)"); + } +} // Invoked when device is mounted (configured) void tuh_mount_cb (uint8_t daddr) { Serial.printf("Device attached, address = %d\r\n", daddr); + dev_info_t* dev = &dev_info[daddr-1]; + dev->mounted = true; + // Get Device Descriptor - tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); + tuh_descriptor_get_device(daddr, &dev->desc_device, 18, print_device_descriptor, 0); } /// Invoked when device is unmounted (bus reset/unplugged) void tuh_umount_cb(uint8_t daddr) { Serial.printf("Device removed, address = %d\r\n", daddr); + dev_info_t* dev = &dev_info[daddr-1]; + dev->mounted = false; + + // print device summary + print_lsusb(); } void print_device_descriptor(tuh_xfer_t* xfer) @@ -169,45 +205,48 @@ void print_device_descriptor(tuh_xfer_t* xfer) } uint8_t const daddr = xfer->daddr; + dev_info_t* dev = &dev_info[daddr-1]; + tusb_desc_device_t* desc = &dev->desc_device; - Serial.printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); + Serial.printf("Device %u: ID %04x:%04x\r\n", daddr, desc->idVendor, desc->idProduct); Serial.printf("Device Descriptor:\r\n"); - Serial.printf(" bLength %u\r\n" , desc_device.bLength); - Serial.printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType); - Serial.printf(" bcdUSB %04x\r\n" , desc_device.bcdUSB); - Serial.printf(" bDeviceClass %u\r\n" , desc_device.bDeviceClass); - Serial.printf(" bDeviceSubClass %u\r\n" , desc_device.bDeviceSubClass); - Serial.printf(" bDeviceProtocol %u\r\n" , desc_device.bDeviceProtocol); - Serial.printf(" bMaxPacketSize0 %u\r\n" , desc_device.bMaxPacketSize0); - Serial.printf(" idVendor 0x%04x\r\n" , desc_device.idVendor); - Serial.printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); - Serial.printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); + Serial.printf(" bLength %u\r\n" , desc->bLength); + Serial.printf(" bDescriptorType %u\r\n" , desc->bDescriptorType); + Serial.printf(" bcdUSB %04x\r\n" , desc->bcdUSB); + Serial.printf(" bDeviceClass %u\r\n" , desc->bDeviceClass); + Serial.printf(" bDeviceSubClass %u\r\n" , desc->bDeviceSubClass); + Serial.printf(" bDeviceProtocol %u\r\n" , desc->bDeviceProtocol); + Serial.printf(" bMaxPacketSize0 %u\r\n" , desc->bMaxPacketSize0); + Serial.printf(" idVendor 0x%04x\r\n" , desc->idVendor); + Serial.printf(" idProduct 0x%04x\r\n" , desc->idProduct); + Serial.printf(" bcdDevice %04x\r\n" , desc->bcdDevice); // Get String descriptor using Sync API - uint16_t temp_buf[128]; - - Serial.printf(" iManufacturer %u " , desc_device.iManufacturer); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf)) ) - { - print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); + Serial.printf(" iManufacturer %u ", desc->iManufacturer); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, dev->manufacturer, sizeof(dev->manufacturer)) ) { + utf16_to_utf8(dev->manufacturer, sizeof(dev->manufacturer)); + Serial.printf((char*) dev->manufacturer); } Serial.printf("\r\n"); - Serial.printf(" iProduct %u " , desc_device.iProduct); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) - { - print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); + Serial.printf(" iProduct %u ", desc->iProduct); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, dev->product, sizeof(dev->product))) { + utf16_to_utf8(dev->product, sizeof(dev->product)); + Serial.printf((char*) dev->product); } Serial.printf("\r\n"); - Serial.printf(" iSerialNumber %u " , desc_device.iSerialNumber); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) - { - print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); + Serial.printf(" iSerialNumber %u ", desc->iSerialNumber); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, dev->serial, sizeof(dev->serial))) { + utf16_to_utf8(dev->serial, sizeof(dev->serial)); + Serial.printf((char*) dev->serial); } Serial.printf("\r\n"); - Serial.printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); + Serial.printf(" bNumConfigurations %u\r\n", desc->bNumConfigurations); + + // print device summary + print_lsusb(); } //--------------------------------------------------------------------+ @@ -253,13 +292,11 @@ static int _count_utf8_bytes(const uint16_t *buf, size_t len) { return total_bytes; } -static void print_utf16(uint16_t *temp_buf, size_t buf_len) { +void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) { size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); size_t utf8_len = _count_utf8_bytes(temp_buf + 1, utf16_len); - _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); + _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, buf_len); ((uint8_t*) temp_buf)[utf8_len] = '\0'; - - Serial.printf((char*)temp_buf); }