USB HID ブートデバイスのレポートディスクリプタ

どうもよくわからないところがあったのでまとめておく。

HID 1.11 Appendix B: Boot Interface Descriptors, B.1 Protocol 1 (Keyboard) より

Usage Page (Generic Desktop),
Usage (Keyboard),
Collection (Application),

  // Input Byte 0: キーボードモディファイア
  Report Size (1), // 1bit を 8 回
  Report Count (8),
  Usage Page (Key Codes),
  Usage Minimum (224), // LeftCtrl から Right GUI まで
  Usage Maximum (231), 
  Logical Minimum (0), // 0 または 1 で
  Logical Maximum (1),
  Input (Data, Variable, Absolute), // 可変の絶対値データ

  // Input Byte 1: 定数
  Report Count (1), // 1byte 分の定数を予約
  Report Size (8),
  Input (Constant), // パディングは定数で

  // Input Byte 2-7: キーコード
  Report Count (6), // キーコード 1-6
  Report Size (8), // 各キーコードは 1byte
  Logical Minimum (0), // この場合、コードは Usage ID と一致
  Logical Maximum(255),
  Usage Page (Key Codes),
  Usage Minimum (0), // 0-255 Usage ID で全キー
  Usage Maximum (255),
  Input (Data, Array), // データは配列

  // Output Byte 1: LED
  Report Count (5), // データは 5bit 分
  Report Size (1),
  Usage Page (LEDs),
  Usage Minimum (1), // NUM LOCK から KANA まで
  Usage Maximum (5),
  Output (Data, Variable, Absolute),
  Report Count (1), // 残りの 3bit 分を定数で埋める
  Report Size (3),
  Output (Constant),
End Collection

Input と Output がごちゃまぜに定義されているようでも、実際に渡すデータは以下のようになる。

Input データ構造。

Byte76543210
0Right
GUI
Right
Alt
Right
Shift
Right
Ctrl
Left
GUI
Left
Alt
Left
Shift
Left
Ctrl
1Reserved
2KeyCode 1
3KeyCode 2
4KeyCode 3
5KeyCode 4
6KeyCode 5
7KeyCode 6

モディファイア部分もUsage IDで定義されている。他のキーのデータも1bit単位で押したかどうかを送信するのであれば120キー分を15バイトで送信できる。
Usage IDは16bit分あるが実際に定義されているのは0-231の範囲のみ。すべてのキー位置を29バイトで指定できるので、USB インタラプト転送の送信上限64バイトでも問題なく送信できる。しかし、この形式では押していないキーの分のデータもいつも送信しなければならない。
この方法はデバイスドライバがHIDディスクリプタを正しく解釈してくれなければ動作しない。


Output データ構造。HID 1.11 8.3、HUT 1.11 11 LED Page (0x08) 参照。

Bit 説明
0 NUM LOCK
1 CAPS LOCK
2 SCROLL LOCK
3 COMPOSE
4 KANA
5 - CONSTANT
6 - CONSTANT
7 - CONSTANT

ついでにブートマウスのレポートディスクリプタ

Usage Page (Generic Desktop),
Usage (Mouse),
Collection (Application),
  Usage (Pointer),
  Collection (Physical),

    Report Count (3), // 1 バイト目の 3 ビット分
    Report Size (1),
    Usage Page (Buttons), // ボタン用 Page から
    Usage Minimum (1), // Button 1 (primary/trigger), Button 2 (secondary), Button 3 (tertiary)
    Usage Maximum (3),
    Logical Minimum (0), // 0 または 1 (OFF/ON)
    Logical Maximum (1),
    Input (Data, Variable, Absolute), // データは可変絶対値

    Report Count (1), // 1 バイト目の 4-7 ビット分
    Report Size (5),
    Input (Constant), // パッディングとして定数

    Report Size (8), // 1 バイトデータを 2 ヶ
    Report Count (2),
    Usage Page (Generic Desktop), Usage Generic Desctop Page から
    Usage (X), // X および Y データ
    Usage (Y),
    Logical Minimum (-127), // 許容するデータの範囲は -127 - 127
    Logical Maximum (127),
    Input (Data, Variable, Relative), // データは可変相対値
  End Collection,
End Collection

Byte76543210
0ReservedBtn2Btn1Btn0
1X
2Y

B.2 Protocol 2 (Mouse) では 4 to 7 がデバイス固有となっているが、実際は 3 to 7 のはず。