Fork me on GitHub

USB协议详解第9讲(USB描述符-HID描述符)

1.HID设备概述

USB设备中有一大类就是HID设备,即Human Interface Devices,人机接口设备。这类设备包括鼠标、键盘、游戏手柄等,主要用于人与计算机进行交互。HID设备可以作为低速、 全速、高速设备用。由于HID设备要求用户输入能得到及时响应,故其传输方式通常采用中断传输

在USB协议中,HID设备的类型定义放置在接口描述符中,USB的设备描述符和配置描述符中不包含HID设备的信息。因此,对于某些特定的HID设备,可以定义多个接口,一个接口为HID设备类即可。。当USB一个设备为HID设备时,其设备描述符里面的bDeviceClass、bDeviceSubClass、bDeviceProtocol应为0,具体的定义在接口描述符中,接口描述符bInterfaceClass、bInterfaceSubClass、bInterfaceProtocol三个值如下:

bInterfaceClass 0x03:表示HID为设备
bInterfaceSubClass 0x00:对无需支持引导的HID设备;0x01:对支持引导的USB设备(鼠标、键盘);其他:保留。
InterfaceProtocol 当bInterfaceSubClass为0x00,此值无效
当bInterfaceSubClass为0x01
设置为0x01:键盘接口
设置为0x02:鼠标接口

注:说明下,支持引导就是在BIOS界面USB设备就可以使用了,比如我们的键盘和鼠标。

2.HID描述符组成

当一个USB设备被定义为HID设备的时候,设备必须实现HID描述符。首先要明确的一点是HID描述符不能单独返回给USB主机,主机会请求获得配置描述符集合,配置描述符集合主要由标准配置描述符、接口描述符、HID描述符、端点描述符,报告描述符和物理描述符是单独返回给USB主机。HID描述符组成如下:

3.STM32配置描述符集合代码(必须按顺序)

/* USB Configuration Descriptor */
const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
{
//
// 标准配置描述符
//	
    0x09, /* bLength: Configuation Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, 	/* bDescriptorType: Configuration */
    CUSTOMHID_SIZ_CONFIG_DESC,			/* wTotalLength low : Bytes returned */
    0x00,								/* wTotalLength high: Bytes returned */
    0x01,         /* bNumInterfaces: 1 interface */
    0x01,         /* bConfigurationValue: Configuration value */
    0x00,         /* 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 */
    0x96,         /* MaxPower 300 mA: this current is used for detecting Vbus */
    
//
// 接口描述符
//		
	/************** Descriptor of Custom HID interface ****************/
    /* 09 */
    0x09,         						/* bLength: Interface Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,		/* bDescriptorType: Interface descriptor type */
    0x00,         /* bInterfaceNumber: Number of Interface */
    0x00,         /* bAlternateSetting: Alternate setting */
    0x02,         /* bNumEndpoints 此接口有两个端点 */
    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描述符
//		
	/******************** Descriptor of Custom HID HID ********************/
    0x09,         			/* bLength: HID Descriptor size */
    HID_DESCRIPTOR_TYPE, 	/* bDescriptorType: HID */
    0x10,         			/* bcdHID: HID Class Spec release number */
    0x01,
    0x00,         /* bCountryCode: Hardware target country 国家代码 */
    
	0x01,         /* bNumDescriptors: Number of HID class descriptors to follow
					 类别描述符数目(至少有一个报表描述符)*/
    0x22,         /* bDescriptorType 报告描述符 */
    CUSTOMHID_SIZ_REPORT_DESC,	/* wItemLength: Total length of Report descriptor 报告描述符大小 */
    0x00,						/* 标志类别描述符说明结束 */ 
	
	
//
// 端点1描述符
//		
	/******************** Descriptor of Custom HID endpoints ******************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
 
    0x82,          /* bEndpointAddress: Endpoint Address (IN) */               
                   // 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,
    0x02,          /* bInterval: Polling Interval (2 ms) */
    /* 34 */
 
//
// 端点2描述符
//		
    0x07,	/* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,	/* bDescriptorType: */
			/*	Endpoint descriptor type */
    0x01,	/* bEndpointAddress: */
			/*	Endpoint Address (OUT) */
    0x03,	/* bmAttributes: Interrupt endpoint */
    0x40,	/* wMaxPacketSize: 64 Bytes max  */
    0x00,
    0x02,	/* bInterval: Polling Interval (2 ms) */
    /* 41 */
}; /* CustomHID_ConfigDescriptor */

4.HID描述符组成详解

1.bLength

描述符长度。HID描述符长度不是固定的,长度多少与描述符中包含的下级描述符个数相关。如果只有一个下级描述符,也就是不包括可选的部分,一共有9字节的长度,如果有多个下级描述符,按照长度往上加。

2.bDescriptorType

描述符类型,设置为0x21。

3.bcdHID

HID设备所遵循的HID版本号,为4位16进制的BCD码。1.0即0x0100,1.1即0x0101,2.0即0x0200。

4.bCountryCode

HID设备国家/地区代码,如下表格自行查询。

5.bNumDescriptor

HID设备支持的下级描述符的数量。在这里大家一定要注意,下一级描述符的类型有两种,报告描述符物理描述符,对于HID设备报告描述符和物理描述符可以有多个,但是至少有一个报告描述符,物理描述符是可选的,bNumDescriptor表示报告描述符和物理描述符的个数总和。由于HID设备至少需要包括一个报告描述符,故其值至小为0x01,一般的HID设备也为1,也就是有一个报告描述符,物理描述符很少用到。

6.bDescriptorTyep

下级描述符的类型,下级描述符第1个必须是报告描述符,所以这里存放报告描述符类型,如下表格,报告描述符的类型为0x22,其他描述符的类型可速查。

7.wDescriptorLength

下级描述符的长度,下级描述符第1个必须是报告描述符,所以这里存放报告描述符的长度,每种HID设备的报告描述符长度是不一样的,比如STM32某HID设备的报告描述符长度为43字节,代码如下,下一节详解报告描述符

//
// 报告描述符
//
const unsigned char ReportDesc[0x2b] =   // Report descriptor
	{
	0x05,0x01,		/* Usage Page (generic desktop) */
	0x09,0x06,		/* Usage (keyboard) */
	0xA1,0x01,		/* Collection */
	0x05,0x07,		/*   Usage Page 7 (keyboard/keypad) */
	0x19,0xE0,		/*   Usage Minimum = 224 */
	0x29,0xE7,		/*   Usage Maximum = 231 */
	0x15,0x00,		/*   Logical Minimum = 0 */
	0x25,0x01,		/*   Logical Maximum = 1 */
	0x75,0x01,		/*   Report Size = 1 */
	0x95,0x08,		/*   Report Count = 8 */
	0x81,0x02,		/*  Input(Data,Variable,Absolute) */
	0x95,0x01,		/*   Report Count = 1 */
	0x75,0x08,		/*   Report Size = 8 */
	0x81,0x01,		/*  Input(Constant) */
	0x19,0x00,		/*   Usage Minimum = 0 */
	0x29,0x65,		/*   Usage Maximum = 101 */
	0x15,0x00,		/*   Logical Minimum = 0 */
	0x25,0x65,		/*   Logical Maximum = 101 */
	0x75,0x08,		/*   Report Size = 8 */
	0x95,0x01,		/*   Report Count = 1 */
	0x81,0x00,		/*  Input(Data,Variable,Array) */
	0xC0};			/* End Collection */
#endif
posted @ 2024-08-13 22:30  yooooooo  阅读(188)  评论(0编辑  收藏  举报