aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/include/hal_usb_hid.h
blob: d50c455fc80cdbbd267cb2087a0702a40ac38b9e (plain)
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 */

/** @} */