Project

General

Profile

Statistics
| Branch: | Revision:

root / arduino-1.0 / hardware / arduino / cores / arduino / HID.cpp @ 58d82c77

History | View | Annotate | Download (11.2 KB)

1 58d82c77 Tom Mullins
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
#define WEAK 
148
149
int WEAK HID_GetInterface(u8* interfaceNum)
150
{
151
        interfaceNum[0] += 1;        // uses 1
152
        return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface));
153
}
154
155
int WEAK HID_GetDescriptor(int i)
156
{
157
        return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));
158
}
159
160
void WEAK HID_SendReport(u8 id, const void* data, int len)
161
{
162
        USB_Send(HID_TX, &id, 1);
163
        USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
164
}
165
166
bool WEAK HID_Setup(Setup& setup)
167
{
168
        u8 r = setup.bRequest;
169
        u8 requestType = setup.bmRequestType;
170
        if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
171
        {
172
                if (HID_GET_REPORT == r)
173
                {
174
                        //HID_GetReport();
175
                        return true;
176
                }
177
                if (HID_GET_PROTOCOL == r)
178
                {
179
                        //Send8(_hid_protocol);        // TODO
180
                        return true;
181
                }
182
        }
183
        
184
        if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
185
        {
186
                if (HID_SET_PROTOCOL == r)
187
                {
188
                        _hid_protocol = setup.wValueL;
189
                        return true;
190
                }
191
192
                if (HID_SET_IDLE == r)
193
                {
194
                        _hid_idle = setup.wValueL;
195
                        return true;
196
                }
197
        }
198
        return false;
199
}
200
201
//================================================================================
202
//================================================================================
203
//        Mouse
204
205
Mouse_::Mouse_() : _buttons(0)
206
{
207
}
208
209
void Mouse_::click(uint8_t b)
210
{
211
        _buttons = b;
212
        move(0,0,0);
213
        _buttons = 0;
214
        move(0,0,0);
215
}
216
217
void Mouse_::move(signed char x, signed char y, signed char wheel)
218
{
219
        u8 m[4];
220
        m[0] = _buttons;
221
        m[1] = x;
222
        m[2] = y;
223
        m[3] = wheel;
224
        HID_SendReport(1,m,4);
225
}
226
227
void Mouse_::buttons(uint8_t b)
228
{
229
        if (b != _buttons)
230
        {
231
                _buttons = b;
232
                move(0,0,0);
233
        }
234
}
235
236
void Mouse_::press(uint8_t b) 
237
{
238
        buttons(_buttons | b);
239
}
240
241
void Mouse_::release(uint8_t b)
242
{
243
        buttons(_buttons & ~b);
244
}
245
246
bool Mouse_::isPressed(uint8_t b)
247
{
248
        if (b & _buttons > 0) 
249
                return true;
250
        return false;
251
}
252
253
//================================================================================
254
//================================================================================
255
//        Keyboard
256
257
Keyboard_::Keyboard_() : _keyMap(0)
258
{
259
}
260
261
void Keyboard_::sendReport(KeyReport* keys)
262
{
263
        HID_SendReport(2,keys,sizeof(KeyReport));
264
}
265
266
void Keyboard_::setKeyMap(KeyMap* keyMap)
267
{
268
        _keyMap = keyMap;
269
}
270
271
extern
272
const uint8_t _asciimap[128] PROGMEM;
273
274
#define SHIFT 0x80
275
const uint8_t _asciimap[128] =
276
{
277
        0x00,             // NUL
278
        0x00,             // SOH
279
        0x00,             // STX
280
        0x00,             // ETX
281
        0x00,             // EOT
282
        0x00,             // ENQ
283
        0x00,             // ACK  
284
        0x00,             // BEL
285
        0x2a,                        // BS        Backspace
286
        0x2b,                        // TAB        Tab
287
        0x28,                        // LF        Enter
288
        0x00,             // VT 
289
        0x00,             // FF 
290
        0x00,             // CR 
291
        0x00,             // SO 
292
        0x00,             // SI 
293
        0x00,             // DEL
294
        0x00,             // DC1
295
        0x00,             // DC2
296
        0x00,             // DC3
297
        0x00,             // DC4
298
        0x00,             // NAK
299
        0x00,             // SYN
300
        0x00,             // ETB
301
        0x00,             // CAN
302
        0x00,             // EM 
303
        0x00,             // SUB
304
        0x00,             // ESC
305
        0x00,             // FS 
306
        0x00,             // GS 
307
        0x00,             // RS 
308
        0x00,             // US 
309
310
        0x2c,                   //  ' '
311
        0x1e|SHIFT,           // !
312
        0x34|SHIFT,           // "
313
        0x20|SHIFT,    // #
314
        0x21|SHIFT,    // $
315
        0x22|SHIFT,    // %
316
        0x24|SHIFT,    // &
317
        0x34,          // '
318
        0x26|SHIFT,    // (
319
        0x27|SHIFT,    // )
320
        0x25|SHIFT,    // *
321
        0x2e|SHIFT,    // +
322
        0x36,          // ,
323
        0x2d,          // -
324
        0x37,          // .
325
        0x38,          // /
326
        0x27,          // 0
327
        0x1e,          // 1
328
        0x1f,          // 2
329
        0x20,          // 3
330
        0x21,          // 4
331
        0x22,          // 5
332
        0x23,          // 6
333
        0x24,          // 7
334
        0x25,          // 8
335
        0x26,          // 9
336
        0x33|SHIFT,      // :
337
        0x33,          // ;
338
        0x36|SHIFT,      // <
339
        0x2e,          // =
340
        0x37|SHIFT,      // >
341
        0x38|SHIFT,      // ?
342
        0x1f|SHIFT,      // @
343
        0x04|SHIFT,      // A
344
        0x05|SHIFT,      // B
345
        0x06|SHIFT,      // C
346
        0x07|SHIFT,      // D
347
        0x08|SHIFT,      // E
348
        0x09|SHIFT,      // F
349
        0x0a|SHIFT,      // G
350
        0x0b|SHIFT,      // H
351
        0x0c|SHIFT,      // I
352
        0x0d|SHIFT,      // J
353
        0x0e|SHIFT,      // K
354
        0x0f|SHIFT,      // L
355
        0x10|SHIFT,      // M
356
        0x11|SHIFT,      // N
357
        0x12|SHIFT,      // O
358
        0x13|SHIFT,      // P
359
        0x14|SHIFT,      // Q
360
        0x15|SHIFT,      // R
361
        0x16|SHIFT,      // S
362
        0x17|SHIFT,      // T
363
        0x18|SHIFT,      // U
364
        0x19|SHIFT,      // V
365
        0x1a|SHIFT,      // W
366
        0x1b|SHIFT,      // X
367
        0x1c|SHIFT,      // Y
368
        0x1d|SHIFT,      // Z
369
        0x2f,          // [
370
        0x31,          // bslash
371
        0x30,          // ]
372
        0x23|SHIFT,    // ^
373
        0x2d|SHIFT,    // _
374
        0x35,          // `
375
        0x04,          // a
376
        0x05,          // b
377
        0x06,          // c
378
        0x07,          // d
379
        0x08,          // e
380
        0x09,          // f
381
        0x0a,          // g
382
        0x0b,          // h
383
        0x0c,          // i
384
        0x0d,          // j
385
        0x0e,          // k
386
        0x0f,          // l
387
        0x10,          // m
388
        0x11,          // n
389
        0x12,          // o
390
        0x13,          // p
391
        0x14,          // q
392
        0x15,          // r
393
        0x16,          // s
394
        0x17,          // t
395
        0x18,          // u
396
        0x19,          // v
397
        0x1a,          // w
398
        0x1b,          // x
399
        0x1c,          // y
400
        0x1d,          // z
401
        0x2f|SHIFT,    // 
402
        0x31|SHIFT,    // |
403
        0x30|SHIFT,    // }
404
        0x35|SHIFT,    // ~
405
        0                                // DEL
406
};
407
408
uint8_t USBPutChar(uint8_t c);
409
size_t Keyboard_::write(uint8_t c)
410
{
411
        // Keydown
412
        {
413
                KeyReport keys = {0};
414
                if (_keyMap)
415
                        _keyMap->charToKey(c,&keys);
416
                else
417
                {
418
                        if (c >= 128) {
419
                                setWriteError();
420
                                return 0;
421
                        }
422
                        c = pgm_read_byte(_asciimap + c);
423
                        if (!c) {
424
                                setWriteError();
425
                                return 0;
426
                        }
427
                        if (c & 0x80)
428
                        {
429
                                keys.modifiers |= KEY_MODIFIER_LEFT_SHIFT;
430
                                c &= 0x7F;
431
                        }
432
                        keys.keys[0] = c;
433
                }
434
                sendReport(&keys);
435
        }
436
        //        Keyup
437
        {
438
                KeyReport keys = {0};
439
                sendReport(&keys);
440
        }
441
        return 1;
442
}
443
444
#endif
445
446
#endif /* if defined(USBCON) */