承上篇,這篇將摘說明 V-USB hid-mouse 範例程式。
usbconfig.h
底下是 hid-mouse 對 usbconfig.h 所做的調整:
- USB_CFG_IOPORTNAME, USB_CFG_DMINUS_BIT 與 USB_CFG_DPLUS_BIT
這些設定 USB bus D+ 和 D- 所用的接腳。預設是:
#define USB_CFG_IOPORTNAME D
#define USB_CFG_DMINUS_BIT 4
#define USB_CFG_DPLUS_BIT 2
- #define USB_CFG_HAVE_INTRIN_ENDPOINT 1
這個設定 interrupt-in endpoint 1,這是 HID device 的必要選項。
- #define USB_CFG_INTR_POLL_INTERVAL 100
這個設定 interrupt-in endpoint 1 的 poll interval,單位為 miliseconds,不能小於 10 ms。
- USB_CFG_VENDOR_ID 與 USB_CFG_DEVICE_ID
這些設定 VID 和 PID。預設是:
#define USB_CFG_VENDOR_ID 0xc0, 0x16
#define USB_CFG_DEVICE_ID 0xe8, 0x03資料表示方式是 low byte first,VID 0x16c0 和 PID 0x03e8 是 obdev 提供的共享 VID/PID。
- USB_CFG_DEVICE_NAME and USB_CFG_DEVICE_NAME_LEN
這些設定 Device Name 和資料長度,hid-mouse 把 Device Name 設成 "Mouse",資料長度是 5:
#define USB_CFG_DEVICE_NAME 'M', 'o', 'u', 's', 'e'
#define USB_CFG_DEVICE_NAME_LEN 5
- USB_CFG_DEVICE_CLASS 與 USB_CFG_INTERFACE_CLASS
這些設定 Device Class 和 Interface Class。hid-mouse 的設定為:
#define USB_CFG_DEVICE_CLASS 0
#define USB_CFG_INTERFACE_CLASS 3USB 有定義一些常用的 device class,你可以在 USB Class Codes 這個頁面中找到,0 代表由 interface 指定。而 interface class 定義成 3 代表這個是 HID Class。
- #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 52
這個設定 HID report descriptor 的資料長度。你必須在程式裏定義一個叫 usbHidReportDescriptor 的陣列,用來存放 report descriptor,而且陣列 size 要跟這個設定一致為 52 bytes 才行。
main.c
主程式分成 main() 和 usbFunctionSetup() 兩個函式。關於 main() 和 usbFunctionSetup() 兩個函式的說明,請參考「V-USB custom-class 範例解說」一文。
在這個範例程式中,main loop 利用 usbInterruptIsReady() 檢查 Interrupt-In endpoint 1 的 buffer 是否可用,假如可以,便呼叫 advanceCircleByFixedAngle() 計算新的滑鼠座標,接著再呼叫 usbSetInterrupt() 把 reportBuffer 傳給 Host:
底下是 hid-mouse 的 usbFunctionSetup():
程式的邏輯是透過 bRequestType 判斷是不是 class request,假如是就依 bRequest 判斷是哪一種 class request (Get Report, Set Report, Get Idle, Set Idle, Get Protocol 或 Set Protocol)。hid-mouse 只處理 Get Report, Get Idle 和 Set Idle 這三個 requests。除了 Get Report 是必要的外,其它兩個 requests 可以省略不寫。事實上因為 Host 端的 HID Driver 已經知道 report 的格式,所以其實 host 也不會發出這些 requests。
HID Report Descriptor
底下是 hid-mouse 所定義的 HID Report Descriptor:
上列定義一個標準滑鼠,有三個按鈕,X 和 Y 軸的相對座標,以及一個滾輪 (wheel)。而 report 的資料結構如下:
底下簡單說明這個 Report Descriptor 的結構:
首先,必須先定義 Buttons,總共有 3 個 Button:
每個 Button 狀態不是 0 就是 1:
3 個 Button 總共是 3 個位元:
這 3 個位元是 INPUT report:
其它 5 個位元是填充位元 (padding bits):
最後定義 X, Y 和滾輪:
把它們全當成 1 byte 的 signed integer,值域為 -127 到 +127:
每個 8 位元,總共 3 個:
把它們宣告成 INPUT report:
最後告訴電腦這是一個滑鼠:
就這樣。關於 HID Report Descriptor,你也可以參考「HID Report Descriptor 教學」這幾篇文章。
延伸閱讀
- V-USB (Virtual USB port for AVR microcontrollers)
- HID Information
- HID Descriptor Tool
- HID Report Descriptor 教學 #1 #2 #3
0 意見:
張貼留言