USB學習筆記(3)HID應用分析

2020-08-11 23:33:24

USB學習筆記(3)HID應用分析

本文根據前面對USB系統的瞭解,和USB協定的學習,列出滑鼠,鍵盤,多媒體控制器,自定義HID裝置等HID裝置的各種描述符。

前景提要:每個裝置有且僅有一個裝置描述符,至少要有一個設定描述符,在裝置描述符中規定了該裝置有多少中設定;設定描述符集合資訊包括:設定描述符>介面描述符>HID描述符(如果是HID類)>端點描述符,

1. Mouse(滑鼠)

① 描述符

一個裝置描述符,一個設定描述符,一個介面描述符,一個hid描述符,一個端點描述符,一個語言ID描述符,N個字串描述符,一個報告描述符

//裝置描述符
const u8 DeviceDescriptor[18] =
{
    0x12,   /*bLength *///該描述符長度
    0x01,   /*bDescriptorType*///描述符型別:0x01表示裝置描述符
    0x00,   /*bcdUSB *///USB協定版本 2.0
    0x02,
    0x00,   /*bDeviceClass*///裝置所使用的類程式碼,一般爲0
    0x00,   /*bDeviceSubClass*///裝置所使用的子類程式碼,類程式碼爲0,子類程式碼也爲0
    0x00,   /*bDeviceProtocol*///裝置所使用的協定
    0x40,   /*bMaxPacketSize*///端點0最大包長,0x40,64個位元組
    0x83,   /*idVendor (0x0483)*///VID 廠商ID,自定義
    0x04,
    0x50,   /*idProduct = 0x5750*///PID 產品ID,自定義
    0x57,
    0x00,   /*bcdDevice rel. 2.00*///產品版本號,自定義
    0x02,
    1,      /*Index of string descriptor describing manufacturer *///廠商字串描述符索引值,如果沒有則爲0                                             
    2,      /*Index of string descriptor describing product *///產品字串描述符索引值	                                             
    3,      /*Index of string descriptor describing the device serial number *///裝置序列號字串索引值
                                             
    0x01,   /*bNumConfigurations*///表示支援多少種設定
}

//設定描述符集合
const u8 ConfigDescriptor[9+9+9+7] =
{
	//設定描述符
    0x09,   /* bLength: Configuation Descriptor size *///描述符長度,9位元組
    0x02,   /* bDescriptorType: Configuration *///描述符型別:設定描述符爲0x02
    0x22,   /* wTotalLength: Bytes returned *///設定描述符集合總長度     
    0x00,
    0x01,   /* bNumInterfaces: 1 interface *///表示該設定所支援的介面數量
    0x01,   /* bConfigurationValue: Configuration value *///表示該設定集合的設定值,在設定設定請求中,主機會發送對應的設定值,表示設定了該設定
    0,      /* iConfiguration: Index of string descriptor describing the configuration*///設定字串索引                                  
    0xC0,   /* bmAttributes: Bus powered *//*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits *///描述裝置特性    
    0x32,   /* MaxPower 100 mA: this current is used for detecting Vbus *///裝置需要的最大電流

    //介面描述符
    0x09,   /* bLength: Interface Descriptor size *///描述符長度
    0x04,   /* bDescriptorType: Interface descriptor type *///描述符型別:0x03表示介面描述符
    0x00,   /* bInterfaceNumber: Number of Interface *///表示該介面的編號,從0開始遞增
    0x00,   /* bAlternateSetting: Alternate setting *///表示該介面的備用介面編號,從0開始遞增
    0x01,   /* bNumEndpoints *///該介面使用的非0端點的端點數
    0x03,   /* bInterfaceClass: HID *///該介面所使用的類
    0x01,   /* bInterfaceSubClass : 1=BOOT, 0=no boot *///該介面所使用的子類
    0x02,   /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse *///該介面所使用的協定
    0,      /* iInterface: Index of string descriptor *///介面描述符索引
    
	//HID描述符
    0x09,   /* bLength: HID Descriptor size *///描述符長度
    0x21,   /* bDescriptorType: HID *///描述符型別:0x21表示HID描述符
    0x10,   /* bcdHID: HID Class Spec release number *///HID協定版本號 1.1
    0x01,
    0x00,   /* bCountryCode: Hardware target country *///國家程式碼
    0x01,   /* bNumDescriptors: Number of HID class descriptors to follow *///下級描述符數量
    0x22,   /* bDescriptorType *///下級描述符型別:0x22表示報告描述符
    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor *///報告描述符長度
    0x00,
    
	//端點描述符
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x82,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點2輸入
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間
}; 

//語言ID描述符
const u8 StringLangID[4] =
{
    0x04,   /* bLength: LanguageID Descriptor size */
    0x03,   /* bDescriptorType: LanguageID */
    0x09,   /* 0x0409 表示美式英語 */
    0x04
}

//N個字串描述符


//報告描述符
const u8 ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
    0x05, 0x01,     /* USAGE_PAGE (Generic Desktop) *///全域性:用途頁:桌面應用
    0x09, 0x02,     /* USAGE (Mouse) *///區域性:用途:滑鼠
    0xa1, 0x01,     /* COLLECTION (Application) *///主條目:開集合:應用型
	
	0x09, 0x01,     /* USAGE (Pointer) *///區域性:用途:指針
	0xa1, 0x00,     /* COLLECTION (Physical) *///主條目:開集合:物理型

	0x05, 0x09,     /* USAGE_PAGE (Button) *///全域性:用途頁:按鍵
	0x19, 0x01,     /* USAGE_MIN (Button1) *///區域性:用途最小值:滑鼠左鍵
	0x29, 0x03,	    /* USAGE_MAX (Button3) *///區域性:用途最大值:滑鼠右鍵		
	0x15, 0x00,     /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,     /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x03,     /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,     /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,     /* INPUT(Data,Var,Abs) *///主條目:說明有三個長度爲1的數據域

	0x95, 0x01,     /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x05,     /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x03,     /* INPUT(Cnst,Var,Abs) *///主條目:說明有1個長度爲5的數據固定數據域,爲了和前面的3位補齊爲一個位元組
	
	0x05, 0x01,     /* USAGE_PAGE(Generic Desktop) *///全域性:用途頁:桌面應用
	0x09, 0x30,     /* USAGE(X) *///區域性:用途:X軸
	0x09, 0x31,     /* USAGE(Y) *///區域性:用途:Y軸
	0x09, 0x38,     /* USAGE(Wheel) *///區域性:用途:滾輪		
	0x15, 0x81,     /* LOGICAL_MIN (-127) *///全域性:返回邏輯最小值:-127
	0x25, 0x7f,     /* LOGICAL_MAX (127) *///全域性:返回邏輯最大值:127
	
	0x95, 0x03,     /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,     /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x06,     /* INPUT(Data,Var,Rel) *///主條目:說明有三個長度爲8的數據域

	0xc0,           /* END_COLLECTION *///主條目:關集合
    0xc0            /* END_COLLECTION *///主條目:關集合
};

