]> git.donarmstrong.com Git - qmk_firmware.git/blob - protocol/usb_hid/arduino-1.0.1/cores/arduino/HID.cpp
Change TOP_DIR to TMK_DIR in makefiles
[qmk_firmware.git] / protocol / usb_hid / arduino-1.0.1 / cores / arduino / HID.cpp
1
2
3 /* Copyright (c) 2011, Peter Barrett  
4 **  
5 ** Permission to use, copy, modify, and/or distribute this software for  
6 ** any purpose with or without fee is hereby granted, provided that the  
7 ** above copyright notice and this permission notice appear in all copies.  
8 ** 
9 ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL  
10 ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED  
11 ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR  
12 ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES  
13 ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,  
14 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  
15 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS  
16 ** SOFTWARE.  
17 */
18
19 #include "Platform.h"
20 #include "USBAPI.h"
21 #include "USBDesc.h"
22
23 #if defined(USBCON)
24 #ifdef HID_ENABLED
25
26 //#define RAWHID_ENABLED
27
28 //      Singletons for mouse and keyboard
29
30 Mouse_ Mouse;
31 Keyboard_ Keyboard;
32
33 //================================================================================
34 //================================================================================
35
36 //      HID report descriptor
37
38 #define LSB(_x) ((_x) & 0xFF)
39 #define MSB(_x) ((_x) >> 8)
40
41 #define RAWHID_USAGE_PAGE       0xFFC0
42 #define RAWHID_USAGE            0x0C00
43 #define RAWHID_TX_SIZE 64
44 #define RAWHID_RX_SIZE 64
45
46 extern const u8 _hidReportDescriptor[] PROGMEM;
47 const u8 _hidReportDescriptor[] = {
48         
49         //      Mouse
50     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)      // 54
51     0x09, 0x02,                    // USAGE (Mouse)
52     0xa1, 0x01,                    // COLLECTION (Application)
53     0x09, 0x01,                    //   USAGE (Pointer)
54     0xa1, 0x00,                    //   COLLECTION (Physical)
55     0x85, 0x01,                    //     REPORT_ID (1)
56     0x05, 0x09,                    //     USAGE_PAGE (Button)
57     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
58     0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
59     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
60     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
61     0x95, 0x03,                    //     REPORT_COUNT (3)
62     0x75, 0x01,                    //     REPORT_SIZE (1)
63     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
64     0x95, 0x01,                    //     REPORT_COUNT (1)
65     0x75, 0x05,                    //     REPORT_SIZE (5)
66     0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
67     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
68     0x09, 0x30,                    //     USAGE (X)
69     0x09, 0x31,                    //     USAGE (Y)
70     0x09, 0x38,                    //     USAGE (Wheel)
71     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
72     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
73     0x75, 0x08,                    //     REPORT_SIZE (8)
74     0x95, 0x03,                    //     REPORT_COUNT (3)
75     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
76     0xc0,                          //   END_COLLECTION
77     0xc0,                          // END_COLLECTION
78
79         //      Keyboard
80     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)      // 47
81     0x09, 0x06,                    // USAGE (Keyboard)
82     0xa1, 0x01,                    // COLLECTION (Application)
83     0x85, 0x02,                    //   REPORT_ID (2)
84     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
85    
86         0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
87     0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
88     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
89     0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
90     0x75, 0x01,                    //   REPORT_SIZE (1)
91     
92         0x95, 0x08,                    //   REPORT_COUNT (8)
93     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
94     0x95, 0x01,                    //   REPORT_COUNT (1)
95     0x75, 0x08,                    //   REPORT_SIZE (8)
96     0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
97     
98         0x95, 0x06,                    //   REPORT_COUNT (6)
99     0x75, 0x08,                    //   REPORT_SIZE (8)
100     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
101     0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
102     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
103     
104         0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
105     0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
106     0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
107     0xc0,                          // END_COLLECTION
108
109 #if RAWHID_ENABLED
110         //      RAW HID
111         0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE),   // 30
112         0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
113
114         0xA1, 0x01,                             // Collection 0x01
115     0x85, 0x03,             // REPORT_ID (3)
116         0x75, 0x08,                             // report size = 8 bits
117         0x15, 0x00,                             // logical minimum = 0
118         0x26, 0xFF, 0x00,               // logical maximum = 255
119
120         0x95, 64,                               // report count TX
121         0x09, 0x01,                             // usage
122         0x81, 0x02,                             // Input (array)
123
124         0x95, 64,                               // report count RX
125         0x09, 0x02,                             // usage
126         0x91, 0x02,                             // Output (array)
127         0xC0                                    // end collection
128 #endif
129 };
130
131 extern const HIDDescriptor _hidInterface PROGMEM;
132 const HIDDescriptor _hidInterface =
133 {
134         D_INTERFACE(HID_INTERFACE,1,3,0,0),
135         D_HIDREPORT(sizeof(_hidReportDescriptor)),
136         D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
137 };
138
139 //================================================================================
140 //================================================================================
141 //      Driver
142
143 u8 _hid_protocol = 1;
144 u8 _hid_idle = 1;
145
146 #define WEAK __attribute__ ((weak))
147
148 int WEAK HID_GetInterface(u8* interfaceNum)
149 {
150         interfaceNum[0] += 1;   // uses 1
151         return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface));
152 }
153
154 int WEAK HID_GetDescriptor(int i)
155 {
156         return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));
157 }
158
159 void WEAK HID_SendReport(u8 id, const void* data, int len)
160 {
161         USB_Send(HID_TX, &id, 1);
162         USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
163 }
164
165 bool WEAK HID_Setup(Setup& setup)
166 {
167         u8 r = setup.bRequest;
168         u8 requestType = setup.bmRequestType;
169         if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
170         {
171                 if (HID_GET_REPORT == r)
172                 {
173                         //HID_GetReport();
174                         return true;
175                 }
176                 if (HID_GET_PROTOCOL == r)
177                 {
178                         //Send8(_hid_protocol); // TODO
179                         return true;
180                 }
181         }
182         
183         if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
184         {
185                 if (HID_SET_PROTOCOL == r)
186                 {
187                         _hid_protocol = setup.wValueL;
188                         return true;
189                 }
190
191                 if (HID_SET_IDLE == r)
192                 {
193                         _hid_idle = setup.wValueL;
194                         return true;
195                 }
196         }
197         return false;
198 }
199
200 //================================================================================
201 //================================================================================
202 //      Mouse
203
204 Mouse_::Mouse_(void) : _buttons(0)
205 {
206 }
207
208 void Mouse_::begin(void) 
209 {
210 }
211
212 void Mouse_::end(void) 
213 {
214 }
215
216 void Mouse_::click(uint8_t b)
217 {
218         _buttons = b;
219         move(0,0,0);
220         _buttons = 0;
221         move(0,0,0);
222 }
223
224 void Mouse_::move(signed char x, signed char y, signed char wheel)
225 {
226         u8 m[4];
227         m[0] = _buttons;
228         m[1] = x;
229         m[2] = y;
230         m[3] = wheel;
231         HID_SendReport(1,m,4);
232 }
233
234 void Mouse_::buttons(uint8_t b)
235 {
236         if (b != _buttons)
237         {
238                 _buttons = b;
239                 move(0,0,0);
240         }
241 }
242
243 void Mouse_::press(uint8_t b) 
244 {
245         buttons(_buttons | b);
246 }
247
248 void Mouse_::release(uint8_t b)
249 {
250         buttons(_buttons & ~b);
251 }
252
253 bool Mouse_::isPressed(uint8_t b)
254 {
255         if ((b & _buttons) > 0) 
256                 return true;
257         return false;
258 }
259
260 //================================================================================
261 //================================================================================
262 //      Keyboard
263
264 Keyboard_::Keyboard_(void) 
265 {
266 }
267
268 void Keyboard_::begin(void) 
269 {
270 }
271
272 void Keyboard_::end(void) 
273 {
274 }
275
276 void Keyboard_::sendReport(KeyReport* keys)
277 {
278         HID_SendReport(2,keys,sizeof(KeyReport));
279 }
280
281 extern
282 const uint8_t _asciimap[128] PROGMEM;
283
284 #define SHIFT 0x80
285 const uint8_t _asciimap[128] =
286 {
287         0x00,             // NUL
288         0x00,             // SOH
289         0x00,             // STX
290         0x00,             // ETX
291         0x00,             // EOT
292         0x00,             // ENQ
293         0x00,             // ACK  
294         0x00,             // BEL
295         0x2a,                   // BS   Backspace
296         0x2b,                   // TAB  Tab
297         0x28,                   // LF   Enter
298         0x00,             // VT 
299         0x00,             // FF 
300         0x00,             // CR 
301         0x00,             // SO 
302         0x00,             // SI 
303         0x00,             // DEL
304         0x00,             // DC1
305         0x00,             // DC2
306         0x00,             // DC3
307         0x00,             // DC4
308         0x00,             // NAK
309         0x00,             // SYN
310         0x00,             // ETB
311         0x00,             // CAN
312         0x00,             // EM 
313         0x00,             // SUB
314         0x00,             // ESC
315         0x00,             // FS 
316         0x00,             // GS 
317         0x00,             // RS 
318         0x00,             // US 
319
320         0x2c,              //  ' '
321         0x1e|SHIFT,        // !
322         0x34|SHIFT,        // "
323         0x20|SHIFT,    // #
324         0x21|SHIFT,    // $
325         0x22|SHIFT,    // %
326         0x24|SHIFT,    // &
327         0x34,          // '
328         0x26|SHIFT,    // (
329         0x27|SHIFT,    // )
330         0x25|SHIFT,    // *
331         0x2e|SHIFT,    // +
332         0x36,          // ,
333         0x2d,          // -
334         0x37,          // .
335         0x38,          // /
336         0x27,          // 0
337         0x1e,          // 1
338         0x1f,          // 2
339         0x20,          // 3
340         0x21,          // 4
341         0x22,          // 5
342         0x23,          // 6
343         0x24,          // 7
344         0x25,          // 8
345         0x26,          // 9
346         0x33|SHIFT,      // :
347         0x33,          // ;
348         0x36|SHIFT,      // <
349         0x2e,          // =
350         0x37|SHIFT,      // >
351         0x38|SHIFT,      // ?
352         0x1f|SHIFT,      // @
353         0x04|SHIFT,      // A
354         0x05|SHIFT,      // B
355         0x06|SHIFT,      // C
356         0x07|SHIFT,      // D
357         0x08|SHIFT,      // E
358         0x09|SHIFT,      // F
359         0x0a|SHIFT,      // G
360         0x0b|SHIFT,      // H
361         0x0c|SHIFT,      // I
362         0x0d|SHIFT,      // J
363         0x0e|SHIFT,      // K
364         0x0f|SHIFT,      // L
365         0x10|SHIFT,      // M
366         0x11|SHIFT,      // N
367         0x12|SHIFT,      // O
368         0x13|SHIFT,      // P
369         0x14|SHIFT,      // Q
370         0x15|SHIFT,      // R
371         0x16|SHIFT,      // S
372         0x17|SHIFT,      // T
373         0x18|SHIFT,      // U
374         0x19|SHIFT,      // V
375         0x1a|SHIFT,      // W
376         0x1b|SHIFT,      // X
377         0x1c|SHIFT,      // Y
378         0x1d|SHIFT,      // Z
379         0x2f,          // [
380         0x31,          // bslash
381         0x30,          // ]
382         0x23|SHIFT,    // ^
383         0x2d|SHIFT,    // _
384         0x35,          // `
385         0x04,          // a
386         0x05,          // b
387         0x06,          // c
388         0x07,          // d
389         0x08,          // e
390         0x09,          // f
391         0x0a,          // g
392         0x0b,          // h
393         0x0c,          // i
394         0x0d,          // j
395         0x0e,          // k
396         0x0f,          // l
397         0x10,          // m
398         0x11,          // n
399         0x12,          // o
400         0x13,          // p
401         0x14,          // q
402         0x15,          // r
403         0x16,          // s
404         0x17,          // t
405         0x18,          // u
406         0x19,          // v
407         0x1a,          // w
408         0x1b,          // x
409         0x1c,          // y
410         0x1d,          // z
411         0x2f|SHIFT,    // 
412         0x31|SHIFT,    // |
413         0x30|SHIFT,    // }
414         0x35|SHIFT,    // ~
415         0                               // DEL
416 };
417
418 uint8_t USBPutChar(uint8_t c);
419
420 // press() adds the specified key (printing, non-printing, or modifier)
421 // to the persistent key report and sends the report.  Because of the way 
422 // USB HID works, the host acts like the key remains pressed until we 
423 // call release(), releaseAll(), or otherwise clear the report and resend.
424 size_t Keyboard_::press(uint8_t k) 
425 {
426         uint8_t i;
427         if (k >= 136) {                 // it's a non-printing key (not a modifier)
428                 k = k - 136;
429         } else if (k >= 128) {  // it's a modifier key
430                 _keyReport.modifiers |= (1<<(k-128));
431                 k = 0;
432         } else {                                // it's a printing key
433                 k = pgm_read_byte(_asciimap + k);
434                 if (!k) {
435                         setWriteError();
436                         return 0;
437                 }
438                 if (k & 0x80) {                                         // it's a capital letter or other character reached with shift
439                         _keyReport.modifiers |= 0x02;   // the left shift modifier
440                         k &= 0x7F;
441                 }
442         }
443         
444         // Add k to the key report only if it's not already present
445         // and if there is an empty slot.
446         if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && 
447                 _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
448                 _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
449                 
450                 for (i=0; i<6; i++) {
451                         if (_keyReport.keys[i] == 0x00) {
452                                 _keyReport.keys[i] = k;
453                                 break;
454                         }
455                 }
456                 if (i == 6) {
457                         setWriteError();
458                         return 0;
459                 }       
460         }
461         sendReport(&_keyReport);
462         return 1;
463 }
464
465 // release() takes the specified key out of the persistent key report and
466 // sends the report.  This tells the OS the key is no longer pressed and that
467 // it shouldn't be repeated any more.
468 size_t Keyboard_::release(uint8_t k) 
469 {
470         uint8_t i;
471         if (k >= 136) {                 // it's a non-printing key (not a modifier)
472                 k = k - 136;
473         } else if (k >= 128) {  // it's a modifier key
474                 _keyReport.modifiers &= ~(1<<(k-128));
475                 k = 0;
476         } else {                                // it's a printing key
477                 k = pgm_read_byte(_asciimap + k);
478                 if (!k) {
479                         return 0;
480                 }
481                 if (k & 0x80) {                                                 // it's a capital letter or other character reached with shift
482                         _keyReport.modifiers &= ~(0x02);        // the left shift modifier
483                         k &= 0x7F;
484                 }
485         }
486         
487         // Test the key report to see if k is present.  Clear it if it exists.
488         // Check all positions in case the key is present more than once (which it shouldn't be)
489         for (i=0; i<6; i++) {
490                 if (0 != k && _keyReport.keys[i] == k) {
491                         _keyReport.keys[i] = 0x00;
492                 }
493         }
494
495         sendReport(&_keyReport);
496         return 1;
497 }
498
499 void Keyboard_::releaseAll(void)
500 {
501         _keyReport.keys[0] = 0;
502         _keyReport.keys[1] = 0; 
503         _keyReport.keys[2] = 0;
504         _keyReport.keys[3] = 0; 
505         _keyReport.keys[4] = 0;
506         _keyReport.keys[5] = 0; 
507         _keyReport.modifiers = 0;
508         sendReport(&_keyReport);
509 }
510
511 size_t Keyboard_::write(uint8_t c)
512 {       
513         uint8_t p = press(c);           // Keydown
514         uint8_t r = release(c);         // Keyup
515         return (p);                                     // just return the result of press() since release() almost always returns 1
516 }
517
518 #endif
519
520 #endif /* if defined(USBCON) */