For a project, I need media keys (play, volume, mute, …) and a way to lock a computer under Windows (Windows+L keys). There is a lot of HID keyboard descriptors on the Internet, some are for keyboards + media but all contain at least one unused byte… Not a good thing for embedded systems with constraint memory. Why? The descriptor can be found in USB-IF example (Appendix B) and describe a boot compatible keyboard. So unless you need your keyboard in boot menus, this byte can be dropped. Also, the example defines 6 simultaneous keys, I decreased it to three as I don’t need more.
Consumer device
profile allows a lot of actions, which can be found in
HID usage tables
document, in ยง15 consumer page
. I selected some relevant to my application
(media keys), but you can add more if required: just increase the report count
and add the new key.
Note that each started byte must be padded with constant bits, so if your
report count
is not a multiple of 8, add a constant section.
How to use it?
Prepare an uint8_t
table with a size matching the amount of data you have to
send plus one for the descriptor (first byte). For media keys, each bit of the
second byte will correspond to one key, LSB is the first in the descriptor. For
a keyboard, the second byte is for modifiers, and the third, fourth, fifth are
for keys.
Those examples are related to the following descriptor.
uint8_t bufferHID[5] = {0, 0, 0, 0, 0};
// Send media mute
bufferHID[0] = 2; // Start with the report ID
bufferHID[1] = 0x20; // Set mute bit to 1
USB_HID_SendReport(bufferHID, 2); // Only 2 bytes required : report ID + media keys byte.
// Send Windows+L
bufferHID[0] = 1; // Start with the report ID
bufferHID[1] = 0x08; // Set left GUI bit to 1 - Windows or Apple/Cmd key
bufferHID[2] = 0x0F; // 'l' key
USB_HID_SendReport(bufferHID, 5); // 5 bytes required : report ID + keyboard[4]
delay(30); // Leave some time for the USB stack
bufferHID[1] = 0; // Release keys
bufferHID[2] = 0;
USB_HID_SendReport(bufferHID, 5); // Send released keys
Descriptor
- Keyboard
- Modifiers (MSB-LSB) :
RIGHT_GUI
-RIGHT_ALT
-RIGHT_SHIFT
-RIGHT_CTRL
-LEFT_GUI
-LEFT_ALT
-LEFT_SHIFT
-LEFT_CTRL
- Media keys
- Keys (MSB-LSB) :
Next
-Previous
-Stop
-Eject
-Play/Pause
-Mute
-Vol inc
-Vol dec
Descriptor
// 78 bytes
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x19, 0xE0, // Usage Minimum (0xE0)
0x29, 0xE7, // Usage Maximum (0xE7)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x03, // Report Count (3)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x64, // Logical Maximum (100)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0x00, // Usage Minimum (0x00)
0x29, 0x65, // Usage Maximum (0x65)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x02, // Report ID (2)
0x05, 0x0C, // Usage Page (Consumer)
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, 0xB8, // Usage (Eject)
0x09, 0xCD, // Usage (Play/Pause)
0x09, 0xE2, // Usage (Mute)
0x09, 0xE9, // Usage (Volume Increment)
0x09, 0xEA, // Usage (Volume Decrement)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
Helpful defines
// USB media codes
#define USB_HID_SCAN_NEXT 0x01
#define USB_HID_SCAN_PREV 0x02
#define USB_HID_STOP 0x04
#define USB_HID_EJECT 0x08
#define USB_HID_PAUSE 0x10
#define USB_HID_MUTE 0x20
#define USB_HID_VOL_UP 0x40
#define USB_HID_VOL_DEC 0x80
// USB keyboard codes
#define USB_HID_MODIFIER_LEFT_CTRL 0x01
#define USB_HID_MODIFIER_LEFT_SHIFT 0x02
#define USB_HID_MODIFIER_LEFT_ALT 0x04
#define USB_HID_MODIFIER_LEFT_GUI 0x08 // (Win/Apple/Meta)
#define USB_HID_MODIFIER_RIGHT_CTRL 0x10
#define USB_HID_MODIFIER_RIGHT_SHIFT 0x20
#define USB_HID_MODIFIER_RIGHT_ALT 0x40
#define USB_HID_MODIFIER_RIGHT_GUI 0x80
#define USB_HID_KEY_L 0x0F
Documentation
- Most useful page I read about custom HID descriptors
- USB HID usage table to find key codes.
- Next, how to implemnt it on STM32 targets.
Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Pinterest
Email