② 報告的輸入

總共返回四個位元組的數據:buf[4]

buf[0]:【D0:左鍵是否按下】【D1:中鍵是否按下】【D2:右鍵是否按下】

buf[1]: X軸移動的位置,負值表示左移,正值表示右移

buf[2]: Y軸移動的位置,負值表示上移,正值表示下移

buf[3]: 滾輪滑動的位置,負值表示下滾,正值表示上滾

2. Keyboard(鍵盤)

① 描述符

一個裝置描述符,一個設定描述符,一個介面描述符,一個hid描述符,兩個端點描述符,一個語言ID描述符,N個字串描述符,一個報告描述符

//裝置描述符
const u8 DeviceDescriptor[18] =
{
    0x12,   /*bLength *///該描述符長度
    0x01,   /*bDescriptorType*///描述符型別:0x01表示裝置描述符
    0x00,   /*bcdUSB *///USB協定版本 2.0
    0x02,
    0x00,   /*bDeviceClass*///裝置所使用的類程式碼,一般爲0
    0x00,   /*bDeviceSubClass*///裝置所使用的子類程式碼,類程式碼爲0,子類程式碼也爲0
    0x00,   /*bDeviceProtocol*///裝置所使用的協定
    0x40,   /*bMaxPacketSize*///端點0最大包長,0x40,64個位元組
    0x83,   /*idVendor (0x0483)*///VID 廠商ID,自定義
    0x04,
    0x50,   /*idProduct = 0x5750*///PID 產品ID,自定義
    0x57,
    0x00,   /*bcdDevice rel. 2.00*///產品版本號,自定義
    0x02,
    1,      /*Index of string descriptor describing manufacturer *///廠商字串描述符索引值,如果沒有則爲0                                             
    2,      /*Index of string descriptor describing product *///產品字串描述符索引值	                                             
    3,      /*Index of string descriptor describing the device serial number *///裝置序列號字串索引值
                                             
    0x01,   /*bNumConfigurations*///表示支援多少種設定
}

//設定描述符集合
const u8 ConfigDescriptor[9+9+9+7+7] =
{
	//設定描述符
    0x09,   /* bLength: Configuation Descriptor size *///描述符長度,9位元組
    0x02,   /* bDescriptorType: Configuration *///描述符型別:設定描述符爲0x02
    0x29,   /* wTotalLength: Bytes returned *///設定描述符集合總長度     
    0x00,
    0x01,   /* bNumInterfaces: 1 interface *///表示該設定所支援的介面數量
    0x01,   /* bConfigurationValue: Configuration value *///表示該設定集合的設定值,在設定設定請求中,主機會發送對應的設定值,表示設定了該設定
    0,      /* iConfiguration: Index of string descriptor describing the configuration*///設定字串索引                                  
    0xC0,   /* bmAttributes: Bus powered *//*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits *///描述裝置特性    
    0x32,   /* MaxPower 100 mA: this current is used for detecting Vbus *///裝置需要的最大電流

    //介面描述符
    0x09,   /* bLength: Interface Descriptor size *///描述符長度
    0x04,   /* bDescriptorType: Interface descriptor type *///描述符型別:0x03表示介面描述符
    0x00,   /* bInterfaceNumber: Number of Interface *///表示該介面的編號,從0開始遞增
    0x00,   /* bAlternateSetting: Alternate setting *///表示該介面的備用介面編號,從0開始遞增
    0x02,   /* bNumEndpoints *///該介面使用的非0端點的端點數
    0x03,   /* bInterfaceClass: HID *///該介面所使用的類
    0x01,   /* bInterfaceSubClass : 1=BOOT, 0=no boot *///該介面所使用的子類
    0x01,   /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse *///該介面所使用的協定
    0,      /* iInterface: Index of string descriptor *///介面描述符索引
    
	//HID描述符
    0x09,   /* bLength: HID Descriptor size *///描述符長度
    0x21,   /* bDescriptorType: HID *///描述符型別:0x21表示HID描述符
    0x10,   /* bcdHID: HID Class Spec release number *///HID協定版本號 1.1
    0x01,
    0x00,   /* bCountryCode: Hardware target country *///國家程式碼
    0x01,   /* bNumDescriptors: Number of HID class descriptors to follow *///下級描述符數量
    0x22,   /* bDescriptorType *///下級描述符型別:0x22表示報告描述符
    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor *///報告描述符長度
    0x00,
    
	//端點描述符

	//第一個端點輸入
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x82,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點2輸入
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間

	//第二個端點輸出
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x01,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點1輸出
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間
}; 

//語言ID描述符
const u8 StringLangID[4] =
{
    0x04,   /* bLength: LanguageID Descriptor size */
    0x03,   /* bDescriptorType: LanguageID */
    0x09,   /* 0x0409 表示美式英語 */
    0x04
}

//N個字串描述符


