Hello, I have a good news. I got STRING DESCRIPTOR working. Based on posts from Wim van der Vegt and info found at USB.org I was able to get mbed introduce to USB host not only with VID & PID but also with name of Manufacturer, Product name, Serial Number, Configuration number and interface name.
So I cut STRING DESCRIPTOR array to multiple STRING DESCRIPTORS arrays each for one string in USBhid.cpp:
unsigned char stringLangidDescriptor[] = {
0x04, /*bLength - must match size of stringLangidDescriptor array (always 4 bytes - hex 0x04) */
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
0x09,0x00, /*bString Lang ID - 0x009 - English*/
};
unsigned char stringImanufacturerDescriptor[] = {
0x12, /*bLength must match size of stringImanufacturerDescriptor array (here 18 bytes - hex 0x12) */
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/
};
unsigned char stringIproductDescriptor[] = {
0x12, /*bLength must match size of stringIproductDescriptor array (here 18 bytes - hex 0x12) */
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'm',0,'b',0,'e',0,'d',0,' ',0,'H',0,'I',0,'D',0, /*bString iProduct - mbed HID*/
};
unsigned char stringIserialDescriptor[] = {
0x16, /*bLength must match size of stringIserialDescriptor array (here 22 bytes - hex 0x16) */
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/
};
unsigned char stringIconfigurationDescriptor[] = {
0x06, /*bLength must match size of stringIconfigurationDescriptor array (here 6 bytes - hex 0x06) */
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'0',0,'1',0, /*bString iConfiguration - 01*/
};
unsigned char stringIinterfaceDescriptor[] = {
0x08, /*bLength must match size of stringIinterfaceDescriptor array (here 8 bytes - hex 0x08) */
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'H',0,'I',0,'D',0, /*bString iInterface - HID*/
};
Then i defined string offset (which string will be send for each ask from host in USBdevice.h:
/*string offset*/
#define STRING_OFFSET_LANGID (0)
#define STRING_OFFSET_IMANUFACTURER (1)
#define STRING_OFFSET_IPRODUCT (2)
#define STRING_OFFSET_ISERIAL (3)
#define STRING_OFFSET_ICONFIGURATION (4)
#define STRING_OFFSET_IINTERFACE (5)
And used this offset in definition of DEVICE DESCRIPTOR and CONFIGURATION DESCRIPTOR in USBhid.cpp:
/* Descriptors */
unsigned char deviceDescriptor[] = {
0x12, /* bLength */
DEVICE_DESCRIPTOR, /* bDescriptorType */
0x00, /* bcdUSB (LSB) */
0x02, /* bcdUSB (MSB) */
0x00, /* bDeviceClass */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceprotocol */
MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
0x28, /* idVendor (LSB) */
0x0d, /* idVendor (MSB) */
0x05, /* idProduct (LSB) */
0x02, /* idProduct (MSB) */
0x00, /* bcdDevice (LSB) */
0x00, /* bcdDevice (MSB) */
STRING_OFFSET_IMANUFACTURER, /* iManufacturer */
STRING_OFFSET_IPRODUCT, /* iProduct */
STRING_OFFSET_ISERIAL, /* iSerialNumber */
0x01 /* bNumConfigurations */
};
unsigned char configurationDescriptor[] = {
0x09, /* bLength */
CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
0x09+0x09+0x09+0x07, /* wTotalLength (LSB) */
0x00, /* wTotalLength (MSB) */
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
STRING_OFFSET_ICONFIGURATION,/* iConfiguration */
0xc0, /* bmAttributes */
0x00, /* bMaxPower */
0x09, /* bLength */
INTERFACE_DESCRIPTOR, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndpoints */
HID_CLASS, /* bInterfaceClass */
HID_SUBCLASS_NONE, /* bInterfaceSubClass */
HID_PROTOCOL_NONE, /* bInterfaceProtocol */
STRING_OFFSET_IINTERFACE, /* iInterface */
0x09, /* bLength */
HID_DESCRIPTOR, /* bDescriptorType */
0x11, /* bcdHID (LSB) */
0x01, /* bcdHID (MSB) */
0x00, /* bCountryCode */
0x01, /* bNumDescriptors */
REPORT_DESCRIPTOR, /* bDescriptorType */
0x79, /* wDescriptorLength (LSB) */
0x00, /* wDescriptorLength (MSB) */
0x07, /* bLength */
ENDPOINT_DESCRIPTOR, /* bDescriptorType */
0x81, /* bEndpointAddress */
0x03, /* bmAttributes */
MAX_PACKET_SIZE_EP1, /* wMaxPacketSize (LSB) */
0x00, /* wMaxPacketSize (MSB) */
0x0a, /* bInterval */
};
I found that USB host asks for each string with offset specified in DEVICE & CONFIGURATION DESCRIPTOR mentoied above. This offset is send from host in wINDEX of STRING DESCRIPTOR request. So I found that i have to send each string based on wIndex request and modified case STRING_DESCRIPTOR in switch in USBhid.cpp to this:
case STRING_DESCRIPTOR:
switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
{
case STRING_OFFSET_LANGID:
transfer.remaining = sizeof(stringLangidDescriptor);
transfer.ptr = stringLangidDescriptor;
transfer.direction = DEVICE_TO_HOST;
success = true;
break;
case STRING_OFFSET_IMANUFACTURER:
transfer.remaining = sizeof(stringImanufacturerDescriptor);
transfer.ptr = stringImanufacturerDescriptor;
transfer.direction = DEVICE_TO_HOST;
success = true;
break;
case STRING_OFFSET_IPRODUCT:
transfer.remaining = sizeof(stringIproductDescriptor);
transfer.ptr = stringIproductDescriptor;
transfer.direction = DEVICE_TO_HOST;
success = true;
break;
case STRING_OFFSET_ISERIAL:
transfer.remaining = sizeof(stringIserialDescriptor);
transfer.ptr = stringIserialDescriptor;
transfer.direction = DEVICE_TO_HOST;
success = true;
break;
case STRING_OFFSET_ICONFIGURATION:
transfer.remaining = sizeof(stringIconfigurationDescriptor);
transfer.ptr = stringIconfigurationDescriptor;
transfer.direction = DEVICE_TO_HOST;
success = true;
break;
case STRING_OFFSET_IINTERFACE:
transfer.remaining = sizeof(stringIinterfaceDescriptor);
transfer.ptr = stringIinterfaceDescriptor;
transfer.direction = DEVICE_TO_HOST;
success = true;
break;
}
So I added another switch into case STRING_DESCRIPTOR which selects proper string based on wIndex - (DESCRIPTOR_INDEX(transfer.setup.wValue)) - value recieved from host in GetDescriptor.
Then it worked but there was also problem because these strings was sent multiple times - Strings was 1 iManufacturer, 2 iProduct, 3 iSerial then 17 iManufacturer, 18 iProduct, 19 iSerial etc each 16 up to string 255.
After time I found how to get send only once. There was definition of DESCRIPTOR_INDEX in USBdevice.h (on which I based selection of sent strings in switch) which was:
#define DESCRIPTOR_INDEX(wValue) (wValue & 0xf)
I changed it to:
#define DESCRIPTOR_INDEX(wValue) (wValue & 0xff)
And then everything works like a charm.
I am newbie in electronics and programing (learn from May) so I would like if somebody experienced can look at code an say if it is OK.
Once again I would like to thank Wim van der Vegt who pointed me to right way.
I will add published example bellow.
EDIT: You can use SimpleHIDwrite utility http://www.lvr.com/files/SimpleHIDWrite3.zip to view this strings.
Good evening, I am working with program USB HID Joystick http://mbed.org/users/bricklife/programs/USBJoystick/ll8vnv based on USB HID Mouse. My target was to add String descriptor which is as TODO list in both programs and is located in USBhid.cpp.
Original code part is :
So I created my own string descriptor based on example I found on keil.com
And modified part of code mentoied above to this:
Program compiles without any warnings or errors but if I use SimpleHIDwrite utility I see this:
As You can see LangID is correctly recognised as english (string with offset 0x00) but iMANUFACTURER and iPRODUCT strings are not recognised and in the name of device appears "?" instead of iPRODUCT.
I also found that if I use this tool on my mouse it lists only strings that have to appear (iMANUFACTURER string1, iPRODUCT string2, etc) but in my test appears String1 "?", String2 "?" up to string255. But I only define 4 strings.
Good list of strings from my mouse looks like this:
I also defined offset for strings in device descriptor:
I would like to ask You for any ideas what is wrong and why. Without changing code in SWITCH for STRING_DESCRIPTOR there was no langID recognised in SimpleHIDwrite tool so code +- works but there is something wrong.
Here are some used defines from start of page. All seems to be OK.
Thank everybody for any help. I am trying to get it work whole day but without success. I am sorry of my english.