CH372开发HID发卡器

现在市面上的发卡器一般都做成HID类型。类似USB鼠标,USB键盘。用户使用时不用安装驱动程序,方便用户使用。对开发者来说,windows操作系统提供了完善的库文件,可以直接操作HID设备。省去了开发驱动程序的步骤。

CH372的外围电路简单,只需一个晶振和几个电容。CH372有5个端点:

端点0是默认端点,控制传输时使用,支持上传和下传。上传和下传缓冲区各8字节。

端点1包括上传端点和下传端点。上传和下传缓冲区各8字节

端点2包括上传端点和下传端点,上传和下传缓冲区各64字节

CH372有内部固件模式和外部固件模式。使用内部固件模式时,CH372自动完成USB的枚举过程。编写程序简单,但是需要安装南京沁恒公司提供的驱动程序。开发HID设备不能选用内部固件模式。

使用外部固件模式时,程序的主要功能是通过CH372完成和主机的通讯,最复杂的部分就是枚举过程。完成了枚举过程,基本就大功告成了。

先来详细了解USB的通讯格式:

USB的通讯以包为基本单位。

包的种类:

令牌包:OUT,IN,SOF,SETUP

数据类:DATA0,DATA1,DATA2,MDATA

握手类:ACK,NCK,STALL,NYET

特殊类:PRE,ERR,SPLIT,PING

不能简单的通过包来进行数据传输,一个传输过程可能包括一个包,二个包,三个包。由不同的包组织而成传输事务。

一个传输事务通常由3个不同类型的包组成:令牌包,数据包,握手包。令牌包启动事务。数据包传输数据,握手包返回信息。方向有令牌包决定。

枚举的控制传输有三个过程:建立过程,数据过程,状态过程。每个过程就是一个传输事务,每个传输事务又包括几个包。下面有例子详细说明。

要注意的是,建立过程只能使用DATA0包,数据传输的第一个过程必须是DATA1包,每次传输正确后在DATA0,DATA1之间切换。而状态事务只能使用DATA1包。

每个包都是以同步域开始,接着是PID,最后以EOP结束。

同步域(sync sequence)值为00000001,根据NRZI编码,位值为0时信号要翻转一次,同步域的作用就是提供一组用来同步的时钟。

PID,8位,前4位代表封包类型,后4位是前4位反码。

PID类型 PID【3:0】

SOF 0101

SETUP 1101

OUT 0001

IN 1001

DATA0 0011

DATA1 1011

ACK 0010

NAK 1010

STALL 1110

PRE 1100

SOF封包框架

Sync + pid + 11位frame number + 5位CRC + EOP

IN封包

Sync + pid + 7bit设备地址 + 4bit端点地址 + 5bitCRC + EOP

执行IN封包动作时,首先PC送出一个IN封包,接着设备回传一个数据封包,最后PC送一个握手封包,表示已收到资料。

OUT封包

Sync + pid + 7bit设备地址 + 4bit端点地址 + 5bitCRC + EOP

SETUP封包

只在控制型传输的建立阶段使用

在形式上类似一个OUT动作,SETUP封包后跟一个DATA0封包和一个握手封包。SETUP包的目的是传送一个命令给设备执行。

Sync + pid + 7bit设备地址 + 4bit端点地址 + 5bitCRC + EOP

DATA封包跟在IN,OUT,SETUP封包后,IN封包后的DATA封包是将资料传给PC,OUT与SETUP封包后的DATA封包是把数据传给设备。传输数据时,DATA0封包和DATA1封包交互使用,作为一个同步机制。

DATA0 DATA1封包格式

Sync + PID + data0~datan(0~1024字节) + 16bitCRC + EOP

握手封包:

ACK封包:确认数据接收正确

NAK封包:告诉主机现在设备暂时无法接收或传回数据

STALL封包:无法完成传输,需要软件处理使设备能从STALL状态复原

握手封包格式

Sync + PID + EOP

下面详细介绍USB的枚举过程:

一、USB接上主机后,主机识别到有USB设备插入,先复位USB总线。然后发送请求描述符命令。此时主机使用默认地址0,默认端点0发送命令