//報告描述符
const u8 ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
    0x05, 0x01,         /* USAGE_PAGE (Generic Desktop) *///全域性:用途頁:桌面應用
    0x09, 0x06,         /* USAGE (Keyboard) *///區域性:用途:鍵盤
    0xa1, 0x01,         /* COLLECTION (Application) *///主條目:開集合:應用型

	//輸入報告
	0x05, 0x07,         /* USAGE_PAGE (Keyboard) *///全域性:用途頁:鍵盤
	0x19, 0xe0,         /* USAGE_MIN (Keyboard LeftControl) *///區域性:用途最小值:鍵盤左ctrl鍵
	0x29, 0xe7,         /* USAGE_MAX (Keyboard Right GUI) *///區域性:用途最大值:鍵盤右WIN鍵		
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,         /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x08,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,         /* INPUT(Data,Var,Abs) *///主條目:說明有八個長度爲1的數據域//總共8個特殊按鍵

	0x95, 0x01,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,	        /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x03,         /* INPUT(Cnst,Var,Abs) *///主條目:說明有1個長度爲8的數據固定數據域,保留
	
	0x05, 0x07,         /* USAGE_PAGE (Keyboard) *///全域性:用途頁:鍵盤
	0x19, 0x00,         /* USAGE_MIN (Reserved) *///區域性:用途最小值:0表示沒有按鍵按下
	0x29, 0x65,         /* USAGE_MAX (其他按鍵的鍵值) *///區域性:用途最大值:0x65		
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x26, 0x00,	0xFF,   /* LOGICAL_MAX *///全域性:返回邏輯最大值:255
	0x95, 0x06,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,	        /* REPORT_SIZE *///全域性:一個數據域的位長度
	0x81, 0x00,         /* INPUT(Data,Ary,Abs) *///主條目:說明有6個長度爲8的數據域(陣列)//總共顯示6個按鍵按下


	//輸出報告
	0x05, 0x08,         /* USAGE_PAGE (LED) *///全域性:用途頁:指示燈
	0x19, 0x01,         /* USAGE_MIN (Num Lock) *///區域性:用途最小值:數位鍵盤燈
	0x29, 0x05,         /* USAGE_MAX (Kana) *///區域性:用途最大值:Kana燈
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,         /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x05,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x91, 0x02,         /* OUTPUT(Data,Var,Abs) *///主條目

	0x95, 0x03,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x91, 0x03,         /* OUTPUT(Cnst,Var,Abs) *///主條目

    0xc0                /* END_COLLECTION *///主條目:關集合
};

② 報告的輸入

總共輸入8個位元組的數據:buf[8]

buf[0]: 8個特殊按鍵是否被按下,【D0~7】分別是左Ctrl,左Shift,左Alt,左WIN,右Ctrl,右Shift,右Alt,右WIN

buf[1]: 0x00,常數

buf[2:7]: 分別表示被按下的按鍵鍵值

③ 報告輸出

總共輸出1個位元組的數據:buf

buf:【D0~4】5個led的顯示,0關1開

3. 帶滑鼠功能的USB鍵盤(方法一)

① 描述符

只使用一個介面,但是使用兩個應用集合和兩個報告

//裝置描述符
const u8 DeviceDescriptor[18] =
{
    0x12,   /*bLength *///該描述符長度
    0x01,   /*bDescriptorType*///描述符型別:0x01表示裝置描述符
    0x00,   /*bcdUSB *///USB協定版本 2.0
    0x02,
    0x00,   /*bDeviceClass*///裝置所使用的類程式碼,一般爲0
    0x00,   /*bDeviceSubClass*///裝置所使用的子類程式碼,類程式碼爲0,子類程式碼也爲0
    0x00,   /*bDeviceProtocol*///裝置所使用的協定
    0x40,   /*bMaxPacketSize*///端點0最大包長,0x40,64個位元組
    0x83,   /*idVendor (0x0483)*///VID 廠商ID,自定義
    0x04,
    0x50,   /*idProduct = 0x5750*///PID 產品ID,自定義
    0x57,
    0x00,   /*bcdDevice rel. 2.00*///產品版本號,自定義
    0x02,
    1,      /*Index of string descriptor describing manufacturer *///廠商字串描述符索引值,如果沒有則爲0                                             
    2,      /*Index of string descriptor describing product *///產品字串描述符索引值	                                             
    3,      /*Index of string descriptor describing the device serial number *///裝置序列號字串索引值
                                             
    0x01,   /*bNumConfigurations*///表示支援多少種設定
}

//設定描述符集合
const u8 ConfigDescriptor[9+9+9+7+7] =
{
	//設定描述符
    0x09,   /* bLength: Configuation Descriptor size *///描述符長度,9位元組
    0x02,   /* bDescriptorType: Configuration *///描述符型別:設定描述符爲0x02
    41,	    /* wTotalLength: Bytes returned *///設定描述符集合總長度     
    0x00,
    0x01,   /* bNumInterfaces: 1 interface *///表示該設定所支援的介面數量
    0x01,   /* bConfigurationValue: Configuration value *///表示該設定集合的設定值,在設定設定請求中,主機會發送對應的設定值,表示設定了該設定
    0,      /* iConfiguration: Index of string descriptor describing the configuration*///設定字串索引                                  
    0xC0,   /* bmAttributes: Bus powered *//*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits *///描述裝置特性    
    0x32,   /* MaxPower 100 mA: this current is used for detecting Vbus *///裝置需要的最大電流

    //介面描述符
    0x09,   /* bLength: Interface Descriptor size *///描述符長度
    0x04,   /* bDescriptorType: Interface descriptor type *///描述符型別:0x03表示介面描述符
    0x00,   /* bInterfaceNumber: Number of Interface *///表示該介面的編號,從0開始遞增
    0x00,   /* bAlternateSetting: Alternate setting *///表示該介面的備用介面編號,從0開始遞增
    0x02,   /* bNumEndpoints *///該介面使用的非0端點的端點數
    0x03,   /* bInterfaceClass: HID *///該介面所使用的類
    0x01,   /* bInterfaceSubClass : 1=BOOT, 0=no boot *///該介面所使用的子類
    0x02,   /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse *///該介面所使用的協定
    0,      /* iInterface: Index of string descriptor *///介面描述符索引
    
	//HID描述符
    0x09,   /* bLength: HID Descriptor size *///描述符長度
    0x21,   /* bDescriptorType: HID *///描述符型別:0x21表示HID描述符
    0x10,   /* bcdHID: HID Class Spec release number *///HID協定版本號 1.1
    0x01,
    0x00,   /* bCountryCode: Hardware target country *///國家程式碼
    0x01,   /* bNumDescriptors: Number of HID class descriptors to follow *///下級描述符數量
    0x22,   /* bDescriptorType *///下級描述符型別:0x22表示報告描述符
    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor *///報告描述符長度
    0x00,
    
	//端點描述符
	//第一個端點輸入
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x82,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點2輸入
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間

	//第二個端點輸出
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x01,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點1輸出
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間
}; 

