diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp index 7a6351d8e..c489d9f1a 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -50,6 +50,15 @@ int PluggableUSB_::getDescriptor(USBSetup& setup) return 0; } +void PluggableUSB_::getShortName(char *iSerialNum) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + iSerialNum += node->getShortName(iSerialNum); + } + *iSerialNum = 0; +} + bool PluggableUSB_::setup(USBSetup& setup) { PluggableUSBModule* node; diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h index 3df9bfff5..507f0df9b 100644 --- a/hardware/arduino/avr/cores/arduino/PluggableUSB.h +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -35,6 +35,7 @@ protected: virtual bool setup(USBSetup& setup) = 0; virtual int getInterface(uint8_t* interfaceCount) = 0; virtual int getDescriptor(USBSetup& setup) = 0; + virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; } uint8_t pluggedInterface; uint8_t pluggedEndpoint; @@ -55,6 +56,7 @@ public: int getInterface(uint8_t* interfaceCount); int getDescriptor(USBSetup& setup); bool setup(USBSetup& setup); + void getShortName(char *iSerialNum); private: uint8_t lastIf; diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index f67bfeabc..3c6610cd6 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -18,6 +18,7 @@ #include "USBAPI.h" #include "PluggableUSB.h" +#include #if defined(USBCON) @@ -69,10 +70,10 @@ const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER; // DEVICE DESCRIPTOR const DeviceDescriptor USB_DeviceDescriptor = - D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); + D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1); const DeviceDescriptor USB_DeviceDescriptorB = - D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); + D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1); //================================================================== //================================================================== @@ -409,11 +410,12 @@ int USB_SendControl(u8 flags, const void* d, int len) // Send a USB descriptor string. The string is stored in PROGMEM as a // plain ASCII string but is sent out as UTF-16 with the correct 2-byte // prefix -static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len) { +static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len, uint8_t flags) { SendControl(2 + string_len * 2); SendControl(3); + bool pgm = flags & TRANSFER_PGM; for(u8 i = 0; i < string_len; i++) { - bool r = SendControl(pgm_read_byte(&string_P[i])); + bool r = SendControl(pgm ? pgm_read_byte(&string_P[i]) : string_P[i]); r &= SendControl(0); // high byte if(!r) { return false; @@ -495,10 +497,17 @@ bool SendDescriptor(USBSetup& setup) desc_addr = (const u8*)&STRING_LANGUAGE; } else if (setup.wValueL == IPRODUCT) { - return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT)); + return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM); } else if (setup.wValueL == IMANUFACTURER) { - return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER)); + return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER), TRANSFER_PGM); + } + else if (setup.wValueL == ISERIAL) { +#ifdef PLUGGABLE_USB_ENABLED + char name[ISERIAL_MAX_LEN]; + PluggableUSB().getShortName(name); + return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0); +#endif } else return false; diff --git a/hardware/arduino/avr/cores/arduino/USBDesc.h b/hardware/arduino/avr/cores/arduino/USBDesc.h index 4b9cf6636..c0dce079e 100644 --- a/hardware/arduino/avr/cores/arduino/USBDesc.h +++ b/hardware/arduino/avr/cores/arduino/USBDesc.h @@ -24,6 +24,8 @@ #define USB_ENDPOINTS 5 // AtMegaxxU2 #endif +#define ISERIAL_MAX_LEN 20 + #define CDC_INTERFACE_COUNT 2 #define CDC_ENPOINT_COUNT 3 @@ -39,6 +41,6 @@ #define CDC_RX CDC_ENDPOINT_OUT #define CDC_TX CDC_ENDPOINT_IN -#define IMANUFACTURER 1 -#define IPRODUCT 2 - +#define IMANUFACTURER 1 +#define IPRODUCT 2 +#define ISERIAL 3 \ No newline at end of file diff --git a/hardware/arduino/avr/libraries/HID/HID.cpp b/hardware/arduino/avr/libraries/HID/HID.cpp index 411529ecf..1a432fffd 100644 --- a/hardware/arduino/avr/libraries/HID/HID.cpp +++ b/hardware/arduino/avr/libraries/HID/HID.cpp @@ -57,6 +57,16 @@ int HID_::getDescriptor(USBSetup& setup) return total; } +uint8_t HID_::getShortName(char *name) +{ + name[0] = 'H'; + name[1] = 'I'; + name[2] = 'D'; + name[3] = 'A' + (descriptorSize & 0x0F); + name[4] = 'A' + ((descriptorSize >> 4) & 0x0F); + return 5; +} + void HID_::AppendDescriptor(HIDSubDescriptor *node) { if (!rootNode) { diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h index ba08da7be..b6638c889 100644 --- a/hardware/arduino/avr/libraries/HID/HID.h +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -96,6 +96,7 @@ protected: int getInterface(uint8_t* interfaceCount); int getDescriptor(USBSetup& setup); bool setup(USBSetup& setup); + uint8_t getShortName(char* name); private: uint8_t epType[1];