16
16
#include " usbdrv.h"
17
17
#include " keylayouts.h"
18
18
19
-
20
19
typedef uint8_t byte;
21
20
22
-
23
21
#define BUFFER_SIZE 2 // Minimum of 2: 1 for modifiers + 1 for keystroke
24
22
25
-
26
- static uchar idleRate; // in 4 ms units
27
-
23
+ static uchar idleRate; // in 4 ms units
28
24
29
25
/* We use a simplifed keyboard report descriptor which does not support the
30
26
* boot protocol. We don't allow setting status LEDs and but we do allow
@@ -35,26 +31,25 @@ static uchar idleRate; // in 4 ms units
35
31
* for the second INPUT item.
36
32
*/
37
33
const PROGMEM uchar usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
38
- 0x05 , 0x01 , // USAGE_PAGE (Generic Desktop)
39
- 0x09 , 0x06 , // USAGE (Keyboard)
40
- 0xa1 , 0x01 , // COLLECTION (Application)
41
- 0x05 , 0x07 , // USAGE_PAGE (Keyboard)
42
- 0x19 , 0xe0 , // USAGE_MINIMUM (Keyboard LeftControl)
43
- 0x29 , 0xe7 , // USAGE_MAXIMUM (Keyboard Right GUI)
44
- 0x15 , 0x00 , // LOGICAL_MINIMUM (0)
45
- 0x25 , 0x01 , // LOGICAL_MAXIMUM (1)
46
- 0x75 , 0x01 , // REPORT_SIZE (1)
47
- 0x95 , 0x08 , // REPORT_COUNT (8)
48
- 0x81 , 0x02 , // INPUT (Data,Var,Abs)
49
- 0x95 , 0x01 , // REPORT_COUNT (simultaneous keystrokes)
50
- 0x75 , 0x08 , // REPORT_SIZE (8)
51
- 0x25 , 0x65 , // LOGICAL_MAXIMUM (101)
52
- 0x19 , 0x00 , // USAGE_MINIMUM (Reserved (no event indicated))
53
- 0x29 , 0x65 , // USAGE_MAXIMUM (Keyboard Application)
54
- 0x81 , 0x00 , // INPUT (Data,Ary,Abs)
55
- 0xc0 // END_COLLECTION
56
- };
57
-
34
+ 0x05 , 0x01 , // USAGE_PAGE (Generic Desktop)
35
+ 0x09 , 0x06 , // USAGE (Keyboard)
36
+ 0xa1 , 0x01 , // COLLECTION (Application)
37
+ 0x05 , 0x07 , // USAGE_PAGE (Keyboard)
38
+ 0x19 , 0xe0 , // USAGE_MINIMUM (Keyboard LeftControl)
39
+ 0x29 , 0xe7 , // USAGE_MAXIMUM (Keyboard Right GUI)
40
+ 0x15 , 0x00 , // LOGICAL_MINIMUM (0)
41
+ 0x25 , 0x01 , // LOGICAL_MAXIMUM (1)
42
+ 0x75 , 0x01 , // REPORT_SIZE (1)
43
+ 0x95 , 0x08 , // REPORT_COUNT (8)
44
+ 0x81 , 0x02 , // INPUT (Data,Var,Abs)
45
+ 0x95 , 0x01 , // REPORT_COUNT (simultaneous keystrokes)
46
+ 0x75 , 0x08 , // REPORT_SIZE (8)
47
+ 0x25 , 0x65 , // LOGICAL_MAXIMUM (101)
48
+ 0x19 , 0x00 , // USAGE_MINIMUM (Reserved (no event indicated))
49
+ 0x29 , 0x65 , // USAGE_MAXIMUM (Keyboard Application)
50
+ 0x81 , 0x00 , // INPUT (Data,Ary,Abs)
51
+ 0xc0 // END_COLLECTION
52
+ };
58
53
59
54
#define MOD_CONTROL_LEFT MODIFIERKEY_LEFT_CTRL
60
55
#define MOD_SHIFT_LEFT MODIFIERKEY_LEFT_SHIFT
@@ -65,158 +60,164 @@ const PROGMEM uchar usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH]
65
60
#define MOD_ALT_RIGHT MODIFIERKEY_RIGHT_ALT
66
61
#define MOD_GUI_RIGHT MODIFIERKEY_RIGHT_GUI
67
62
68
- class DigiKeyboardDevice : public Print {
69
- public:
70
- DigiKeyboardDevice () {
71
- cli ();
72
- usbDeviceDisconnect ();
73
- _delay_ms (250 );
74
- usbDeviceConnect ();
75
-
76
-
77
- usbInit ();
78
-
79
- sei ();
80
-
81
- // TODO: Remove the next two lines once we fix
82
- // missing first keystroke bug properly.
83
- memset (reportBuffer, 0 , sizeof (reportBuffer));
84
- usbSetInterrupt (reportBuffer, sizeof (reportBuffer));
85
- }
86
-
87
- void update () {
88
- usbPoll ();
89
- }
90
-
91
- // delay while updating until we are finished delaying
92
- void delay (long milli) {
93
- unsigned long last = millis ();
94
- while (milli > 0 ) {
95
- unsigned long now = millis ();
96
- milli -= now - last;
97
- last = now;
98
- update ();
99
- }
100
- }
101
-
102
- // sendKeyStroke: sends a key press AND release
103
- void sendKeyStroke (byte keyStroke) {
104
- sendKeyStroke (keyStroke, 0 );
105
- }
106
-
107
- // sendKeyStroke: sends a key press AND release with modifiers
108
- void sendKeyStroke (byte keyStroke, byte modifiers) {
109
- sendKeyPress (keyStroke, modifiers);
110
- // This stops endlessly repeating keystrokes:
111
- sendKeyPress (0 ,0 );
112
- }
113
-
114
- // sendKeyPress: sends a key press only - no release
115
- // to release the key, send again with keyPress=0
116
- void sendKeyPress (byte keyPress) {
117
- sendKeyPress (keyPress, 0 );
118
- }
119
-
120
- // sendKeyPress: sends a key press only, with modifiers - no release
121
- // to release the key, send again with keyPress=0
122
- void sendKeyPress (byte keyPress, byte modifiers) {
123
- while (!usbInterruptIsReady ()) {
124
- // Note: We wait until we can send keyPress
125
- // so we know the previous keyPress was
126
- // sent.
127
- usbPoll ();
128
- _delay_ms (5 );
63
+ class DigiKeyboardDevice : public Print {
64
+ public:
65
+ DigiKeyboardDevice () {
66
+ noInterrupts ();
67
+ usbDeviceDisconnect ();
68
+ _delay_ms (250 );
69
+ usbDeviceConnect ();
70
+
71
+ usbInit ();
72
+
73
+ interrupts ();
74
+
75
+ // TODO: Remove the next two lines once we fix
76
+ // missing first keystroke bug properly.
77
+ memset (reportBuffer, 0 , sizeof (reportBuffer));
78
+ usbSetInterrupt (reportBuffer, sizeof (reportBuffer));
129
79
}
130
80
131
- memset (reportBuffer, 0 , sizeof (reportBuffer));
132
-
133
- reportBuffer[0 ] = modifiers;
134
- reportBuffer[1 ] = keyPress;
135
-
136
- usbSetInterrupt (reportBuffer, sizeof (reportBuffer));
137
- }
138
-
139
- uint8_t keycode_to_modifier (KEYCODE_TYPE keycode){
140
- uint8_t modifier=0 ;
141
-
142
- #ifdef SHIFT_MASK
143
- if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT;
144
- #endif
145
- #ifdef ALTGR_MASK
146
- if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT;
147
- #endif
148
- #ifdef RCTRL_MASK
149
- if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL;
150
- #endif
151
- return modifier;
152
- }
153
-
154
- uint8_t keycode_to_key (KEYCODE_TYPE keycode){
155
- uint8_t key = keycode & 0x3F ;
156
- #ifdef KEY_NON_US_100
157
- if (key == KEY_NON_US_100) key = 100 ;
158
- #endif
159
- return key;
160
- }
161
-
162
- size_t write (uint8_t chr) {
163
- uint8_t data = 0 ;
164
- if (chr == 0x09 ) {
165
- data = (uint8_t )KEY_TAB;
166
- }else if (chr == 0x0a ) {
167
- data = (uint8_t )KEY_ENTER;
168
- }else if (chr >= 0x20 ) {
169
- data = pgm_read_byte_near (keycodes_ascii + (chr - 0x20 ));
81
+ void update () {
82
+ usbPoll ();
170
83
}
171
- if (data) {
172
- sendKeyStroke (keycode_to_key (data), keycode_to_modifier (data));
84
+
85
+ // delay while updating until we are finished delaying
86
+ void delay (long milli) {
87
+ unsigned long last = millis ();
88
+ while (milli > 0 ) {
89
+ unsigned long now = millis ();
90
+ milli -= now - last;
91
+ last = now;
92
+ update ();
93
+ }
94
+ }
95
+
96
+ // sendKeyStroke: sends a key press AND release
97
+ void sendKeyStroke (byte keyStroke) {
98
+ sendKeyStroke (keyStroke, 0 );
99
+ }
100
+
101
+ // sendKeyStroke: sends a key press AND release with modifiers
102
+ void sendKeyStroke (byte keyStroke, byte modifiers) {
103
+ sendKeyPress (keyStroke, modifiers);
104
+ // This stops endlessly repeating keystrokes:
105
+ sendKeyPress (0 , 0 );
106
+ }
107
+
108
+ // sendKeyPress: sends a key press only - no release
109
+ // to release the key, send again with keyPress=0
110
+ void sendKeyPress (byte keyPress) {
111
+ sendKeyPress (keyPress, 0 );
173
112
}
174
- return 1 ;
175
- }
176
113
177
- // private: TODO: Make friend?
178
- uchar reportBuffer[2 ]; // buffer for HID reports [ 1 modifier byte + (len-1) key strokes]
179
- using Print::write;
114
+ // sendKeyPress: sends a key press only, with modifiers - no release
115
+ // to release the key, send again with keyPress=0
116
+ void sendKeyPress (byte keyPress, byte modifiers) {
117
+ while (!usbInterruptIsReady ()) {
118
+ // Note: We wait until we can send keyPress
119
+ // so we know the previous keyPress was
120
+ // sent.
121
+ usbPoll ();
122
+ _delay_ms (5 );
123
+ }
124
+
125
+ memset (reportBuffer, 0 , sizeof (reportBuffer));
126
+
127
+ reportBuffer[0 ] = modifiers;
128
+ reportBuffer[1 ] = keyPress;
129
+
130
+ usbSetInterrupt (reportBuffer, sizeof (reportBuffer));
131
+ }
132
+
133
+ uint8_t keycode_to_modifier (KEYCODE_TYPE keycode) {
134
+ uint8_t modifier = 0 ;
135
+
136
+ #ifdef SHIFT_MASK
137
+ if (keycode & SHIFT_MASK)
138
+ modifier |= MODIFIERKEY_SHIFT;
139
+ #endif
140
+ #ifdef ALTGR_MASK
141
+ if (keycode & ALTGR_MASK)
142
+ modifier |= MODIFIERKEY_RIGHT_ALT;
143
+ #endif
144
+ #ifdef RCTRL_MASK
145
+ if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL;
146
+ #endif
147
+ return modifier;
148
+ }
149
+
150
+ uint8_t keycode_to_key (KEYCODE_TYPE keycode) {
151
+ uint8_t key = keycode & 0x3F ;
152
+ #ifdef KEY_NON_US_100
153
+ if (key == KEY_NON_US_100) {
154
+ key = 100 ;
155
+ }
156
+ #endif
157
+ return key;
158
+ }
159
+
160
+ /*
161
+ * Convert ASCII to USB code
162
+ */
163
+ size_t write (uint8_t chr) {
164
+ uint8_t data = 0 ;
165
+ if (chr == 0x09 ) {
166
+ data = (uint8_t ) KEY_TAB;
167
+ } else if (chr == 0x0a ) {
168
+ data = (uint8_t ) KEY_ENTER;
169
+ } else if (chr >= 0x20 ) {
170
+ // read from mapping table
171
+ data = pgm_read_byte_near (keycodes_ascii + (chr - 0x20 ));
172
+ }
173
+ if (data) {
174
+ sendKeyStroke (keycode_to_key (data), keycode_to_modifier (data));
175
+ }
176
+ return 1 ;
177
+ }
178
+
179
+ // private: TODO: Make friend?
180
+ uchar reportBuffer[2 ]; // buffer for HID reports [ 1 modifier byte + (len-1) key strokes]
181
+ using Print::write;
180
182
};
181
183
182
184
DigiKeyboardDevice DigiKeyboard = DigiKeyboardDevice();
183
185
184
186
#ifdef __cplusplus
185
- extern " C" {
187
+ extern " C" {
186
188
#endif
187
- // USB_PUBLIC uchar usbFunctionSetup
188
- uchar usbFunctionSetup (uchar data[8 ]) {
189
- usbRequest_t *rq = (usbRequest_t *)((void *)data);
189
+ // USB_PUBLIC uchar usbFunctionSetup
190
+ uchar usbFunctionSetup (uchar data[8 ]) {
191
+ usbRequest_t *rq = (usbRequest_t *) ((void *) data);
190
192
191
193
usbMsgPtr = DigiKeyboard.reportBuffer ; //
192
194
if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
193
- /* class request type */
195
+ /* class request type */
194
196
195
- if (rq->bRequest == USBRQ_HID_GET_REPORT) {
196
- /* wValue: ReportType (highbyte), ReportID (lowbyte) */
197
+ if (rq->bRequest == USBRQ_HID_GET_REPORT) {
198
+ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
197
199
198
- /* we only have one report type, so don't look at wValue */
199
- // TODO: Ensure it's okay not to return anything here?
200
- return 0 ;
200
+ /* we only have one report type, so don't look at wValue */
201
+ // TODO: Ensure it's okay not to return anything here?
202
+ return 0 ;
201
203
202
- } else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
203
- // usbMsgPtr = &idleRate;
204
- // return 1;
205
- return 0 ;
204
+ } else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
205
+ // usbMsgPtr = &idleRate;
206
+ // return 1;
207
+ return 0 ;
206
208
207
- } else if (rq->bRequest == USBRQ_HID_SET_IDLE) {
208
- idleRate = rq->wValue .bytes [1 ];
209
+ } else if (rq->bRequest == USBRQ_HID_SET_IDLE) {
210
+ idleRate = rq->wValue .bytes [1 ];
209
211
210
- }
212
+ }
211
213
} else {
212
- /* no vendor specific requests implemented */
214
+ /* no vendor specific requests implemented */
213
215
}
214
216
215
217
return 0 ;
216
- }
218
+ }
217
219
#ifdef __cplusplus
218
220
} // extern "C"
219
221
#endif
220
222
221
-
222
223
#endif // __DigiKeyboard_h__
0 commit comments