1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
|
/*
ChibiOS - Copyright (C) 2016 Jonathan Struebel
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_usb_hid.h
* @brief USB HID macros and structures.
*
* @addtogroup USB_HID
* @{
*/
#ifndef HAL_USB_HID_H
#define HAL_USB_HID_H
#if (HAL_USE_USB_HID == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name HID specific messages.
* @{
*/
#define HID_GET_REPORT 0x01U
#define HID_GET_IDLE 0x02U
#define HID_GET_PROTOCOL 0x03U
#define HID_SET_REPORT 0x09U
#define HID_SET_IDLE 0x0AU
#define HID_SET_PROTOCOL 0x0BU
/** @} */
/**
* @name HID classes
* @{
*/
#define HID_INTERFACE_CLASS 0x03U
/** @} */
/**
* @name HID subclasses
* @{
*/
#define HID_BOOT_INTERFACE 0x01U
/** @} */
/**
* @name HID descriptors
* @{
*/
#define USB_DESCRIPTOR_HID 0x21U
#define HID_REPORT 0x22U
#define HID_PHYSICAL 0x23U
/** @} */
/**
* @name HID Report items
* @{
*/
#define HID_REPORT_INPUT 0x80
#define HID_REPORT_OUTPUT 0x90
#define HID_REPORT_COLLECTION 0xA0
#define HID_REPORT_FEATURE 0xB0
#define HID_REPORT_END_COLLECTION 0xC0
#define HID_REPORT_USAGE_PAGE 0x04
#define HID_REPORT_LOGICAL_MINIMUM 0x14
#define HID_REPORT_LOGICAL_MAXIMUM 0x24
#define HID_REPORT_PHYSICAL_MINIMUM 0x34
#define HID_REPORT_PHYSICAL_MAXIMUM 0x44
#define HID_REPORT_UNIT_EXPONENT 0x54
#define HID_REPORT_UNIT 0x64
#define HID_REPORT_REPORT_SIZE 0x74
#define HID_REPORT_REPORT_ID 0x84
#define HID_REPORT_REPORT_COUNT 0x94
#define HID_REPORT_REPORT_PUSH 0xA4
#define HID_REPORT_REPORT_POP 0xB4
#define HID_REPORT_USAGE 0x08
#define HID_REPORT_USAGE_MINIMUM 0x18
#define HID_REPORT_USAGE_MAXIMUM 0x28
#define HID_REPORT_DESIGNATOR_INDEX 0x38
#define HID_REPORT_DESIGNATOR_MINUMUM 0x48
#define HID_REPORT_DESIGNATOR_MAXIMUM 0x58
#define HID_REPORT_STRING_INDEX 0x78
#define HID_REPORT_STRING_MINUMUM 0x88
#define HID_REPORT_STRING_MAXIMUM 0x98
#define HID_REPORT_DELIMITER 0xA8
/** @} */
/**
* @name HID Collection item definitions
* @{
*/
#define HID_COLLECTION_PHYSICAL 0x00
#define HID_COLLECTION_APPLICATION 0x01
#define HID_COLLECTION_LOGICAL 0x02
#define HID_COLLECTION_REPORT 0x03
#define HID_COLLECTION_NAMED_ARRAY 0x04
#define HID_COLLECTION_USAGE_SWITCH 0x05
#define HID_COLLECTION_USAGE_MODIFIER 0x06
/** @} */
/**
* @name HID Usage Page item definitions
* @{
*/
#define HID_USAGE_PAGE_GENERIC_DESKTOP 0x01
#define HID_USAGE_PAGE_SIMULATION 0x02
#define HID_USAGE_PAGE_VR 0x03
#define HID_USAGE_PAGE_SPORT 0x04
#define HID_USAGE_PAGE_GAME 0x05
#define HID_USAGE_PAGE_GENERIC_DEVICE 0x06
#define HID_USAGE_PAGE_KEYBOARD_KEYPAD 0x07
#define HID_USAGE_PAGE_LEDS 0x08
#define HID_USAGE_PAGE_BUTTON 0x09
#define HID_USAGE_PAGE_ORDINAL 0x0A
#define HID_USAGE_PAGE_TELEPHONY 0x0B
#define HID_USAGE_PAGE_CONSUMER 0x0C
#define HID_USAGE_PAGE_DIGITIZER 0x0D
#define HID_USAGE_PAGE_PID 0x0F
#define HID_USAGE_PAGE_UNICODE 0x10
#define HID_USAGE_PAGE_VENDOR 0xFF00
/** @} */
/**
* @name HID Usage item definitions
* @{
*/
#define HID_USAGE_ALPHANUMERIC_DISPLAY 0x14
#define HID_USAGE_MEDICAL_INSTRUMENTS 0x40
#define HID_USAGE_MONITOR_PAGE1 0x80
#define HID_USAGE_MONITOR_PAGE2 0x81
#define HID_USAGE_MONITOR_PAGE3 0x82
#define HID_USAGE_MONITOR_PAGE4 0x83
#define HID_USAGE_POWER_PAGE1 0x84
#define HID_USAGE_POWER_PAGE2 0x85
#define HID_USAGE_POWER_PAGE3 0x86
#define HID_USAGE_POWER_PAGE4 0x87
#define HID_USAGE_BAR_CODE_SCANNER_PAGE 0x8C
#define HID_USAGE_SCALE_PAGE 0x8D
#define HID_USAGE_MSR_PAGE 0x8E
#define HID_USAGE_CAMERA_PAGE 0x90
#define HID_USAGE_ARCADE_PAGE 0x91
#define HID_USAGE_POINTER 0x01
#define HID_USAGE_MOUSE 0x02
#define HID_USAGE_JOYSTICK 0x04
#define HID_USAGE_GAMEPAD 0x05
#define HID_USAGE_KEYBOARD 0x06
#define HID_USAGE_KEYPAD 0x07
#define HID_USAGE_MULTIAXIS_CONTROLLER 0x08
#define HID_USAGE_BUTTON1 0x01
#define HID_USAGE_BUTTON2 0x02
#define HID_USAGE_BUTTON3 0x03
#define HID_USAGE_BUTTON4 0x04
#define HID_USAGE_BUTTON5 0x05
#define HID_USAGE_BUTTON6 0x06
#define HID_USAGE_BUTTON7 0x07
#define HID_USAGE_BUTTON8 0x08
#define HID_USAGE_X 0x30
#define HID_USAGE_Y 0x31
#define HID_USAGE_Z 0x32
#define HID_USAGE_RX 0x33
#define HID_USAGE_RY 0x34
#define HID_USAGE_RZ 0x35
#define HID_USAGE_VX 0x40
#define HID_USAGE_VY 0x41
#define HID_USAGE_VZ 0x42
#define HID_USAGE_VBRX 0x43
#define HID_USAGE_VBRY 0x44
#define HID_USAGE_VBRZ 0x45
#define HID_USAGE_VNO 0x46
/** @} */
/**
* @name HID item types definitions
* @{
*/
#define HID_ITEM_DATA 0x00
#define HID_ITEM_CNST 0x01
#define HID_ITEM_ARR 0x00
#define HID_ITEM_VAR 0x02
#define HID_ITEM_ABS 0x00
#define HID_ITEM_REL 0x04
#define HID_ITEM_NWRP 0x00
#define HID_ITEM_WRP 0x08
#define HID_ITEM_LIN 0x00
#define HID_ITEM_NLIN 0x10
#define HID_ITEM_PRF 0x00
#define HID_ITEM_NPRF 0x20
#define HID_ITEM_NNUL 0x00
#define HID_ITEM_NUL 0x40
#define HID_ITEM_NVOL 0x00
#define HID_ITEM_VOL 0x80
#define HID_ITEM_DATA_VAR_ABS (HID_ITEM_DATA | \
HID_ITEM_VAR | \
HID_ITEM_ABS)
#define HID_ITEM_CNST_VAR_ABS (HID_ITEM_CNST | \
HID_ITEM_VAR | \
HID_ITEM_ABS)
#define HID_ITEM_DATA_VAR_REL (HID_ITEM_DATA | \
HID_ITEM_VAR | \
HID_ITEM_REL)
/** @} */
/**
* @name Helper macros for USB HID descriptors
* @{
*/
/*
* @define HID Descriptor size.
*/
#define USB_DESC_HID_SIZE 9U
/**
* @brief HID Descriptor helper macro.
* @note This macro can only be used with a single HID report descriptor
*/
#define USB_DESC_HID(bcdHID, bCountryCode, bNumDescriptors, \
bDescriptorType, wDescriptorLength) \
USB_DESC_BYTE(USB_DESC_HID_SIZE), \
USB_DESC_BYTE(USB_DESCRIPTOR_HID), \
USB_DESC_BCD(bcdHID), \
USB_DESC_BYTE(bCountryCode), \
USB_DESC_BYTE(bNumDescriptors), \
USB_DESC_BYTE(bDescriptorType), \
USB_DESC_WORD(wDescriptorLength)
/**
* @brief HID Report item helper macro (Single byte).
*/
#define HID_ITEM_B(id, value) \
USB_DESC_BYTE(id | 0x01), \
USB_DESC_BYTE(value)
/**
* @brief HID Report item helper macro (Double byte).
*/
#define HID_ITEM_W(id, value) \
USB_DESC_BYTE(id | 0x02), \
USB_DESC_WORD(value)
/**
* @brief HID Report Usage Page item helper macro (Single byte).
*/
#define HID_USAGE_PAGE_B(up) \
HID_ITEM_B(HID_REPORT_USAGE_PAGE, up)
/**
* @brief HID Report Usage Page item helper macro (Double byte).
*/
#define HID_USAGE_PAGE_W(up) \
HID_ITEM_W(HID_REPORT_USAGE_PAGE, up)
/**
* @brief HID Report Usage item helper macro (Single byte).
*/
#define HID_USAGE_B(u) \
HID_ITEM_B(HID_REPORT_USAGE, u)
/**
* @brief HID Report Usage item helper macro (Double byte).
*/
#define HID_USAGE_W(u) \
HID_ITEM_W(HID_REPORT_USAGE, u)
/**
* @brief HID Report Collection item helper macro (Single Byte).
*/
#define HID_COLLECTION_B(c) \
HID_ITEM_B(HID_REPORT_COLLECTION, c)
/**
* @brief HID Report Collection item helper macro (Double Byte).
*/
#define HID_COLLECTION_W(c) \
HID_ITEM_W(HID_REPORT_COLLECTION, c)
/**
* @brief HID Report End Collection item helper macro.
*/
#define HID_END_COLLECTION \
USB_DESC_BYTE(HID_REPORT_END_COLLECTION)
/**
* @brief HID Report Usage Minimum item helper macro (Single byte).
*/
#define HID_USAGE_MINIMUM_B(x) \
HID_ITEM_B(HID_REPORT_USAGE_MINIMUM, x)
/**
* @brief HID Report Usage Minimum item helper macro (Double byte).
*/
#define HID_USAGE_MINIMUM_W(x) \
HID_ITEM_W(HID_REPORT_USAGE_MINIMUM, x)
/**
* @brief HID Report Usage Maximum item helper macro (Single byte).
*/
#define HID_USAGE_MAXIMUM_B(x) \
HID_ITEM_B(HID_REPORT_USAGE_MAXIMUM, x)
/**
* @brief HID Report Usage Maximum item helper macro (Double byte).
*/
#define HID_USAGE_MAXIMUM_W(x) \
HID_ITEM_W(HID_REPORT_USAGE_MAXIMUM, x)
/**
* @brief HID Report Logical Minimum item helper macro (Single byte).
*/
#define HID_LOGICAL_MINIMUM_B(x) \
HID_ITEM_B(HID_REPORT_LOGICAL_MINIMUM, x)
/**
* @brief HID Report Logical Minimum item helper macro (Double byte).
*/
#define HID_LOGICAL_MINIMUM_W(x) \
HID_ITEM_W(HID_REPORT_LOGICAL_MINIMUM, x)
/**
* @brief HID Report Logical Maximum item helper macro (Single byte).
*/
#define HID_LOGICAL_MAXIMUM_B(x) \
HID_ITEM_B(HID_REPORT_LOGICAL_MAXIMUM, x)
/**
* @brief HID Report Logical Maximum item helper macro (Double byte).
*/
#define HID_LOGICAL_MAXIMUM_W(x) \
HID_ITEM_W(HID_REPORT_LOGICAL_MAXIMUM, x)
/**
* @brief HID Report ID item helper macro (Single byte).
*/
#define HID_REPORT_ID_B(x) \
HID_ITEM_B(HID_REPORT_REPORT_ID, x)
/**
* @brief HID Report ID item helper macro (Double byte).
*/
#define HID_REPORT_ID_W(x) \
HID_ITEM_W(HID_REPORT_REPORT_ID, x)
/**
* @brief HID Report Count item helper macro (Single byte).
*/
#define HID_REPORT_COUNT_B(x) \
HID_ITEM_B(HID_REPORT_REPORT_COUNT, x)
/**
* @brief HID Report Count item helper macro (Double byte).
*/
#define HID_REPORT_COUNT_W(x) \
HID_ITEM_W(HID_REPORT_REPORT_COUNT, x)
/**
* @brief HID Report Size item helper macro (Single byte).
*/
#define HID_REPORT_SIZE_B(x) \
HID_ITEM_B(HID_REPORT_REPORT_SIZE, x)
/**
* @brief HID Report Size item helper macro (Double byte).
*/
#define HID_REPORT_SIZE_W(x) \
HID_ITEM_W(HID_REPORT_REPORT_SIZE, x)
/**
* @brief HID Report Input item helper macro (Single byte).
*/
#define HID_INPUT_B(x) \
HID_ITEM_B(HID_REPORT_INPUT, x)
/**
* @brief HID Report Input item helper macro (Double byte).
*/
#define HID_INPUT_W(x) \
HID_ITEM_W(HID_REPORT_INPUT, x)
/** @} */
/**
* @brief HID Report Output item helper macro (Single byte).
*/
#define HID_OUTPUT_B(x) \
HID_ITEM_B(HID_REPORT_OUTPUT, x)
/**
* @brief HID Report Output item helper macro (Double byte).
*/
#define HID_OUTPUT_W(x) \
HID_ITEM_W(HID_REPORT_OUTPUT, x)
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name USB HID configuration options
* @{
*/
/**
* @brief USB HID buffers size.
* @details Configuration parameter, the buffer size must be a multiple of
* the USB data endpoint maximum packet size.
* @note The default is 256 bytes for both the transmission and receive
* buffers.
*/
#if !defined(USB_HID_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define USB_HID_BUFFERS_SIZE 256
#endif
/**
* @brief USB HID number of buffers.
* @note The default is 2 buffers.
*/
#if !defined(USB_HID_BUFFERS_NUMBER) || defined(__DOXYGEN__)
#define USB_HID_BUFFERS_NUMBER 2
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if HAL_USE_USB == FALSE
#error "USB HID Driver requires HAL_USE_USB"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Driver state machine possible states.
*/
typedef enum {
HID_UNINIT = 0, /**< Not initialized. */
HID_STOP = 1, /**< Stopped. */
HID_READY = 2 /**< Ready. */
} hidstate_t;
/**
* @brief Structure representing a USB HID driver.
*/
typedef struct USBHIDDriver USBHIDDriver;
/**
* @brief USB HID Driver configuration structure.
* @details An instance of this structure must be passed to @p hidStart()
* in order to configure and start the driver operations.
*/
typedef struct {
/**
* @brief USB driver to use.
*/
USBDriver *usbp;
/**
* @brief Interrupt IN endpoint used for outgoing data transfer.
*/
usbep_t int_in;
/**
* @brief Interrupt OUT endpoint used for incoming data transfer.
*/
usbep_t int_out;
} USBHIDConfig;
/**
* @brief @p USBHIDDriver specific data.
*/
#define _usb_hid_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
hidstate_t state; \
/* Input buffers queue.*/ \
input_buffers_queue_t ibqueue; \
/* Output queue.*/ \
output_buffers_queue_t obqueue; \
/* Input buffer.*/ \
uint8_t ib[BQ_BUFFER_SIZE(USB_HID_BUFFERS_NUMBER, \
USB_HID_BUFFERS_SIZE)]; \
/* Output buffer.*/ \
uint8_t ob[BQ_BUFFER_SIZE(USB_HID_BUFFERS_NUMBER, \
USB_HID_BUFFERS_SIZE)]; \
/* End of the mandatory fields.*/ \
/* Current configuration data.*/ \
const USBHIDConfig *config;
/**
* @brief @p USBHIDDriver specific methods.
*/
#define _usb_hid_driver_methods \
_base_asynchronous_channel_methods \
/* Buffer flush method.*/ \
void (*flush)(void *instance);
/**
* @extends BaseAsynchronousChannelVMT
*
* @brief @p USBHIDDriver virtual methods table.
*/
struct USBHIDDriverVMT {
_usb_hid_driver_methods
};
/**
* @extends BaseAsynchronousChannel
*
* @brief Full duplex USB HID driver class.
* @details This class extends @p BaseAsynchronousChannel by adding physical
* I/O queues.
*/
struct USBHIDDriver {
/** @brief Virtual Methods Table.*/
const struct USBHIDDriverVMT *vmt;
_usb_hid_driver_data
};
#define USB_DRIVER_EXT_FIELDS \
USBHIDDriver hid
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hidInit(void);
void hidObjectInit(USBHIDDriver *uhdp);
void hidStart(USBHIDDriver *uhdp, const USBHIDConfig *config);
void hidStop(USBHIDDriver *uhdp);
void hidDisconnectI(USBHIDDriver *uhdp);
void hidConfigureHookI(USBHIDDriver *uhdp);
bool hidRequestsHook(USBDriver *usbp);
void hidDataTransmitted(USBDriver *usbp, usbep_t ep);
void hidDataReceived(USBDriver *usbp, usbep_t ep);
size_t hidWriteReport(USBHIDDriver *uhdp, uint8_t *bp, size_t n);
size_t hidWriteReportt(USBHIDDriver *uhdp, uint8_t *bp, size_t n, systime_t timeout);
size_t hidReadReport(USBHIDDriver *uhdp, uint8_t *bp, size_t n);
size_t hidReadReportt(USBHIDDriver *uhdp, uint8_t *bp, size_t n, systime_t timeout);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_USB_HID */
#endif /* HAL_USB_HID_H */
/** @} */
|