Skip to content

Commit 781181e

Browse files
committed
Added support to press power/sleep/hibernate (and some more) buttons via System Controls.
Implemented in Keyboard_::systemControl().
1 parent 5e3dd2a commit 781181e

File tree

3 files changed

+109
-14
lines changed

3 files changed

+109
-14
lines changed

hardware/arduino/cores/arduino/HID.cpp

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
/* Copyright (c) 2011, Peter Barrett
44
**
5+
** Sleep/Wakeup/SystemControl support added by Michael Dreher
6+
**
57
** Permission to use, copy, modify, and/or distribute this software for
68
** any purpose with or without fee is hereby granted, provided that the
79
** above copyright notice and this permission notice appear in all copies.
@@ -43,16 +45,20 @@ Keyboard_ Keyboard;
4345
#define RAWHID_TX_SIZE 64
4446
#define RAWHID_RX_SIZE 64
4547

48+
#define HID_REPORTID_MOUSE (1)
49+
#define HID_REPORTID_KEYBOARD (2)
50+
#define HID_REPORTID_RAWHID (3)
51+
#define HID_REPORTID_SYSTEMCONTROL (4)
4652
extern const u8 _hidReportDescriptor[] PROGMEM;
4753
const u8 _hidReportDescriptor[] = {
4854

49-
// Mouse
55+
// Mouse
5056
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
5157
0x09, 0x02, // USAGE (Mouse)
5258
0xa1, 0x01, // COLLECTION (Application)
5359
0x09, 0x01, // USAGE (Pointer)
5460
0xa1, 0x00, // COLLECTION (Physical)
55-
0x85, 0x01, // REPORT_ID (1)
61+
0x85, HID_REPORTID_MOUSE, // REPORT_ID (1)
5662
0x05, 0x09, // USAGE_PAGE (Button)
5763
0x19, 0x01, // USAGE_MINIMUM (Button 1)
5864
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
@@ -76,43 +82,73 @@ const u8 _hidReportDescriptor[] = {
7682
0xc0, // END_COLLECTION
7783
0xc0, // END_COLLECTION
7884

79-
// Keyboard
85+
// Keyboard
8086
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47
8187
0x09, 0x06, // USAGE (Keyboard)
8288
0xa1, 0x01, // COLLECTION (Application)
83-
0x85, 0x02, // REPORT_ID (2)
89+
0x85, HID_REPORTID_KEYBOARD, // REPORT_ID (2)
8490
0x05, 0x07, // USAGE_PAGE (Keyboard)
8591

86-
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
92+
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
8793
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
8894
0x15, 0x00, // LOGICAL_MINIMUM (0)
8995
0x25, 0x01, // LOGICAL_MAXIMUM (1)
9096
0x75, 0x01, // REPORT_SIZE (1)
9197

92-
0x95, 0x08, // REPORT_COUNT (8)
98+
0x95, 0x08, // REPORT_COUNT (8)
9399
0x81, 0x02, // INPUT (Data,Var,Abs)
94100
0x95, 0x01, // REPORT_COUNT (1)
95101
0x75, 0x08, // REPORT_SIZE (8)
96102
0x81, 0x03, // INPUT (Cnst,Var,Abs)
97-
98-
0x95, 0x06, // REPORT_COUNT (6)
103+
104+
0x95, 0x06, // REPORT_COUNT (6)
99105
0x75, 0x08, // REPORT_SIZE (8)
100106
0x15, 0x00, // LOGICAL_MINIMUM (0)
101107
0x25, 0x65, // LOGICAL_MAXIMUM (101)
102108
0x05, 0x07, // USAGE_PAGE (Keyboard)
103109

104-
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
110+
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
105111
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
106112
0x81, 0x00, // INPUT (Data,Ary,Abs)
107113
0xc0, // END_COLLECTION
108114

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

114150
0xA1, 0x01, // Collection 0x01
115-
0x85, 0x03, // REPORT_ID (3)
151+
0x85, HID_REPORTID_RAWHID, // REPORT_ID (3)
116152
0x75, 0x08, // report size = 8 bits
117153
0x15, 0x00, // logical minimum = 0
118154
0x26, 0xFF, 0x00, // logical maximum = 255
@@ -228,7 +264,7 @@ void Mouse_::move(signed char x, signed char y, signed char wheel)
228264
m[1] = x;
229265
m[2] = y;
230266
m[3] = wheel;
231-
HID_SendReport(1,m,4);
267+
HID_SendReport(HID_REPORTID_MOUSE,m,sizeof(m));
232268
}
233269

234270
void Mouse_::buttons(uint8_t b)
@@ -275,7 +311,7 @@ void Keyboard_::end(void)
275311

276312
void Keyboard_::sendReport(KeyReport* keys)
277313
{
278-
HID_SendReport(2,keys,sizeof(KeyReport));
314+
HID_SendReport(HID_REPORTID_KEYBOARD,keys,sizeof(*keys));
279315
}
280316

281317
extern
@@ -462,6 +498,38 @@ size_t Keyboard_::press(uint8_t k)
462498
return 1;
463499
}
464500

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

518586
#endif
519587

520-
#endif /* if defined(USBCON) */
588+
#endif /* if defined(USBCON) */