//語言ID描述符
const u8 StringLangID[4] =
{
    0x04,   /* bLength: LanguageID Descriptor size */
    0x03,   /* bDescriptorType: LanguageID */
    0x09,   /* 0x0409 表示美式英語 */
    0x04
}

//N個字串描述符


//報告描述符
const u8 ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
	//USB滑鼠部分
    0x05, 0x01,     /* USAGE_PAGE (Generic Desktop) *///全域性:用途頁:桌面應用
    0x09, 0x02,     /* USAGE (Mouse) *///區域性:用途:滑鼠
    0xa1, 0x01,     /* COLLECTION (Application) *///主條目:開集合:應用型
	
	0x85, 0x01,     /* Report ID(1) *///全域性,報告ID

	0x09, 0x01,     /* USAGE (Pointer) *///區域性:用途:指針
	0xa1, 0x00,     /* COLLECTION (Physical) *///主條目:開集合:物理型

	0x05, 0x09,     /* USAGE_PAGE (Button) *///全域性:用途頁:按鍵
	0x19, 0x01,     /* USAGE_MIN (Button1) *///區域性:用途最小值:滑鼠左鍵
	0x29, 0x03,	    /* USAGE_MAX (Button3) *///區域性:用途最大值:滑鼠右鍵		
	0x15, 0x00,	    /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,	    /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x03,	    /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,     /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,     /* INPUT(Data,Var,Abs) *///主條目:說明有三個長度爲1的數據域

	0x95, 0x01,     /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x05,     /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x03,     /* INPUT(Cnst,Var,Abs) *///主條目:說明有1個長度爲5的數據固定數據域,爲了和前面的3位補齊爲一個位元組
	
	0x05, 0x01,     /* USAGE_PAGE(Generic Desktop) *///全域性:用途頁:桌面應用
	0x09, 0x30,     /* USAGE(X) *///區域性:用途:X軸
	0x09, 0x31,     /* USAGE(Y) *///區域性:用途:Y軸
	0x09, 0x38,     /* USAGE(Wheel) *///區域性:用途:滾輪		
	0x15, 0x81,     /* LOGICAL_MIN (-127) *///全域性:返回邏輯最小值:-127
	0x25, 0x7f,     /* LOGICAL_MAX (127) *///全域性:返回邏輯最大值:127
	
	0x95, 0x03,     /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,	    /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x06,     /* INPUT(Data,Var,Rel) *///主條目:說明有三個長度爲8的數據域

	0xc0,           /* END_COLLECTION *///主條目:關集合
    0xc0            /* END_COLLECTION *///主條目:關集合


	//鍵盤部分
    0x05, 0x01,         /* USAGE_PAGE (Generic Desktop) *///全域性:用途頁:桌面應用
    0x09, 0x06,         /* USAGE (Keyboard) *///區域性:用途:鍵盤
    0xa1, 0x01,         /* COLLECTION (Application) *///主條目:開集合:應用型

	0x85, 0x02,	        /* Report ID(2) *///全域性,報告ID

	//輸入報告
	0x05, 0x07,         /* USAGE_PAGE (Keyboard) *///全域性:用途頁:鍵盤
	0x19, 0xe0,         /* USAGE_MIN (Keyboard LeftControl) *///區域性:用途最小值:鍵盤左ctrl鍵
	0x29, 0xe7,	        /* USAGE_MAX (Keyboard Right GUI) *///區域性:用途最大值:鍵盤右WIN鍵		
	0x15, 0x00,	        /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,	        /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x08,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,	        /* INPUT(Data,Var,Abs) *///主條目:說明有八個長度爲1的數據域//總共8個特殊按鍵

	0x95, 0x01,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,	        /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x03,         /* INPUT(Cnst,Var,Abs) *///主條目:說明有1個長度爲8的數據固定數據域,保留
	
	0x05, 0x07,         /* USAGE_PAGE (Keyboard) *///全域性:用途頁:鍵盤
	0x19, 0x00,         /* USAGE_MIN (Reserved) *///區域性:用途最小值:0表示沒有按鍵按下
	0x29, 0x65,         /* USAGE_MAX (其他按鍵的鍵值) *///區域性:用途最大值:0x65		
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x26, 0x00,	0xFF,   /* LOGICAL_MAX *///全域性:返回邏輯最大值:255
	0x95, 0x06,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,         /* REPORT_SIZE *///全域性:一個數據域的位長度
	0x81, 0x00,	        /* INPUT(Data,Ary,Abs) *///主條目:說明有6個長度爲8的數據域(陣列)//總共顯示6個按鍵按下


	//輸出報告
	0x05, 0x08,         /* USAGE_PAGE (LED) *///全域性:用途頁:指示燈
	0x19, 0x01,         /* USAGE_MIN (Num Lock) *///區域性:用途最小值:數位鍵盤燈
	0x29, 0x05,         /* USAGE_MAX (Kana) *///區域性:用途最大值:Kana燈
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,         /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x05,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x91, 0x02,         /* OUTPUT(Data,Var,Abs) *///主條目

	0x95, 0x03,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x91, 0x03,         /* OUTPUT(Cnst,Var,Abs) *///主條目

    0xc0                /* END_COLLECTION *///主條目:關集合
};

4. 帶滑鼠功能的USB鍵盤(方法二)

使用兩個介面,一個介面實現鍵盤功能,一個介面實現滑鼠功能