1、主机发送SETUP包

sync

Pid(setup)

Addr

Endp

Crc5

eop

00000001

0xb4

0

0

0x08

 

主机发送数据包(请求设备描述符)

sync

Pid(DATA0)

DATA

Crc16

eop

00000001

0Xc3

80 06 00 01 00 00 40 00

0xbb29

 

设备发送握手包 ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

以上是一个控制传输的完整的建立事务过程。

2、主机发送IN令牌包

sync

Pid(IN)

Addr

Endp

Crc5

eop

00000001

0x96

0

0

0x08

 

设备发送一个DATA1包

sync

Pid(DATA1)

DATA

Crc16

eop

00000001

0XD2

12 01 00 02 00 00 00 08

0xeae7

 

主机发送ACK包

sync

Pid(ACK)

eop

00000001

0X4b

 

3、主机发送IN令牌包

sync

Pid(IN)

Addr

Endp

Crc5

eop

00000001

0x96

0

0

0x08

 

设备发送一个DATA0包 注意这里切换成了DATA0

sync

Pid(DATA0)

DATA

Crc16

eop

00000001

0Xc3

6d 04 18 c0 01 43 01 02

0x72ac

 

主机发送ACK包

sync

Pid(ACK)

eop

00000001

0X4b

 

4、主机发送IN令牌包

sync

Pid(IN)

Addr

Endp

Crc5

eop

00000001

0x96

0

0

0x08

 

设备发送一个DATA1包 注意这里切换成了DATA1

sync

Pid(DATA1)

DATA

Crc16

eop

00000001

0XD2

00 01

0xfcf1

 

主机发送ACK包

sync

Pid(ACK)

eop

00000001

0X4b

 

5、数据过程完成后,进入状态过程。主机发送OUT包

sync

Pid(OUT)

Addr

Endp

Crc5

eop

00000001

0x87

0

0

0x08

 

主机发送0字节状态数据包,表示已收到设备描述符

sync

Pid(DATA1)

DATA

Crc16

eop

00000001

0XD2

0x0000

 

设备发送握手包

sync

Pid(ACK)

eop

00000001

0X4b

 

注意,这里设备发送握手包不会产生端点0数据输出中断,因为此时没有数据。1是建立过程,2,3,4是数据过程,5是状态过程。第一次获取设备描述符主要是为了得到端点0可以发送数据的大小。

二、主机复位设备后,进入地址设置控制传输阶段。

1、主机发送SETUP包

sync

Pid(setup)

Addr

Endp

Crc5

eop

00000001

0xb4

0

0

0x08

 

主机发送DATA0包

sync

Pid(DATA0)

DATA

Crc16

eop

00000001

0Xc3

00 05 03 00 00 00 00 00

0x57e3

 

设备返回ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

2、主机发送IN包

sync

Pid(in)

Addr

Endp

Crc5

eop

00000001

0x96

0

0

0x08

 

设备发送一个字节为0的状态数据包

sync

Pid(DATA1)

DATA

Crc16

eop

00000001

0XD2

0x0000

 

主机发送ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

1是控制传输建立阶段,2是控制传输状态阶段,没有数据阶段,主机发送的DATA0包中的3就是分配给设备的地址

三、主机获取完整设备描述符,过程同一

四、主机获取配置描述符

1、主机发送SETUP包

sync

Pid(setup)

Addr

Endp

Crc5

eop

00000001

0xb4

3

0

0x0a

 

因为设置地址阶段为设备分配的地址是3,所以SETUP包的ADDR为3,端点地址在控制传输阶段一直为0

主机发送DATA0包

sync

Pid(DATA0)

DATA

Crc16

eop

00000001

0Xc3

80 06 00 02 00 00 09 00

0x57e3

 

设备返回ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

2、主机发送IN包

sync

Pid(in)

Addr

Endp

Crc5

eop

00000001

0x96

3

0

0x0a

 

设备发送DATA1包

sync

Pid(DATA1)

DATA

Crc16

eop

00000001

0XD2

09 02 22 00 01 01 00 a0

