USB HID 教學 #1(轉載)
什麼是 HID Report Descriptor?
HID report descriptor 的用途是定義 reports 的資料格式與使用目的,包括:device 支援多少個 reports, report 的大小,還有 report 中每個 byte 與 bit 的用途。例如,如果是 mouse device,資料會是 mouse movements (滑鼠的移動) 與 button clicks (滑鼠按鍵動作) ;如果是鍵盤,資料會是 keystrokes (按鍵), modifiers (組合鍵或稱輔助鍵) 與 LED Indicators (指示燈) 的輸出狀態。所以,application 只要解讀 report descriptors 便可以知道 report 中的資料是做何種操控 (control) 之用。
HID report descriptor 可以包含多個 reports,而 report 的種類可以分成三種:Input, Output 與 Feature reports。Host 會用 Input report 收資料、用 Output report 送資料,而 Feature report 則是雙向的。
HID 文件
在 http://www.usb.org/developers/hidpage/ 這個頁面中有很多 HID 相關的文件,其中,底下這兩份文件比較重要,是學習 HID 必讀的文件:
HID descriptor tool
同一個頁面上有一支工具,叫做 HID descriptor tool:
這支工具可以用來幫助你產生 report descriptor,是每個寫 report descriptor 的工程師必備的,因為自行翻閱 HID Usage Tables 查表對應代碼以純手工的方式寫 report descriptor 是很累的一件事,用這支工具會省下不少工夫。
HID descriptor tool 內附一些 report descriptors 的範例,在同一個資料夾中副檔名為 .hid 的檔案即是。HID descriptor tool 可以輸出多種格式的檔案,包括 .txt, .inc, .h 等,在打開「另存新檔 ("File > Save as")」這個視窗的時候 ,就可以選擇輸出檔的格式。
以 mouse 為例,打開 mouse.hid 後會看到:
點選 "File > Save As" 開啟「另存新檔」視窗:
在「存檔類型」中選擇 "Header File (*.h)",按下「儲存」鈕,就會產生包含 reports descriptor 的 mouse.h 檔,內容如下:
01 | char ReportDescriptor[50] = { |
02 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) |
03 | 0x09, 0x02, // USAGE (Mouse) |
04 | 0xa1, 0x01, // COLLECTION (Application) |
05 | 0x09, 0x01, // USAGE (Pointer) |
06 | 0xa1, 0x00, // COLLECTION (Physical) |
07 | 0x05, 0x09, // USAGE_PAGE (Button) |
08 | 0x19, 0x01, // USAGE_MINIMUM (Button 1) |
09 | 0x29, 0x03, // USAGE_MAXIMUM (Button 3) |
10 | 0x15, 0x00, // LOGICAL_MINIMUM (0) |
11 | 0x25, 0x01, // LOGICAL_MAXIMUM (1) |
12 | 0x95, 0x03, // REPORT_COUNT (3) |
13 | 0x75, 0x01, // REPORT_SIZE (1) |
14 | 0x81, 0x02, // INPUT (Data,Var,Abs) |
15 | 0x95, 0x01, // REPORT_COUNT (1) |
16 | 0x75, 0x05, // REPORT_SIZE (5) |
17 | 0x81, 0x03, // INPUT (Cnst,Var,Abs) |
18 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) |
19 | 0x09, 0x30, // USAGE (X) |
20 | 0x09, 0x31, // USAGE (Y) |
21 | 0x15, 0x81, // LOGICAL_MINIMUM (-127) |
22 | 0x25, 0x7f, // LOGICAL_MAXIMUM (127) |
23 | 0x75, 0x08, // REPORT_SIZE (8) |
24 | 0x95, 0x02, // REPORT_COUNT (2) |
25 | 0x81, 0x06, // INPUT (Data,Var,Rel) |
26 | 0xc0, // END_COLLECTION |
27 | 0xc0 // END_COLLECTION |
28 | }; |
留言
張貼留言