Skip to content

Commit 4388bed

Browse files
nospam2000obra
authored andcommitted
Add support for the USB HID SystemControl page
1 parent 60e6c34 commit 4388bed

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

hardware/arduino/avr/cores/arduino/HID.cpp

+65-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ Keyboard_ Keyboard;
4444
#define HID_REPORTID_MOUSE (1)
4545
#define HID_REPORTID_KEYBOARD (2)
4646
#define HID_REPORTID_RAWHID (3)
47+
#define HID_REPORTID_SYSTEMCONTROL (4)
48+
4749
extern const u8 _hidReportDescriptor[] PROGMEM;
4850
const u8 _hidReportDescriptor[] = {
4951

@@ -107,7 +109,37 @@ const u8 _hidReportDescriptor[] = {
107109
0x81, 0x00, // INPUT (Data,Ary,Abs)
108110
0xc0, // END_COLLECTION
109111

110-
#ifdef RAWHID_ENABLED
112+
// System Control (Power Down, Sleep, Wakeup, ...)
113+
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
114+
0x09, 0x80, // USAGE (System Control)
115+
0xa1, 0x01, // COLLECTION (Application)
116+
0x85, HID_REPORTID_SYSTEMCONTROL,// REPORT_ID (4)
117+
0x09, 0x81, // USAGE (System Power Down)
118+
0x09, 0x82, // USAGE (System Sleep)
119+
0x09, 0x83, // USAGE (System Wakeup)
120+
0x09, 0x8E, // USAGE (System Cold Restart)
121+
0x09, 0x8F, // USAGE (System Warm Restart)
122+
0x09, 0xA0, // USAGE (System Dock)
123+
0x09, 0xA1, // USAGE (System Undock)
124+
0x09, 0xA7, // USAGE (System Speaker Mute)
125+
0x09, 0xA8, // USAGE (System Hibernate)
126+
// although these display usages are not that important, they don't cost much more than declaring
127+
// the otherwise necessary constant fill bits
128+
0x09, 0xB0, // USAGE (System Display Invert)
129+
0x09, 0xB1, // USAGE (System Display Internal)
130+
0x09, 0xB2, // USAGE (System Display External)
131+
0x09, 0xB3, // USAGE (System Display Both)
132+
0x09, 0xB4, // USAGE (System Display Dual)
133+
0x09, 0xB5, // USAGE (System Display Toggle Intern/Extern)
134+
0x09, 0xB6, // USAGE (System Display Swap)
135+
0x15, 0x00, // LOGICAL_MINIMUM (0)
136+
0x25, 0x01, // LOGICAL_MAXIMUM (1)
137+
0x75, 0x01, // REPORT_SIZE (1)
138+
0x95, 0x10, // REPORT_COUNT (16)
139+
0x81, 0x02, // INPUT (Data,Var,Abs)
140+
0xc0, // END_COLLECTION
141+
142+
#if RAWHID_ENABLED
111143
// RAW HID
112144
0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
113145
0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
@@ -463,6 +495,38 @@ size_t Keyboard_::press(uint8_t k)
463495
return 1;
464496
}
465497

498+
// System Control
499+
// k is one of the SYSTEM_CONTROL defines which come from the HID usage table "Generic Desktop Page (0x01)"
500+
// in "HID Usage Tables" (HUT1_12v2.pdf)
501+
size_t Keyboard_::systemControl(uint8_t k)
502+
{
503+
if(k <= 16)
504+
{
505+
u16 mask = 0;
506+
u8 m[2];
507+
508+
if(k > 0)
509+
{
510+
mask = 1 << (k - 1);
511+
}
512+
513+
m[0] = LSB(mask);
514+
m[1] = MSB(mask);
515+
HID_SendReport(HID_REPORTID_SYSTEMCONTROL,m,sizeof(m));
516+
517+
// these are all OSCs, so send a clear to make it possible to send it again later
518+
m[0] = 0;
519+
m[1] = 0;
520+
HID_SendReport(HID_REPORTID_SYSTEMCONTROL,m,sizeof(m));
521+
return 1;
522+
}
523+
else
524+
{
525+
setWriteError();
526+
return 0;
527+
}
528+
}
529+
466530
// release() takes the specified key out of the persistent key report and
467531
// sends the report. This tells the OS the key is no longer pressed and that
468532
// it shouldn't be repeated any more.

hardware/arduino/avr/cores/arduino/USBAPI.h

+25
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,30 @@ extern Mouse_ Mouse;
159159
#define KEY_F11 0xCC
160160
#define KEY_F12 0xCD
161161

162+
163+
// System Control values for Keyboard_::systemControl()
164+
// these defines come from the HID usage table "Generic Desktop Page (0x01)"
165+
// in the USB standard document "HID Usage Tables" (HUT1_12v2.pdf)
166+
// Currently this list contains only OSC (one shot control) values,
167+
// the implementation of systemControl will have to be changed when
168+
// adding OOC or RTC values.
169+
#define SYSTEM_CONTROL_POWER_DOWN 1
170+
#define SYSTEM_CONTROL_SLEEP 2
171+
#define SYSTEM_CONTROL_WAKEUP 3
172+
#define SYSTEM_CONTROL_COLD_RESTART 4
173+
#define SYSTEM_CONTROL_WARM_RESTART 5
174+
#define SYSTEM_CONTROL_DOCK 6
175+
#define SYSTEM_CONTROL_UNDOCK 7
176+
#define SYSTEM_CONTROL_SPEAKER_MUTE 8
177+
#define SYSTEM_CONTROL_HIBERNATE 9
178+
#define SYSTEM_CONTROL_DISPLAY_INVERT 10
179+
#define SYSTEM_CONTROL_DISPLAY_INTERNAL 11
180+
#define SYSTEM_CONTROL_DISPLAY_EXTERNAL 12
181+
#define SYSTEM_CONTROL_DISPLAY_BOTH 13
182+
#define SYSTEM_CONTROL_DISPLAY_DUAL 14
183+
#define SYSTEM_CONTROL_DISPLAY_TOGGLE_INT_EXT 15
184+
#define SYSTEM_CONTROL_DISPLAY_SWAP 16
185+
162186
// Low level key report: up to 6 keys and shift, ctrl etc at once
163187
#define KEYREPORT_KEYCOUNT 0x06
164188
typedef struct
@@ -181,6 +205,7 @@ class Keyboard_ : public Print
181205
virtual size_t press(uint8_t k);
182206
virtual size_t release(uint8_t k);
183207
virtual void releaseAll(void);
208+
virtual size_t systemControl(uint8_t k);
184209
};
185210
extern Keyboard_ Keyboard;
186211

0 commit comments

Comments
 (0)