一、USB HID的設備描述符分析
USB HID的設備描述符用以下結構定義:
Device_Property
DEVICE_PROP Device_Property =
{
CustomHID_init,
CustomHID_Reset,
CustomHID_Status_In,
CustomHID_Status_Out,
CustomHID_Data_Setup,
CustomHID_NoData_Setup,
CustomHID_Get_Interface_Setting,
CustomHID_GetDeviceDescriptor,
CustomHID_GetConfigDescriptor,
CustomHID_GetStringDescriptor,
0,
0x40/*MAX PACKET SIZE*/
};
這是裝載了多個函數指針的結構體,用于統(tǒng)一管理USB的多屬性及狀態(tài),包括USB初始化、復位、輸入輸出狀態(tài)、數據傳輸參數請求、獲得設備狀態(tài)、設備描述符、配置描述符以及字符串描述符。下面按定義順序介紹下其中主要函數的含義:
1.USB初始化
包括IO初始化、控制管腳初始化、底層初始化以及中斷配置。USB初始化完成后就使能了 USB中斷,響應函數為void USB_Istr(void),當與主機交互時便會進入中斷進行處理。
該中斷函數處理的中斷主要有三個
①正常中斷類型ISTR_CTR
這個中斷是處理USB的正常節(jié)點讀取、輸入輸出等。根據索引的節(jié)點編號進行不同的處理,當索引為0節(jié)點時(通常為控制節(jié)點),程序會調用In0_Process()改變USB控制狀態(tài),調用Setup0_Process()設置USB本地參數,調用Out0_Process()輸出結果。
當索引節(jié)點為其他時,調用(*pEpInt_OUT[EPindex-1])();進行相應節(jié)點的程序處理。
本程序中1節(jié)點為主機發(fā)送本機接收節(jié)點EP1_OUT_Callback,通過調用這個函數,可以把主機發(fā)送過來的數據通過函數USB_SIL_Read(EP1_OUT,USB_Receive_Buffer)提取出來放在USB_Receive_Buffer,長度等于或小于64個字節(jié)。這就是接收中斷。
2節(jié)點為主機接收節(jié)點EP1_IN_Callback,用于本地USB發(fā)送,本程序不采用中斷發(fā)送的方式,而采用查詢發(fā)送的方式,通過函數UserToPMABufferCopy(data,ENDP1_TXADDR, dataNum)發(fā)送到主機,封裝為USB_SendData.
通過這幾個過程,主機就可以對本機進行控制、發(fā)送以及接收數據了。
②復位請求中斷ISTR_RESET
當主機發(fā)來復位信號時,調用復位函數CustomHID_Reset對本機進行復位,對端點0、1、2的功能進行設置。
③掛起中斷ISTR_SUSP
進入掛起中斷時調用Suspend,然后關閉USB時鐘進入低功耗模式。
④喚醒中斷ISTR_WKUP
調用Resume,進行狀態(tài)恢復。
2.USB復位CustomHID_Reset
對本機進行復位,對端點0、1、2的功能進行設置。
3.請求數據相關參數CustomHID_Data_Setup、CustomHID_NoData_Setup
調用CustomHID_GetReportDescriptor, 加載CustomHID_GetConfigDescriptor對USB協(xié)議參數進行加載,用于Setup0_Process()設置過程。
4.CustomHID_GetDeviceDescriptor(設備描述符)
設備描述符主要獲得的參數包括USB設備最大包長度bMaxPacketSize40(一般固定為64個字節(jié))、協(xié)議類型bDeviceProtocol、生產商編號idVendor、產品編號idProduct以及設備編號bcdDevice。用于Setup0_Process()設置過程。
5.CustomHID_GetConfigDescriptor(配置描述符)
配置描述符主要包括的參數有對USB供電的配置MaxPower、節(jié)點數量bNumEndpoints、設備類型bInterfaceClass(HID)、接口類型nInterfaceProtocol(0=none,1=keyboard, 2=mouse)、輸入節(jié)點屬性、輸出節(jié)點屬性等。用于Setup0_Process()設置過程。
6.CustomHID_GetStringDescriptor(字符串描述)
ONE_DESCRIPTOR String_Descriptor[4] ={
{(uint8_t*)CustomHID_StringLangID, CUSTOMHID_SIZ_STRING_LANGID},
{(uint8_t*)CustomHID_StringVendor, CUSTOMHID_SIZ_STRING_VENDOR},
{(uint8_t*)CustomHID_StringProduct_AD, CUSTOMHID_SIZ_STRING_PRODUCT},
{(uint8_t*)CustomHID_StringSerial, CUSTOMHID_SIZ_STRING_SERIAL}
};
字符串描述符包括以下幾個部分:
1) CustomHID_StringLangID 設備描述符的語言識別碼 LangID = 0x0409: U.S.English
2) CustomHID_StringVendor 生產商名稱字符串
3) CustomHID_StringProduct 設備名稱字符串
4) CustomHID_StringSerial 設備編號字符串
用于Setup0_Process()設置過程。
歸納起來,可以簡單的說這樣總結,USB HID驅動用一個數據結構描述了USB的各個屬性,對USB初始化后,便可以進入中斷進行請求處理,0端點用于狀態(tài)控制以及參數設置(中斷方式),1端點用于主機發(fā)送本機接收(中斷方式),2節(jié)點用于本機發(fā)送主機接收(查詢模式)。