//裝置描述符
const u8 DeviceDescriptor[18] =
{
    0x12,   /*bLength *///該描述符長度
    0x01,   /*bDescriptorType*///描述符型別:0x01表示裝置描述符
    0x00,   /*bcdUSB *///USB協定版本 2.0
    0x02,
    0x00,   /*bDeviceClass*///裝置所使用的類程式碼,一般爲0
    0x00,   /*bDeviceSubClass*///裝置所使用的子類程式碼,類程式碼爲0,子類程式碼也爲0
    0x00,   /*bDeviceProtocol*///裝置所使用的協定
    0x40,   /*bMaxPacketSize*///端點0最大包長,0x40,64個位元組
    0x83,   /*idVendor (0x0483)*///VID 廠商ID,自定義
    0x04,
    0x50,   /*idProduct = 0x5750*///PID 產品ID,自定義
    0x57,
    0x00,   /*bcdDevice rel. 2.00*///產品版本號,自定義
    0x02,
    1,      /*Index of string descriptor describing manufacturer *///廠商字串描述符索引值,如果沒有則爲0                                             
    2,      /*Index of string descriptor describing product *///產品字串描述符索引值	                                             
    3,      /*Index of string descriptor describing the device serial number *///裝置序列號字串索引值
                                             
    0x01,   /*bNumConfigurations*///表示支援多少種設定
}

//設定描述符集合
const u8 ConfigDescriptor[9+9+9+7+9+9+7+7] =
{
	//設定描述符
    0x09,   /* bLength: Configuation Descriptor size *///描述符長度,9位元組
    0x02,   /* bDescriptorType: Configuration *///描述符型別:設定描述符爲0x02
    0x22,   /* wTotalLength: Bytes returned *///設定描述符集合總長度     
    0x00,
    0x02,   /* bNumInterfaces: 1 interface *///表示該設定所支援的介面數量
    0x01,   /* bConfigurationValue: Configuration value *///表示該設定集合的設定值,在設定設定請求中,主機會發送對應的設定值,表示設定了該設定
    0,      /* iConfiguration: Index of string descriptor describing the configuration*///設定字串索引                                  
    0xC0,   /* bmAttributes: Bus powered *//*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits *///描述裝置特性    
    0x32,   /* MaxPower 100 mA: this current is used for detecting Vbus *///裝置需要的最大電流

	//滑鼠部分第一個介面

    //介面描述符
    0x09,   /* bLength: Interface Descriptor size *///描述符長度
    0x04,   /* bDescriptorType: Interface descriptor type *///描述符型別:0x03表示介面描述符
    0x00,   /* bInterfaceNumber: Number of Interface *///表示該介面的編號,從0開始遞增
    0x00,   /* bAlternateSetting: Alternate setting *///表示該介面的備用介面編號,從0開始遞增
    0x01,   /* bNumEndpoints *///該介面使用的非0端點的端點數
    0x03,   /* bInterfaceClass: HID *///該介面所使用的類
    0x01,   /* bInterfaceSubClass : 1=BOOT, 0=no boot *///該介面所使用的子類
    0x02,   /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse *///該介面所使用的協定
    0,      /* iInterface: Index of string descriptor *///介面描述符索引
    
	//HID描述符
    0x09,   /* bLength: HID Descriptor size *///描述符長度
    0x21,   /* bDescriptorType: HID *///描述符型別:0x21表示HID描述符
    0x10,   /* bcdHID: HID Class Spec release number *///HID協定版本號 1.1
    0x01,
    0x00,   /* bCountryCode: Hardware target country *///國家程式碼
    0x01,   /* bNumDescriptors: Number of HID class descriptors to follow *///下級描述符數量
    0x22,   /* bDescriptorType *///下級描述符型別:0x22表示報告描述符
    MOUSE_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor *///報告描述符長度
    0x00,
    
	//端點描述符
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x83,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點3輸入
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間

	//鍵盤部分第二個介面

    //介面描述符
    0x09,   /* bLength: Interface Descriptor size *///描述符長度
    0x04,   /* bDescriptorType: Interface descriptor type *///描述符型別:0x03表示介面描述符
    0x00,   /* bInterfaceNumber: Number of Interface *///表示該介面的編號,從0開始遞增
    0x00,   /* bAlternateSetting: Alternate setting *///表示該介面的備用介面編號,從0開始遞增
    0x02,   /* bNumEndpoints *///該介面使用的非0端點的端點數
    0x03,   /* bInterfaceClass: HID *///該介面所使用的類
    0x01,   /* bInterfaceSubClass : 1=BOOT, 0=no boot *///該介面所使用的子類
    0x01,   /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse *///該介面所使用的協定
    0,      /* iInterface: Index of string descriptor *///介面描述符索引
    
	//HID描述符
    0x09,   /* bLength: HID Descriptor size *///描述符長度
    0x21,   /* bDescriptorType: HID *///描述符型別:0x21表示HID描述符
    0x10,   /* bcdHID: HID Class Spec release number *///HID協定版本號 1.1
    0x01,
    0x00,   /* bCountryCode: Hardware target country *///國家程式碼
    0x01,   /* bNumDescriptors: Number of HID class descriptors to follow *///下級描述符數量
    0x22,   /* bDescriptorType *///下級描述符型別:0x22表示報告描述符
    KEYBOARD_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor *///報告描述符長度
    0x00,
    
	//端點描述符
	//第一個端點輸入
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x82,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點2輸入
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間

	//第二個端點輸出
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x01,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點1輸出
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間
}; 

//語言ID描述符
const u8 StringLangID[4] =
{
    0x04,   /* bLength: LanguageID Descriptor size */
    0x03,   /* bDescriptorType: LanguageID */
    0x09,   /* 0x0409 表示美式英語 */
    0x04
}

//N個字串描述符


