USB HID

文章目录

目录

一、USB简介

二、USB(HID)协议及描述符

1.USB描述符简介

2.USB描述符

  

一、USB简介

USB根据速度可分为:

  1. 低速USB  Low Speed Device (LS)  
  2. 全速USB Full Speed Device (FS)  
  3. 高速USB设备 Hight Speed Device (HS)

具体应用以及特性如下:

USB HID_第1张图片

一般USB接口有4根线,分别是VCC DM DP GND。DM,DP是数据线。

USB的检测:

每一个主机USB的DM, DP都有内部15K下拉到GND,没有外设插入情况下是低电平。在USB从设备中,如果设备是高速USB则在DP上加有1.5K上拉到VCC,如果是低速设备则在DM上加1.5K上拉到VCC。当DP或者DM被拉高就可以检测USB插入,并且可以区分是高速还是低速USB。

二、USB(HID)协议及描述符

1.USB描述符简介

USB的硬件端口是统一的,但是USB设备却是多种多样的,USB主机根据USB设备的描述符来区分不同的USB设备。每一个USB设备都有自己的描述符,当插入USB设备之后,主机会向从机发送命令,从机收到命令之后,会返回特定的描述符信息。主机通过解析收到的描述符,来识别从机设备的相关信息,这个过程,就是设备枚举(enumeration)过程。

USB有5种标准设备描述符,分别是:设备描述符、配置描述符、字符串描述符、接口描述符、端点描述符。

另外还有:HID描述符、报告描述符等各个类特有的描述符。见下表:

USB HID_第2张图片

要注意的是,设备描述符有且只有一个。其包含关系如下图所示。

USB HID_第3张图片

2.USB描述符

         2.1 USB设备描述符

设备描述符有且仅有一个!

描述符使用到的宏定义如下:

#define USB_DEVICE_DESCRIPTOR_TYPE              0x01

#define USB_CONFIGURATION_DESCRIPTOR_TYPE       0x02

#define USB_STRING_DESCRIPTOR_TYPE              0x03

#define USB_INTERFACE_DESCRIPTOR_TYPE           0x04

#define USB_ENDPOINT_DESCRIPTOR_TYPE            0x05

#define HID_DESCRIPTOR_TYPE                     0x21


设备描述符类型定义固定为0x01

USB HID设备的设备描述符代码例子(STM32 USB HID)如下:

/* USB Standard Device Descriptor */
const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] =
 {
    0x12,                       /*bLength */
    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
    0x00,                       /*bcdUSB */
    0x02,
    0x00,                       /*bDeviceClass*/
    0x00,                       /*bDeviceSubClass*/
    0x00,                       /*bDeviceProtocol*/
    0x40,                       /*bMaxPacketSize40*/
    0x83,                       /*idVendor (0x0483)*/
    0x04,
    0x50,                       /*idProduct = 0x5750*/
    0x57,
    0x00,                       /*bcdDevice rel. 2.00*/
    0x02,
    1,                          /*Index of string descriptor describing
                                              manufacturer */
    2,                          /*Index of string descriptor describing
                                             product*/
    3,                          /*Index of string descriptor describing the
                                             device serial number */
    0x01                        /*bNumConfigurations*/
 }; /* CustomHID_DeviceDescriptor */

其结构成员意义如下:

USB HID_第4张图片

(1)bLength

描述符长度(18字节,十六进制为0x12),就是标志描述符数据结构的长度。

(2)bDescriptorType

bDescriptorType代表了本描述符的类型,设备描述符为0x01 (设备描述符固定为0x01)

(3)bcdUSB

    USB协议版本,表示形式0xJJMN版本JJ.M.N(JJ  - 主要版本号,M  - 次要版本号,N  - 次要版本)

    例子:如果是USB2.0,写成:0200H;如果是USB1.1,写成:0110H 如果是USB3.11,写成:0311H

(4)bDeviceClass、bDeviceSubClass、bDeviceProtocol

    bDeviceClass、bDeviceSubClass、bDeviceProtocol分别代表设备类型,子类型,设备使用的协议,USB-IF区分设备类分了三个等级(类-子类-协议码)其中,类包含人机交互类、图像类、无线类、音频类等等,子类比如音频类的音频控制、音频流等等,协议比如人机接口类中的鼠标、键盘、触摸屏等,为何会有这么多USB的Class分类,子分类,设备协议。我们要知道,USB协议设计的目的,就是为实现通用,用单一的USB接口取代之前种类繁多的各种其他接口。而为了取代其他各种接口,那意味着就要实现各种设备所对应的各种功能。如下图显示USB设备的各种类别,USB设备类信息更详细内容可进入https://www.usb.org/defined-class-codes查看。