hardware/arduino/cores/arduino/USBAPI.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,30 @@ extern Mouse_ Mouse;
112112
#define KEY_F11 0xCC
113113
#define KEY_F12 0xCD
114114

115+
116+
// System Control values for Keyboard_::systemControl()
117+
// these defines come from the HID usage table "Generic Desktop Page (0x01)"
118+
// in the USB standard document "HID Usage Tables" (HUT1_12v2.pdf)
119+
// Currently this list contains only OSC (one shot control) values,
120+
// the implementation of systemControl will have to be changed when
121+
// adding OOC or RTC values.
122+
#define SYSTEM_CONTROL_POWER_DOWN 1
123+
#define SYSTEM_CONTROL_SLEEP 2
124+
#define SYSTEM_CONTROL_WAKEUP 3
125+
#define SYSTEM_CONTROL_COLD_RESTART 4
126+
#define SYSTEM_CONTROL_WARM_RESTART 5
127+
#define SYSTEM_CONTROL_DOCK 6
128+
#define SYSTEM_CONTROL_UNDOCK 7
129+
#define SYSTEM_CONTROL_SPEAKER_MUTE 8
130+
#define SYSTEM_CONTROL_HIBERNATE 9
131+
#define SYSTEM_CONTROL_DISPLAY_INVERT 10
132+
#define SYSTEM_CONTROL_DISPLAY_INTERNAL 11
133+
#define SYSTEM_CONTROL_DISPLAY_EXTERNAL 12
134+
#define SYSTEM_CONTROL_DISPLAY_BOTH 13
135+
#define SYSTEM_CONTROL_DISPLAY_DUAL 14
136+
#define SYSTEM_CONTROL_DISPLAY_TOGGLE_INT_EXT 15
137+
#define SYSTEM_CONTROL_DISPLAY_SWAP 16
138+
115139
// Low level key report: up to 6 keys and shift, ctrl etc at once
116140
typedef struct
117141
{
@@ -133,6 +157,7 @@ class Keyboard_ : public Print
133157
virtual size_t press(uint8_t k);
134158
virtual size_t release(uint8_t k);
135159
virtual void releaseAll(void);
160+
virtual size_t systemControl(uint8_t k);
136161
};
137162
extern Keyboard_ Keyboard;
138163

@@ -194,4 +219,4 @@ void USB_Flush(uint8_t ep);
194219

195220
#endif
196221

197-
#endif /* if defined(USBCON) */
222+
#endif /* if defined(USBCON) */

hardware/arduino/cores/arduino/USBCore.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
/* Copyright (c) 2010, Peter Barrett
44
**
5+
** Sleep/Wakeup/SystemControl support added by Michael Dreher
6+
**
57
** Permission to use, copy, modify, and/or distribute this software for
68
** any purpose with or without fee is hereby granted, provided that the
79
** above copyright notice and this permission notice appear in all copies.

0 commit comments

Comments
 (0)