//報告描述符--滑鼠部分
const u8 MouseReportDescriptor[MOUSE_SIZ_REPORT_DESC] =
{
	//USB滑鼠部分
    0x05, 0x01,     /* USAGE_PAGE (Generic Desktop) *///全域性:用途頁:桌面應用
    0x09, 0x02,     /* USAGE (Mouse) *///區域性:用途:滑鼠
    0xa1, 0x01,     /* COLLECTION (Application) *///主條目:開集合:應用型
	
	0x85, 0x01,     /* Report ID(1) *///全域性,報告ID

	0x09, 0x01,     /* USAGE (Pointer) *///區域性:用途:指針
	0xa1, 0x00,     /* COLLECTION (Physical) *///主條目:開集合:物理型

	0x05, 0x09,     /* USAGE_PAGE (Button) *///全域性:用途頁:按鍵
	0x19, 0x01,     /* USAGE_MIN (Button1) *///區域性:用途最小值:滑鼠左鍵
	0x29, 0x03,     /* USAGE_MAX (Button3) *///區域性:用途最大值:滑鼠右鍵		
	0x15, 0x00,	    /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,     /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x03,     /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,     /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,     /* INPUT(Data,Var,Abs) *///主條目:說明有三個長度爲1的數據域

	0x95, 0x01,     /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x05,     /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x03,     /* INPUT(Cnst,Var,Abs) *///主條目:說明有1個長度爲5的數據固定數據域,爲了和前面的3位補齊爲一個位元組
	
	0x05, 0x01,     /* USAGE_PAGE(Generic Desktop) *///全域性:用途頁:桌面應用
	0x09, 0x30,     /* USAGE(X) *///區域性:用途:X軸
	0x09, 0x31,     /* USAGE(Y) *///區域性:用途:Y軸
	0x09, 0x38,     /* USAGE(Wheel) *///區域性:用途:滾輪		
	0x15, 0x81,     /* LOGICAL_MIN (-127) *///全域性:返回邏輯最小值:-127
	0x25, 0x7f,     /* LOGICAL_MAX (127) *///全域性:返回邏輯最大值:127
	
	0x95, 0x03,     /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,     /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x06,     /* INPUT(Data,Var,Rel) *///主條目:說明有三個長度爲8的數據域

	0xc0,           /* END_COLLECTION *///主條目:關集合
    0xc0            /* END_COLLECTION *///主條目:關集合
};

//報告描述符--鍵盤部分
const u8 KeyboardReportDescriptor[KEYBOARD_SIZ_REPORT_DESC] =
{
	//鍵盤部分
    0x05, 0x01,         /* USAGE_PAGE (Generic Desktop) *///全域性:用途頁:桌面應用
    0x09, 0x06,         /* USAGE (Keyboard) *///區域性:用途:鍵盤
    0xa1, 0x01,         /* COLLECTION (Application) *///主條目:開集合:應用型

	0x85, 0x02,         /* Report ID(2) *///全域性,報告ID

	//輸入報告
	0x05, 0x07,         /* USAGE_PAGE (Keyboard) *///全域性:用途頁:鍵盤
	0x19, 0xe0,         /* USAGE_MIN (Keyboard LeftControl) *///區域性:用途最小值:鍵盤左ctrl鍵
	0x29, 0xe7,         /* USAGE_MAX (Keyboard Right GUI) *///區域性:用途最大值:鍵盤右WIN鍵		
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,         /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x08,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,         /* INPUT(Data,Var,Abs) *///主條目:說明有八個長度爲1的數據域//總共8個特殊按鍵

	0x95, 0x01,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,         /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x03,     	/* INPUT(Cnst,Var,Abs) *///主條目:說明有1個長度爲8的數據固定數據域,保留
	
	0x05, 0x07,     	/* USAGE_PAGE (Keyboard) *///全域性:用途頁:鍵盤
	0x19, 0x00,     	/* USAGE_MIN (Reserved) *///區域性:用途最小值:0表示沒有按鍵按下
	0x29, 0x65,     	/* USAGE_MAX (其他按鍵的鍵值) *///區域性:用途最大值:0x65		
	0x15, 0x00,     	/* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x26, 0x00,	0xFF,   /* LOGICAL_MAX *///全域性:返回邏輯最大值:255
	0x95, 0x06,     	/* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,     	/* REPORT_SIZE *///全域性:一個數據域的位長度
	0x81, 0x00,     	/* INPUT(Data,Ary,Abs) *///主條目:說明有6個長度爲8的數據域(陣列)//總共顯示6個按鍵按下


	//輸出報告
	0x05, 0x08,     	/* USAGE_PAGE (LED) *///全域性:用途頁:指示燈
	0x19, 0x01,     	/* USAGE_MIN (Num Lock) *///區域性:用途最小值:數位鍵盤燈
	0x29, 0x05,     	/* USAGE_MAX (Kana) *///區域性:用途最大值:Kana燈
	0x15, 0x00,     	/* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,     	/* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x05,     	/* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,     	/* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x91, 0x02,     	/* OUTPUT(Data,Var,Abs) *///主條目

	0x95, 0x03,     	/* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,     	/* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x91, 0x03,     	/* OUTPUT(Cnst,Var,Abs) *///主條目

    0xc0     	     	/* END_COLLECTION *///主條目:關集合
};

5. 多媒體控制器

① 描述符

//裝置描述符
const u8 DeviceDescriptor[18] =
{
    0x12,   /*bLength *///該描述符長度
    0x01,   /*bDescriptorType*///描述符型別:0x01表示裝置描述符
    0x00,   /*bcdUSB *///USB協定版本 2.0
    0x02,
    0x00,   /*bDeviceClass*///裝置所使用的類程式碼,一般爲0
    0x00,   /*bDeviceSubClass*///裝置所使用的子類程式碼,類程式碼爲0,子類程式碼也爲0
    0x00,   /*bDeviceProtocol*///裝置所使用的協定
    0x40,   /*bMaxPacketSize*///端點0最大包長,0x40,64個位元組
    0x83,   /*idVendor (0x0483)*///VID 廠商ID,自定義
    0x04,
    0x50,   /*idProduct = 0x5750*///PID 產品ID,自定義
    0x57,
    0x00,   /*bcdDevice rel. 2.00*///產品版本號,自定義
    0x02,
    1,      /*Index of string descriptor describing manufacturer *///廠商字串描述符索引值,如果沒有則爲0                                             
    2,      /*Index of string descriptor describing product *///產品字串描述符索引值	                                             
    3,      /*Index of string descriptor describing the device serial number *///裝置序列號字串索引值
                                             
    0x01,   /*bNumConfigurations*///表示支援多少種設定
}