(5)bMaxPackeSize0

就是端点一次最大传多少个字节。USB协议里有规定,端点0最低8字节,端点的最大传输大小和USB速度等级以及传输类型有关,控制传输一般使用端点0,低速最大8字节,全速和高速最大传输64字节,如下图:

USB HID_第5张图片

(6)idVender

    厂商ID,就是个2字节的编号,由USB协议分配,厂商申请时需要交费。自己随便写的话,仅限于学习、测试的情况下,不能用做产品。

(7)idProduct

    产品ID,厂家自己随便定义。

(8)bcdDevice

    产品版本号,厂家自己随便定义。

(9)iManufacturer

    描述厂商的字符串的索引,为0则表示没有。

(10)iProduct

    描述产品的字符串的索引,为0则表示没有。

(11)iSerialNumber

    产品序列号字符串的索引,为0则表示没有。

(12)bNumConfigurations

指示设备由多少个配置,前面提到过,一个USB可能有多个配置,一般USB产品都是1个配置。

        2.2 配置描述符

配置描述符至少有一个,可以有多个,一般一个设备只设置一个配置描述符。

配置描述符类型定义固定为0x02

USB HID设备的配置描述符代码例子(STM32 USB HID)如下:(注意其中除了配置描述符还包括其他如接口描述符和端点描述符)

/* USB Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
{
    0x09, /* bLength: Configuration Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    CUSTOMHID_SIZ_CONFIG_DESC,/* wTotalLength: Bytes returned */
    0x00,
    0x01,         /* bNumInterfaces: 1 interface */
    0x01,         /* bConfigurationValue: Configuration value */
    0x00,         /* iConfiguration: Index of string descriptor describing
                                 the configuration*/
    0xC0,         /* bmAttributes: Self powered */
    0x32,         /* MaxPower 100 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 */
    /******************** Descriptor of Custom HID HID ********************/
    /* 18 */
    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,
    /******************** Descriptor of Custom HID endpoints ******************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
    0x81,          /* bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x02,          /* wMaxPacketSize: 2 Bytes max */
    0x00,
    0x20,          /* bInterval: Polling Interval (32 ms) */
    /* 34 */
    	
    0x07,	/* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,	/* bDescriptorType: */
			/*	Endpoint descriptor type */
    0x01,	/* bEndpointAddress: */
			/*	Endpoint Address (OUT) */
    0x03,	/* bmAttributes: Interrupt endpoint */
    0x02,	/* wMaxPacketSize: 2 Bytes max  */
    0x00,
    0x20,	/* bInterval: Polling Interval (20 ms) */
    /* 41 */
  }; /* CustomHID_ConfigDescriptor */

其中配置描述符代码段:

    0x09, /* bLength: Configuration Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    CUSTOMHID_SIZ_CONFIG_DESC,/* wTotalLength: Bytes returned */
    0x00,
    0x01,         /* bNumInterfaces: 1 interface */
    0x01,         /* bConfigurationValue: Configuration value */
    0x00,         /* iConfiguration: Index of string descriptor describing
                                 the configuration*/
    0xC0,         /* bmAttributes: Self powered */
    0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */

配置描述符的各个域的意义如下:

USB HID_第6张图片

bLength:大小为1字节,表示该描述符的长度。标准的USB配置描述符的长度为9字节。

bDescriptorType:配置描述符的类型。

wTotalLength:表示整个配置描述符集合的总长度,包括配置描述符、接口描述符、端点描述符和类特殊描述符(HID类)。注意低字节在前。

bNumInterfaces:该配置描述符所支持的接口数量(接口编号数量而不是接口描述符数量,不同的接口描述符可能使用同一个编号接口)。功能单一设备只有一个,而复合设备则具有多个接口。

bConfigurationValue:表示该配置的值。通常一个USB设备可以支持多个配置,bConfigurationValue就是每个配置的标识。

iConfiguration:描述该配置的字符串的索引值。如果该值为0,则表示没有字符串。

bmAttributes:用来描设备的一些特性。其中,D7是保留的,必须要设置为1。D6表示供电方式,D6=1时,表示设备自供电;D6=0时,表示设备时总线供电。D5表示是否支持远程唤醒,D5=1时,支持远程唤醒。D4~D0保留,设置为0

bMaxPower:表示设备需要从总线获取的最大电流量,单位为2mA。如需要200mA的最大电流,则该字节的值为100

        2.3 接口描述符

