基于USB接口设备的固件程序设计
一、 引言
USB是应用在PC领域中的新型接口技术,它由三部分组成:具有USB接口的PC系统,能够支持USB的系统软件和使用USB接口的设备。它的提出是基于采用通用连接技术,实现外设的简单快速连接,达到方便用户、降低成本、扩展PC连接外设范围的目地。它的最显著优点是支持热插拔,当用户插入USB外设后,计算机能够自动识别接入的外设,而不需要重新启动系统。
二、USB设备硬件结构
为了提高系统的可扩展性,也便于选择高性能的单片机,以实现更多的功能,我们使用较为广泛的Philip公司的单纯的接口芯片PDIUSBD12。下面介绍USB设备硬件的相关情况。
1. PDIUSBD12芯片的内部结构
芯片内部集成SIE、320B的FIFO缓存、收发器以及电压调整电路和终结电阻器,提供2MB/s速率的并行接口,具有全自治本地DMA功能,芯片提供的多重中断模式有利于批量和等时数据传输模式。芯片还提供了可编程时钟、上电复位和低电压复位电路。
2. PDIUSBD12芯片的控制字
D12的控制字分为初始化命令、数据流命令和通用命令三种基本类型。在USB 设备列举过程中使用初始化命令,这些命令用来启动设备、设置地址、端点和工作模式。数据流命令用于管理USB 和单片机之间的数据流。很多数据流是通过一个发给单片机的中断请求开始的。控制器使用数据流命令来存取数据,确认在FIFO中的数据是否有效。通用命令主要在数据传输过程中使用,包括恢复和读取当前帧号。
3. PDIUSBD12 与单片机的连接
以PDIUSBD12和89C52单片机之间的连接如图所示,ALE接到单片机的ALE上,使用地址总线复用方式。A0通过电阻接VCC。VCC接+5V,VOUT3.3通过电容接地,同时脚20RESET_N和脚18DMACK_N接高电平。GND接地。8根数据线接至数据总线。脚11CS_N端接至控制器或译码器的相应端, PDIUSBD12可以通过CS_N端,映射为控制器的任何地址。脚14中断接至控制器的中断线,并用电阻拉高。XTAL1和XTAL2接6MHZ晶振,EOT_N拉高,D-、D+分别接到USB 总线的D-、D+上。在实际产品中,脚21GL_N可接LED显示设备状态。
三、USB设备固件的设计
固件的设计要求非常熟悉USB设备的具体通信步骤以及单片机的指令系统。
1. 固件介绍
PDIUSBD12是一种高速并行总线的USB接口设备,支持本地DMA传输.固件设计的目标是使D12在USB上能达到最快的传输率。外围设备如打印机等使用D12传送大量的数据。这些设备中的CPU忙于处理许多任务象设备控制,数据和图象处理。D12的固件设计成完全的中断驱动模式。当CPU在处理前台任务时,USB传输在后台被处理。这保证了最好的传输率和较好的软件结构,简化了编程和调试。
在后台中断服务程序和前台主程序之间的数据交换是通过标志和数据缓冲区来实现的。例如, D12主要的大量输出端点用一个圆形的数据缓冲区。当D12从USB接收到数据封包,就向CPU产生一个中断请求,CPU会马上执行中断服务程序。在中断服务程序内部,固件把数据封包从D12的内部缓冲区送到圆形缓冲区,然后清除PDIUSBD12的内部缓冲区使它能接收下一个新的数据包。CPU能继续执行当前前台的任务直到完成。然后它返回到主循环,检查圆形缓冲区是否有新的数据,开始另外一个前台任务。
使用这种结构,主函数不关心数据源是来自USB设备,串行口还是并行口。主函数只检查圆形缓冲区是否有新数据需要处理。因此,主函数将目标定为数据处理,而中断服务程序做的工作是以可能的最快速度传送数据。类似地,控制端点在数据封包处理上使用了同样的概念。中断服务程序在数据缓冲区里接收和存储控制传输内容并设置相应的标志寄存器。主函数将发送请求到协议处理程序。一旦所有的标准设备,类,和用户请求在协议处理程序处理了,中断服务程序就能保持它的效率。
2. 固件结构和任务
1) 固件结构
固件由6部分组成,它们如下: 主程序:发送USB设备请求,读测试键,控制发光二极管,处理USB总线事务,等等、标准请求、用户请求、中断服务程序、PDIUSBD12命令接口、硬件层。下面依次简略介绍:
硬件层:这是固件中最低的层,它完成向PDIUSBD12的硬件通道.当固件转向其他的CPU 平台,这部分需要修改或增加内容。
PDIUSBD12命令接口:为进一步简化用PDIUSBD12编程,固件定义了一系列命令接口,它们压缩了使用PDIUSBD12的所有功能。
中断服务程序:这部分代码处理由PDIUSBD12产生的中断。它接收从PDIUSBD12内部的FIFO区到CPU存储器的数据,并且建立合适的标志以通知主程序处理。
主程序:主程序检查事件的标志,转移到合适的子程序做进一步的处理。它也包含人机接口代码,例如,发光二极管和键盘扫描。
协议层:协议层处理标准USB设备请求,也处理具体的用户请求诸如DMA和TWAIN。
2) 固件任务
在编写固件程序的过程中,PDIUSBD12 作为接口芯片硬件为我们做了大量的工作,其中包括:
a.检测新的进入事务;翻译从USB 总线上获得的信息;b. 检测事务的目的地址,以决定是否响应;e. 确定事务的类型;d. 从USB 总线上接收数据到FIFO;e. 从FIFO 中发送数据到USB 总线上;f. 计算校验位,检测并报告结果。
但还有相当一部分的工作由固件程序来完成。这部分任务包括:
a.初始化PDIUSBD12并处理PDIUSBD12的中断;b.响应各种请求,至少要响应标准的11种请求;c.选择适当的数据写入PDIUSBD12的FIFO;d.从PDIUSBD12的FIFO中读取数据;
3) PDIUSBD12 的初始化
与一般的接口芯片一样,PDIUSBD12必须先初始化以后再使用,初始化的步骤如下:
a.用Set Address/Enable命令使能芯片功能,地址应设为0;b.用Set Endpoint Enable命令使能芯片上除端点0、1外的所有端点;c.用Set Mode 命令断开连接,延时1-2s;用Set Mode 命令连接;d. 用命令Read Interrupt Register清空中断寄存器;
初始化完后,D12就可以接收USB 总线上的信息了。之后,主机通过端点0、1来读取设备信息,配置设备、设置设备地址,完成设备列举。
4) USB 设备的列举
当有一个USB 设备连接到主机上时,主机的USB总线驱动、根集线器驱动获得设备连接的通知,开始列举设备。在主机一端,列举设备的过程是向设备发出一系列的标准请求。在设备一端,则需要响应主机发出的请求。其顺序如下:
a响应获取设备描述符的请求。务必保证设备描述符的正确发送;b.响应设置地址的请求,设备进入编址态;c.连续三次响应获取设备描述符请求;d.响应获取配置描述符的的请求,务必保证配置描述符的正确发送;e.发送全部的配置描述符,同时发送所有的接口描述符、端点描述符;
如果以上步骤都正确,则主机会提示找到新设备,安装驱动程序。否则,提示找到未知设备,设备不可用。
5) USB 设备固件框架的实现
从上面的讨论发现编写USB设备的固件实质上是处理各种主机提出的请求。其中,标准的11个请求是必须实现的,如果要求设备有其它的功能还必须加入自定义的请求。按照USB 2.0 中的定义,称这些固件程序为USB设备的框架。下面介绍USB设备框架的实现。
3. 主程序的结构
一旦加电,MCU就要初始化所有的端口,存储器,定时器和中断服务子程序。之后,MCU需要重新连接USB。这个程序很重要因为它保证了在MCU未准备好服务D12之前,D12不会动作。
在主循环程序里面,MCU会询问键盘上的任何动作。如果任何一个具体的键被按下,处理键的命令就会执行处理程序,之后返回主程序。这个程序仅是用来调试用。1ms定时是用来启动检查被按下键的子程序。
当询问到达检查Setup包时,它需要先确定setup标志是否建立。如果setup标志已经确立,它将发送设备请求到协议层进行处理。下面的流程图显示了主程序在前台执行的情况。
4. 中断服务程序的实现
PDIUSBD12固件是完全中断驱动的,因此中断服务程序是整个固件编写过程中非常重要的一环。在进入中断服务程序后首先要发用命令Read Interrupt Register(控制字为F4H)读取中断寄存器,根据中断寄存器的内容判断中断源,然后跳转到不同的服务程序中去处理中断。
中断服务程序(ISR)与主程序通信是通过事件标志“EPPFLAG”和数据缓冲区“CONTROL-XFER”。
PDIUSBD12固件是完全中断驱动的,因此中断服务程序是整个固件编写过程中非常重要的一环。在进入中断服务程序后首先要发用命令Read Interrupt Register(控制字为F4H)读取中断寄存器,根据中断寄存器的内容判断中断源,然后跳转到不同的服务程序中去处理中断。
中断服务程序(ISR)与主程序通信是通过事件标志“EPPFLAG”和数据缓冲区“CONTROL-XFER”。
主程序和中断服务程序(ISR)之间任务分配是,ISR从D12收集数据,主程序将处理这些数据。ISR只在它收集了足够的数据才通知主程序准备处理,这样会减少不必要的主程序服务时间,也简化了主程序。
总线重置和空闲在ISR里面不需要特殊的处理。ISR要么设置总线重置标志,要么在EPPFLAG里暂停这一位并退出。
控制型传输总是以setup阶段开始的,接着是数据阶段。然后以状态阶段结束。
下面以处理Control OUT和Control IN这两个最复杂最重要的中断子程序为例,说明编写中断服务程序的一些问题。
Control OUT主要是主机用来传递控制请求的,也可用于传输数据,进入服务程序后首先要发送控制字Read Last TransacTIon Status(40H)给PDIUSBD12,读取管道状态,根据读取的状态判断是因为有数据包还是有SETUP包的到来而中断。当SETUP包被USB设备的D12接收后,设备将会向MCU产生中断。微控制器将通过读取D12中断寄存器的内容判断封包是送到Control端点还是Genric端点而进行处理。如果封包是送到Control端点,MCU将会进一步通过读D12的“Read Last TransacTIon Status Register”判断数据是不是SETUP 封包。对于获取描述符设备请求,第一个封包必须是SETUP封包。
之后,MCU需要读出SETUP封包的内容通过选择Control Out端点来判断这个端点是满的还是空的。如果控制端点是满的,MCU就从缓冲区中读出它的内容并将它存在存储器里。然后,它将从存储器里去验证主机设备请求是否合法。如果是合法请求,MCU必须送“Acknowledge Setup command”到Control Out端点使能接收下一个封包。下一步,MCU需要确定控制传输是控制读还是控制写。这可以通过从SETUP 封包里读bmRequestType的8个字节来完成。控制传输是控制读,设备需要在下一个数据时相回送数据包给主机。MCU需要建立一个标志,表明USB设备现在正处于传送模式。应主机的要求准备送数据。
Control IN主要是用来向主机传送数据的,进入服务子程序后,首先要通过读Read Last TransacTIon Status(40H)来清除Control-In interrupt Bit,在确认D12是处于传送模式下后,MCU将数据包送往主机。但是,由于D12只有16字节的FIFO,所以MCU必须控制好传送的总量,如果要求的长度大于16字节的话。MCU必须检查当前和剩下的要送往主机的数据,如果剩下的字节大于16字节的话,MCU将先送头16字节。在下一个Control-IN令牌包到来的时候,MCU将先判断剩下的字节是否为0,如果是,MCU将发一个空包给主机,通知它数据已经传送完毕。
结束语:
功能强大的USB规格已经成为PC的众多标准之一,钻研计算机科技的种种发展,都离不开USB的相关知识。本文创新点:使用USB通信方面的具体协议,用单片机汇编语言编程,利用单片机的指令系统去实现USB设备与PC主机的具体通信,设计出适合用户需求的USB设备。