//設定描述符集合
const u8 ConfigDescriptor[9+9+9+7] =
{
	//設定描述符
    0x09,   /* bLength: Configuation Descriptor size *///描述符長度,9位元組
    0x02,   /* bDescriptorType: Configuration *///描述符型別:設定描述符爲0x02
    0x22,   /* wTotalLength: Bytes returned *///設定描述符集合總長度     
    0x00,
    0x01,   /* bNumInterfaces: 1 interface *///表示該設定所支援的介面數量
    0x01,   /* bConfigurationValue: Configuration value *///表示該設定集合的設定值,在設定設定請求中,主機會發送對應的設定值,表示設定了該設定
    0,      /* iConfiguration: Index of string descriptor describing the configuration*///設定字串索引                                  
    0xC0,   /* bmAttributes: Bus powered *//*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits *///描述裝置特性    
    0x32,   /* MaxPower 100 mA: this current is used for detecting Vbus *///裝置需要的最大電流

    //介面描述符
    0x09,   /* bLength: Interface Descriptor size *///描述符長度
    0x04,   /* bDescriptorType: Interface descriptor type *///描述符型別:0x03表示介面描述符
    0x00,   /* bInterfaceNumber: Number of Interface *///表示該介面的編號,從0開始遞增
    0x00,   /* bAlternateSetting: Alternate setting *///表示該介面的備用介面編號,從0開始遞增
    0x01,   /* bNumEndpoints *///該介面使用的非0端點的端點數
    0x03,   /* bInterfaceClass: HID *///該介面所使用的類
    0x00,   /* bInterfaceSubClass : 1=BOOT, 0=no boot *///該介面所使用的子類
    0x00,   /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse *///該介面所使用的協定
    0,      /* iInterface: Index of string descriptor *///介面描述符索引
    
	//HID描述符
    0x09,   /* bLength: HID Descriptor size *///描述符長度
    0x21,   /* bDescriptorType: HID *///描述符型別:0x21表示HID描述符
    0x10,   /* bcdHID: HID Class Spec release number *///HID協定版本號 1.1
    0x01,
    0x00,   /* bCountryCode: Hardware target country *///國家程式碼
    0x01,   /* bNumDescriptors: Number of HID class descriptors to follow *///下級描述符數量
    0x22,   /* bDescriptorType *///下級描述符型別:0x22表示報告描述符
    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor *///報告描述符長度
    0x00,
    
	//端點描述符
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x82,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點2輸入
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間
}; 

//語言ID描述符
const u8 StringLangID[4] =
{
    0x04,   /* bLength: LanguageID Descriptor size */
    0x03,   /* bDescriptorType: LanguageID */
    0x09,   /* 0x0409 表示美式英語 */
    0x04
}

//N個字串描述符


//報告描述符
const u8 ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
    0x05, 0x0c,         /* USAGE_PAGE (Consumer) *///全域性:用途頁:使用者
    0x09, 0x01,         /* USAGE (Consumer Control) *///區域性:用途:使用者控制
    0xa1, 0x01,         /* COLLECTION (Application) *///主條目:開集合:應用型
	
	0x09, 0xea,         /* USAGE (Volume Decrement) *///區域性:用途:音量減
	0x09, 0xe9,         /* USAGE (Volume Increment) *///區域性:用途:音量加
	0x09, 0xe2,         /* USAGE (Mute) *///區域性:用途:靜音
	0x09, 0xcd,         /* USAGE (Play/Pause) *///區域性:用途:播放暫停
	0x0a, 0x23, 0x02,   /* USAGE (AC Home) *///區域性:用途:開啓瀏覽器0x0223
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,         /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x05,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,         /* INPUT(Data,Var,Abs) *///主條目:說明有5個長度爲1的數據域

	0x05, 0x01,         /* USAGE_PAGE (Generic Desktop) *///全域性:用途頁:桌面
	0x09, 0x82,         /* USAGE(System Sleep)*///區域性:用途:系統待機
	0x09, 0x81,         /* USAGE(System Power down)*///區域性:用途:系統關機
	0x95, 0x02,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,         /* INPUT(Data,Var,Abs) *///主條目:說明有2個長度爲1的數據域

	0x95, 0x01,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x03,         /* INPUT(Cnst,Var,Abs) *///主條目:說明有1個長度爲1的常數

    0xc0                /* END_COLLECTION *///主條目:關集合
};

② 報告的輸入

總共輸入1個位元組的數據:buf

buf:【D0~6】分別是音量減,音量加,靜音,播放暫停,開啓瀏覽器,系統待機,系統關機,【D7】填充位,無意義

6. 自定義HID裝置

① 描述符

//裝置描述符
const u8 DeviceDescriptor[18] =
{
    0x12,   /*bLength *///該描述符長度
    0x01,   /*bDescriptorType*///描述符型別:0x01表示裝置描述符
    0x00,   /*bcdUSB *///USB協定版本 2.0
    0x02,
    0x00,   /*bDeviceClass*///裝置所使用的類程式碼,一般爲0
    0x00,   /*bDeviceSubClass*///裝置所使用的子類程式碼,類程式碼爲0,子類程式碼也爲0
    0x00,   /*bDeviceProtocol*///裝置所使用的協定
    0x40,   /*bMaxPacketSize*///端點0最大包長,0x40,64個位元組
    0x83,   /*idVendor (0x0483)*///VID 廠商ID,自定義
    0x04,
    0x50,   /*idProduct = 0x5750*///PID 產品ID,自定義
    0x57,
    0x00,   /*bcdDevice rel. 2.00*///產品版本號,自定義
    0x02,
    1,      /*Index of string descriptor describing manufacturer *///廠商字串描述符索引值,如果沒有則爲0                                             
    2,      /*Index of string descriptor describing product *///產品字串描述符索引值	                                             
    3,      /*Index of string descriptor describing the device serial number *///裝置序列號字串索引值
                                             
    0x01,   /*bNumConfigurations*///表示支援多少種設定
}