如上面代码中

 /************** 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的接口描述符。

USB HID_第7张图片


USB_INTERFACE_DESCRIPTOR_TYPE为固定值表示该配置是接口描述符。

bNumEndpoints,该接口使用的端点个数。注意一点,这个端点个数不包括0端点。

bInterfaceClass的定义如下表:

USB HID_第8张图片

bInterfaceSubClass 除带有由接口定义的类的设备外,此字段于设备描述符中的bDeviceSubClass 相同。若 bInterfaceClass 等于00h,bInterfaceSubClass 也必须等于 00h。若 bInterfaceClass 取从 01h到FEh的值,bInterfaceSubClass则等于00h或等于一个为接口的类定义的值。FFh表明为厂商定义的子类。

    bInterfaceProtocol 除了带有接口定义的类的设备外,此字段于设备描述符中的bDeviceProtocol相同。此字段可为所选bInterfaceClass和bInterfaceSubClass 所规定的协议。若bInterfaceClass取从01h到FEh的值,bInterfaceProtocol必须等于00h,或等于为接口的类定义的值。FFh表明为厂商定义的协议。

    iInterface 是指向描述接口的字符串的索引。若没有字符串描述符,该值为0.

        2.4HID描述符

上面在接口描述符中定义了设备类型为0x03的HID设备,那么需要定义HID描述符,上面代码中HID描述符代码如下:

    /* 18 */
    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,

bcdHID为0x0110,表面该HID协议为1.1版本

bCountryCode: 设备所适用的国家。如果使用的键盘是美式键盘,代码为33,即0x21

bNumDescriptors:下级描述符的数量。这个值至少为1,也就是HID类设备至少要有一个报告描述符。下级描述符可以是报告描述符或者物理描述符。

wItemLength: 报告描述符的总长度。

  2.5 端点描述符

上面HID的端点描述符代码:

    /******************** Descriptor of Custom HID endpoints ******************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

    0x81,          /* bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x02,          /* wMaxPacketSize: 2 Bytes max */
    0x00,
0x20,          /* bInterval: Polling Interval (32 ms) */

bEndpointAddress: bit7 :方向  1/0 :in/out,对于控制端点可以忽略;bit4~bit6 保留,bit3~bit0:端点号 

bmAttributes,属性。如下

bit1~bit0:

00 = Control-控制传输

01 = Isochronous-等时传输

10 = Bulk-批量传输

11 = Interrupt-中断传输

如果不是一个等时传输端点,第5~2位是保留的,必须设置为0。如果它是等时的,则定义如下:

Bits 3..2: Synchronization Type-同步类型

00 = No Synchronization-无同步

01 = Asynchronous-异步

10 = Adaptive-适配

11 = Synchronous-同步

/*Bits 5..4: Usage Type-用途*/

00 = Data endpoint-数据端点

01 = Feedback endpoint-反馈端点

10 = Implicit feedback Data endpoint-暗含反馈的数据端点

11 = Reserved-保留

wMaxPackeSize,端点支持的最大包长。对于等时端点,此值用于在调度中保留总线时间,这是每(微)帧数据有效负载所需的时间。在进行中,管道实际使用的带宽可能比保留的带宽少。如果有必要,设备会报告通过其正常的、非usb定义的机制所使用的实际带宽。

对于所有的端点,bit10~bit0指定最大数据包大小(以字节为单位)。

/*5.对于高速同步和中断端点:bit12~bit11指定每个微帧的额外通信次数:

00 = None (1 transaction per microframe)

01 = 1 additional (2 per microframe)

10 = 2 additional (3 per microframe)

11 = Reserved

bInterval,查询时间,说白了就是主机多久和设备通讯一次。根据设备运行速度以帧或微帧表示。

对于全/高速等时端点,此值必须在1到16之间。bInterval值用作2的指数;例如,bInterval为4,表示周期为8, 2(4 – 1)。

对于全速/低速中断端点,该字段的值可以是1到255。

对于高速中断端点,使用bInterval值作为2的指数;例如,bInterval为4表示周期为8 ,2(4-1)。这个值必须在1到16之间。

对于高速批量/控制输出端点,bInterval必须指定端点的最大NAK速率。值0表示端点永不NAK。其它值表示每个微帧的bInterval数最多1个NAK。这个值的范围必须在0到255之间。

2.6 报告描述符

报告描述符包含多个报告,不同的报告通过报告ID来识别,报告的第一个字节就是报告ID。当报告描述符中没有定义报告ID时,开始就是数据。

报告描述符由条目(item)来组成,一个条目占据一行。HID协议规定了两种条目:短条目和长条目,常用的是短条目。

短条目的构成:一字节的前缀 + 可选的数据字节。可选的数据字节可以是0、1、2、4字节。实际中所使用的条目,大部分是1字节的可选数据

一个条目前缀如下

bSize:bit1~bit0后面紧跟的字节数

你可能感兴趣的:(USB,嵌入式硬件)