0x5019

 

主机返回ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

3、主机发送IN包

sync

Pid(in)

Addr

Endp

Crc5

eop

00000001

0x96

3

0

0x0a

 

设备返回配置描述符的最后一个字节,注意这里切换成了DATA0

sync

Pid(DATA0)

DATA

Crc16

eop

00000001

0XC3

32

0x8356

 

主机返回ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

4、主机发送OUT包

sync

Pid(OUT)

Addr

Endp

Crc5

eop

00000001

0x87

3

0

0x0a

 

主机发送0字节DATA1包

sync

Pid(DATA1)

DATA

Crc16

eop

00000001

0XD2

0x0000

 

设备返回ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

五,获取完整配置描述符,包括配置描述符,接口描述符,HID描述符,端点描述符

主机发送命令 80 06 00 02 00 00 22 00

22就是第4步读取的配置描述符里的数据,表示完整配置描述符的总字节数

设备返回

09 02 22 00 01 01 00 a0 32 配置描述符

09 04 00 00 01 03 01 02 00 接口描述符

09 21 11 01 00 01 22 34 00 HID描述符

07 05 81 03 05 00 0a 端点描述符

六、获取语言描述符

主机发送 80 06 00 03 00 00 FF 00

设备回应 04 03 09 04

04 09 表示语言类型为英语

七、获取字符串描述符

主机发送 80 06 02 03 09 04 ff 00

设备返回

24 03 55 00 53 00 42 00 20 00 4f 00 70 00 74 00 69 00 63 00 61 00 61 00 20 00 4d 00 6f 00 75 00 73 00 65 00

八,设置配置,使USB从ADDRESS状态进入CONFIGURED状态

1、 主机发送SETUP包

sync

Pid(setup)

Addr

Endp

Crc5

eop

00000001

0xb4

3

0

0x0a

 

主机发送DATA0包

sync

Pid(DATA0)

DATA

Crc16

eop

00000001

0Xc3

00 09 01 00 00 00 00 00

0xe4e4

 

设备返回ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

2、 主机发送IN包

sync

Pid(in)

Addr

Endp

Crc5

eop

00000001

0x96

3

0

0x0a

 

设备发送一个字节为0的状态数据包

sync

Pid(DATA1)

DATA

Crc16

eop

00000001

0XD2

0x0000

 

主机发送ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

配置值为01,就是配置描述符里bconfigurationvalue字段的值

九、HID设备的SET IDLE命令,设置闲置状态

1、主机发送SETUP 包

sync

Pid(setup)

Addr

Endp

Crc5

eop

00000001

0xb4

3

0

0x0a

 

主机发送DATA0包

sync

Pid(DATA0)

DATA

Crc16

eop

00000001

0Xc3

21 0a 00 00 00 00 00 00

0xe4e4

 

设备返回ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

3、 主机发送IN包

sync

Pid(in)

Addr

Endp

Crc5

eop

00000001

0x96

3

0

0x0a

 

设备发送一个字节为0的状态数据包

sync

Pid(DATA1)

DATA

Crc16

eop

00000001

0XD2

0x0000

 

主机发送ACK

sync

Pid(ACK)

eop

00000001

0X4b

 

十、获取HID报告描述符

主机发送81 06 00 22 00 00 68 00

设备返回定义的报告描述符

到这里主机和设备之间的枚举就完成了

十一、主机和设备之间传输数据

1、 主机发送IN包,读取设备的数据,使用的是端点描述符定义的端点1

sync

Pid(in)

Addr

Endp

Crc5

eop

00000001

0x96

3

1

0x07

 

设备忙,返回NAK

sync

Pid(ACK)

eop

00000001

0X5a

 

2、 主机再次发送IN包

sync

Pid(in)

Addr

Endp

Crc5

eop

00000001

0x96

3

1

0x07

 

设备返回DATA0

sync

Pid(DATA0)

DATA

Crc16

eop

00000001

0XC3

01 00 00 00

0x7fe4

 

主机返回ACK

sync

Pid(ACK)

eop

00000001

0X4b

 
© 版权声明
THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发