//設定描述符集合
const u8 ConfigDescriptor[9+9+9+7+7] =
{
	//設定描述符
    0x09,   /* bLength: Configuation Descriptor size *///描述符長度,9位元組
    0x02,   /* bDescriptorType: Configuration *///描述符型別:設定描述符爲0x02
    0x29,   /* wTotalLength: Bytes returned *///設定描述符集合總長度     
    0x00,
    0x01,   /* bNumInterfaces: 1 interface *///表示該設定所支援的介面數量
    0x01,   /* bConfigurationValue: Configuration value *///表示該設定集合的設定值,在設定設定請求中,主機會發送對應的設定值,表示設定了該設定
    0,      /* iConfiguration: Index of string descriptor describing the configuration*///設定字串索引                                  
    0xC0,   /* bmAttributes: Bus powered *//*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits *///描述裝置特性    
    0x32,   /* MaxPower 100 mA: this current is used for detecting Vbus *///裝置需要的最大電流

    //介面描述符
    0x09,   /* bLength: Interface Descriptor size *///描述符長度
    0x04,   /* bDescriptorType: Interface descriptor type *///描述符型別:0x03表示介面描述符
    0x00,   /* bInterfaceNumber: Number of Interface *///表示該介面的編號,從0開始遞增
    0x00,   /* bAlternateSetting: Alternate setting *///表示該介面的備用介面編號,從0開始遞增
    0x02,   /* bNumEndpoints *///該介面使用的非0端點的端點數
    0x03,   /* bInterfaceClass: HID *///該介面所使用的類
    0x00,   /* bInterfaceSubClass : 1=BOOT, 0=no boot *///該介面所使用的子類
    0x00,   /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse *///該介面所使用的協定
    0,      /* iInterface: Index of string descriptor *///介面描述符索引
    
	//HID描述符
    0x09,   /* bLength: HID Descriptor size *///描述符長度
    0x21,   /* bDescriptorType: HID *///描述符型別:0x21表示HID描述符
    0x10,   /* bcdHID: HID Class Spec release number *///HID協定版本號 1.1
    0x01,
    0x00,   /* bCountryCode: Hardware target country *///國家程式碼
    0x01,   /* bNumDescriptors: Number of HID class descriptors to follow *///下級描述符數量
    0x22,   /* bDescriptorType *///下級描述符型別:0x22表示報告描述符
    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor *///報告描述符長度
    0x00,
    
	//端點描述符

	//第一個端點輸入
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x82,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點2輸入
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間

	//第二個端點輸出
    0x07,   /* bLength: Endpoint Descriptor size *///該描述符長度
    0x05,   /* bDescriptorType: *///描述符型別:0x05表示端點描述符
    0x01,   /* bEndpointAddress: Endpoint Address (IN) *///該端點地址:方向+端點號,端點1輸出
    // bit 3...0 : the endpoint number
    // bit 6...4 : reserved
    // bit 7     : 0(OUT), 1(IN)
    0x03,   /* bmAttributes: Interrupt endpoint *///該端點屬性
    0x40,   /* wMaxPacketSize: 64 Bytes max *///該端點支援的最大包長度
    0x00,
    0x0A,   /* bInterval: Polling Interval (10 ms) *///端點查詢時間
}; 

//語言ID描述符
const u8 StringLangID[4] =
{
    0x04,   /* bLength: LanguageID Descriptor size */
    0x03,   /* bDescriptorType: LanguageID */
    0x09,   /* 0x0409 表示美式英語 */
    0x04
}

//N個字串描述符


//報告描述符
const u8 ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
    0x05, 0x01,         /* USAGE_PAGE (Generic Desktop) *///全域性:用途頁:桌面應用
    0x09, 0x06,         /* USAGE (Keyboard) *///區域性:用途:鍵盤
    0xa1, 0x01,         /* COLLECTION (Application) *///主條目:開集合:應用型

	//輸入報告
	0x05, 0x07,         /* USAGE_PAGE (Keyboard) *///全域性:用途頁:鍵盤
	0x19, 0xe0,         /* USAGE_MIN (Keyboard LeftControl) *///區域性:用途最小值:鍵盤左ctrl鍵
	0x29, 0xe7,         /* USAGE_MAX (Keyboard Right GUI) *///區域性:用途最大值:鍵盤右WIN鍵		
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,         /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x08,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x81, 0x02,         /* INPUT(Data,Var,Abs) *///主條目:說明有八個長度爲1的數據域//總共8個特殊按鍵

	0x95, 0x01,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,         /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x81, 0x03,         /* INPUT(Cnst,Var,Abs) *///主條目:說明有1個長度爲8的數據固定數據域,保留
	
	0x05, 0x07,         /* USAGE_PAGE (Keyboard) *///全域性:用途頁:鍵盤
	0x19, 0x00,         /* USAGE_MIN (Reserved) *///區域性:用途最小值:0表示沒有按鍵按下
	0x29, 0x65,         /* USAGE_MAX (其他按鍵的鍵值) *///區域性:用途最大值:0x65		
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x26, 0x00,	0xFF,   /* LOGICAL_MAX *///全域性:返回邏輯最大值:255
	0x95, 0x06,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x08,         /* REPORT_SIZE *///全域性:一個數據域的位長度
	0x81, 0x00,         /* INPUT(Data,Ary,Abs) *///主條目:說明有6個長度爲8的數據域(陣列)//總共顯示6個按鍵按下


	//輸出報告
	0x05, 0x08,         /* USAGE_PAGE (LED) *///全域性:用途頁:指示燈
	0x19, 0x01,         /* USAGE_MIN (Num Lock) *///區域性:用途最小值:數位鍵盤燈
	0x29, 0x05,         /* USAGE_MAX (Kana) *///區域性:用途最大值:Kana燈
	0x15, 0x00,         /* LOGICAL_MIN *///全域性:返回邏輯最小值:0
	0x25, 0x01,         /* LOGICAL_MAX *///全域性:返回邏輯最大值:1
	0x95, 0x05,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度	
	0x91, 0x02,         /* OUTPUT(Data,Var,Abs) *///主條目

	0x95, 0x03,         /* REPORT_COUNT *///全域性:數據域數量
	0x75, 0x01,         /* REPORT_SIZE *///全域性:一個數據域的位長度		
	0x91, 0x03,         /* OUTPUT(Cnst,Var,Abs) *///主條目

    0xc0                /* END_COLLECTION *///主條目:關集合
};

我的個人部落格網址:一個點的頻率 希望大家關注一下,謝謝!!!