Adding/changing USB descriptors for VUSB for Arduino?

Hello,

I am pulling my hair trying to get multimedia button functionality to the VUSB-for-arduino library.

There are easy ways to add this functionality to the built in keyboard functionality of the Leonardo, but when I try a similar approach with an UNO and VUSB I just cant get it to work. So hoping someone here has done this (I have searched here and on google but havent found anyone who managed to do it yet)...

So, one of the tricks is to change the USB-descriptor, another is to actually make a descriptor that WORKS! Anyways, I have a descriptor that compiles correctly and shows up in my computer as a USB input device.

In USBKeyboard.h I replaced this:

PROGMEM char usbHidReportDescriptor[35] = { /* USB report descriptor */
  0x05, 0x01,                    // USAGE_PAGE (Generic Desktop) 
  0x09, 0x06,                    // USAGE (Keyboard) 
  0xa1, 0x01,                    // COLLECTION (Application) 
  0x05, 0x07,                    //   USAGE_PAGE (Keyboard) 
  0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl) 
  0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI) 
  0x15, 0x00,                    //   LOGICAL_MINIMUM (0) 
  0x25, 0x01,                    //   LOGICAL_MAXIMUM (1) 
  0x75, 0x01,                    //   REPORT_SIZE (1) 
  0x95, 0x08,                    //   REPORT_COUNT (8) 
  0x81, 0x02,                    //   INPUT (Data,Var,Abs) 
  0x95, BUFFER_SIZE-1,           //   REPORT_COUNT (simultaneous keystrokes) 
  0x75, 0x08,                    //   REPORT_SIZE (8) 
  0x25, 0x65,                    //   LOGICAL_MAXIMUM (101) 
  0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated)) 
  0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application) 
  0x81, 0x00,                    //   INPUT (Data,Ary,Abs) 
  0xc0                           // END_COLLECTION 
};

with this:

PROGMEM char usbHidReportDescriptor[37] = { /* USB report descriptor */
	0x05, 0x0C, /*		Usage Page (Consumer Devices)		*/
	0x09, 0x01, /*		Usage (Consumer Control)			*/
	0xA1, 0x01, /*		Collection (Application)			*/
	0x05, 0x0C, /*		Usage Page (Consumer Devices)		*/
	0x15, 0x00, /*		Logical Minimum (0)					*/
	0x25, 0x01, /*		Logical Maximum (1)					*/
	0x75, 0x01, /*		Report Size (1)						*/
	0x95, 0x07, /*		Report Count (7)					*/
	0x09, 0xB5, /*		Usage (Scan Next Track)				*/
	0x09, 0xB6, /*		Usage (Scan Previous Track)			*/
	0x09, 0xB7, /*		Usage (Stop)						*/
	0x09, 0xCD, /*		Usage (Play / Pause)				*/
	0x09, 0xE2, /*		Usage (Mute)						*/
	0x09, 0xE9, /*		Usage (Volume Up)					*/
	0x09, 0xEA, /*		Usage (Volume Down)					*/
	0x81, 0x02, /*		Input (Data, Variable, Absolute)	*/
	0x95, 0x01, /*		Report Count (1)					*/
	0x81, 0x01, /*		Input (Constant)					*/
	0xC0		/*		End Collection */
};

Also some defines after that:

#define KEY_PLAYPAUSE 205 //205 0xcd
#define KEY_MUTE	0xE2 //226	0xe2
#define KEY_PLAY	176 //176	0xb0	
#define KEY_PAUSE	177 //177 	0xb1

Ofcourse also changed this line in usbconfig.h to correlate to the length of the Descriptor:

#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    37

When compiling the device is found as a USB input device.

Then I use the example file that came with V-usb for Arduino and change the keys sent to this:

UsbKeyboard.sendKeyStroke(KEY_PLAYPAUSE);

Above should send a code of 205 to the computer (which is play/pause, and looking in BUS-DOG I get this when pressing the button:

Id	Type	                        Time	       Length	Hex	Ascii	
26	In  (USB URB Function: 9)	0.000000	1	00	.

So, just a 00 value. My guess is that the length of the data is truncated somewhere in the code, but I dont know where. Or also quite probable, there is something in the USB-descriptor that I have written wrongly (also quite probable). OR, there is something else that I missed (well thats obvious)...

Adding USAGE_MINIMUM and USAGE_MAXIMUM does not change anything... Adding REPORT_ID=1 changes nothing. I have tried a lot of different descriptors and combinations. This is the one that has gotten me the furthest, but alas now I feel Im stuck...

So anyone feel they are VUSB-whiz and can come with some pointers :)?

Thanks in advance,
/Kristian

Why are you changing the USB device descriptors, surely this will cause the host system to not use the driver for the leonardo connection.

Which descriptors did you change the manufacturer or the device Id

After you did this, how does the device appear in the windows device manager?

If you are using the same driver but just sending it stuff it doesn't expect, I can't see how this could work either.

Edit.

I took a look at your changes, and you seem to expect the leonardo driver to turn into some other type of device just because you changed the descriptor.
This seems somewhat unlikely.

Sorry about the confusion, I tried to write as much info as possible and I completely missed the hardware side. I am not using a Leonardo (I have it working on it already). What I am trying to accomplish is to get these extra commands using a Arduino UNO (or other ATmega328 based device), along with a HID-interface (see picture), and then modified version of VUSB-for-arduino.

Changing the UsB-descriptors is actually the way to go, to get a HID device to act in a different matter. Since the multimedia keys basically is a keyboard (often integrated in keyboards) I thought it wouldnt be that different. However, somewhere in how the VUSB-for-arduino code handles the values, it either truncates it so I only get the leading 00?

Which descriptors did you change the manufacturer or the device Id
The manufacturer is set in another file, and I did not change this, so it is still RancidBacon.com, I have tried changing the Device ID, from none to 1 to 2,3,4 this doesnt make any difference though...

After you did this, how does the device appear in the windows device manager?
USB Input Deivice

Thanks again,

The latest version of Rancid Bacons V-USB port has example code for creating a HID keyboard and unless I'm missing something I would think just adding your multi-media keys to the UsbKeyboard.h is all you need to do as the descriptor is already configured for HID

Riva, I am using this code. However to add the functionality of these keys the USB descriptor needs to be changed or added to a consumer device (according to USB.org). It can be used to just add this consumer device COLLECTION, as a new DEVICE ID, but I believe this needs more work in the code behind, to find out which DEVICE ID your are working with. So instead I choose to remove the keyboard functionality and keep only the Consumer Device parts...

I'll try your suggestion one more time though... It was just in the beginning of my tampering I did this, so maybe I did some mistake at some other place...

Thanks,