摘要:TMS320VC5509A是TI推出的新一代高性能、低功耗数字信号处理芯片,并扩充了当今流行的USB设备接口模块。本文介绍了嵌入式系统USB接口的特点和主要软件模块,分析了TMS320VC5509A USB接口模块的结构,给出了USB设备固件的设计和实现方案。该方案层次清晰,可移植性强,具有广泛的适用性。
关键词:USB;TMS320VC5509A;片上支持库CSL;固件协议栈
引言
DSP的优势是其出色的数据运算能力,但它的通信接口功能一般都较弱。随着嵌入式系统在各个领域的广泛应用,越来越多的应用不仅要求嵌入式处理器有足够的数据处理能力,还希望有简单、可靠的数据通信功能。USB是目前非常流行的通信接口,具有低功耗、即插即用、广泛的软硬件支持、价格低廉等优点。TI最新推出的新一代TMS320VC5509A DSP,整合了嵌入式系统的许多功能,具有高性能( 400MIPS@200MHz )、低功耗的特点,并在外设中集成了USB设备接口,具有广泛的适用性[4]。
1、嵌入式系统中的USB接口
USB作为计算机领域的新型接口技术,至今在嵌入式系统中的应用还处于起步阶段,远不如RS232等传统接口应用普及。这主要是因为USB的许多优点都是从使用者角度而言的,从开发者的角度来看,USB接口的协议复杂性增加了,为USB固件及PC驱动设计增加了难度。VC5509A 是一种带有USB设备控制器的数字信号处理器,使用VC5509A DSP,可以不用外扩USB控制器芯片,即可实现带USB通信功能的智能外设。
一般来说,一个完整的USB接口软件主要由四个部分组成:USB主机端设备驱动程序、USB主机端应用程序、USB设备端通信固件程序和USB设备端应用程序。
其中,应用程序根据各种不同的系统需求而不同。USB接口软件的主要难点在于USB设备端通信固件程序和主机端的设备驱动程序,这里主要介绍设备端固件的设计与实现。
2、VC5509A USB模块硬件结构分析
VC5509A的USB模块有16个端点(endpoint)。其中有两个控制端点,输入端点0和输出端点0;14个通用端点,输入端点1~7和输出端点1~7[3]。
USB接口的数据传输的方向可以分为Out传输(由主机到USB设备)和In传输(由USB设备到主机)[1]。In传输时,CPU或者USB DMA控制器将数据放在Buffer RAM中,进而数据通过UBM(USB Buffer Manager)到达SIE(串行接口引擎),由SIE负责将片内的并行数据转换成串行数据后通过USB接口输出。Out传输与之方向相反,原理和传输路径相同。图1所示为主机与DSP存储器之间通过USB接口进行数据传输的示意图。
图1. 主机与DSP存储器之间的数据传输
3、USB的固件设计与实现
使用VC5509A DSP芯片的USB接口,DSP系统对外部而言可以看作一个USB设备。USB设备作为一个完整的硬件设备,是由硬件和固件两部分组成的。固件包括有关系统的配置、模块初始化以及USB协议栈三部分。其中,系统配置是在芯片上电就完成的,与具体系统实现的功能密切相关。因此对于VC5509A来说,固件设计需要实现的主要功能可分为两部分:
1) USB设备的初始化与配置:告知主机设备的能力和特性,并为设备分配地址。
2) USB1.1的标准的协议的应答(即实现固件协议栈),并以批量(BULK)方式通过InEndpoint2与OutEndpoint2完成DSP与PC机的数据交换。
3.1 初始化配置
VC5509A的USB固件设计中,初始化配置是很重要的一环。对于55xx系列的DSP芯片,TI在其开发环境CCS中带有芯片支持库CSL(Chip support library),CSL以函数或者宏的形式提供一系列DSP硬件操作接口。使用CSL可以使USB模块驱动的编写变得方便快捷[2]。编写通信接口固件可以通过CSL对USB模块进行配置,具体步骤:
初始化应用函数接口向量指针,USB_setAPIVectorAddress()函数使得使用者可以通过函数调用表来访问芯片支持库CSL的USB应用函数API。
初始化USB时钟产生器以产生USB模块所需要的48MHz时钟。USB模块需要48MHz时钟驱动,CLKIN的时钟可以不等于48MHz,但必须通过USB时钟产生器产生48MHz时钟。可以通过USB_initPLL()函数来完成。该函数有三个参数,第一个是输入频率,第二个是输出频率,第三个是输入时钟分频数。
初始化函数USB_init()初始化USB模块。该函数有三个参数,第一个是USB设备号,第二个指向一个以NULL结束的初始化端点目标的句柄组成的数组,第三个是帧预起始定时器的计数值。
当USB模块初始化完成后,通过USB_devConnect函数,使USB模块与总线联接,发送和接收USB源数据。USB模块与主机的相连接,需要在DSP上运行相应的代码,以支持USB协议。如果没有USB协议处理代码,DSP将不能处理接受到的数据,导致DSP被主机挂起。USB协议处理代码将在3.2传输方式和3.3的固件程序框架中介绍。
USB模块配置与初始化代码如下:
CSL_init(); /*初始化片上支持库*/
USB_setAPIVectorAddress(); /*初始化应用函数接口向量指针*/
USB_disconnectDev(USB0); /*将USB模块与总线断开,保证配置正确进行*/
USB_initPLL(12,48,0); /*产生48MHz时钟*/
…… /*创建端点对象,并初始化端点对象*/
USB_EpHandle hEpObjArray[]= {&EndptObjOut0,&EndptObjIn0,……,NULL};
/*以NULL结束的初始化端点目标的句柄组成的数组*/
USB_init(USB0,hEpObjArray,0x80); /*初始化USB模块*/
USB_devConnect(USB0); /*将USB模块与总线联接*/
…… /*DSP进入枚举过程,进行设备请求命令的应答*/
3.2 传输方式的实现
USB总线上的信息包括差模数据线上的包以及一些有特殊意义的数据线上的信号,如设备唤醒、复位等等。根据USB总线传输的不同数据,USB定义了四种传输方式[1]:控制传输、中断传输、批量传输、同步传输。四种传输方式分别对应于不同的传输环境要求。
USB协议栈应该能够识别不同的数据,并用不同的传输类型并对它们进行相应的处理。
控制传输是最为复杂的传输类型,也是最重要的传输类型,是USB枚举阶段最主要的数据交换方式。主机一旦发现USB设备连接到总线上,就通过控制传输来交换信息:设置设备地址、读取设备描述符和选择配置。下面重点分析在VC5509A上实现控制传输的方法。中断传输、批量传输和同步传输较之控制传输要简单,可以在控制传输的基础上实现。
控制传输中的硬件操作接口可以通过片上支持库CSL中的两个的API函数实现:
接收Setup包函数USB_getSetupPACket()和传输函数USB_postTransaction()。前者可以由数据缓冲区中读取Setup包,后者通过端点发送和接收USB数据。当USB设备初次联接到总线上时,DSP通过USB_getSetupPacket()函数来交换信息、设备地址和读取设备的描述符。
USB_SetupStruct USB0_SetupPkt; /*定义承载Setup包的USB_SetupStruct型变量*/
void USB_Endpt0EventHandler(void) /*控制端点0的中断服务程序*/
{ if(USB_getEvents(EndptObjIn0) & USB_EVENT_SETUP) /*判断Setup事件发生*/
{ if(USB_getSetupPacket(USB0, USB0_SetupPkt) == USB_TRUE)
/*由数据缓冲区中读取Setup包并保存在变量USB0_SetupPkt中 */
{
/*―― 以下分析由主机传送过来的setup包,并作相应处理,完成总线枚举――*/
switch(USB0_SetupPkt.bRequest)
case GET_STATUS: //获取状态请求(2byte)
case CLEAR_FEATURE: //清除特性请求
case SET_FEATURE: //设置特性请求
case SET_ADDRESS: //设置地址请求
case GET_DESCRIPTOR: //获取描述符请求
case SET_DESCRIPTOR: //设置描述符请求
case GET_CONFIGURATION: //获取配置请求
case SET_CONFIGURATION: //设置配置请求
case GET_INTERFACE: //获取接口请求
case SET_INTERFACE: //设置接口请求
case SYNCH_FRAME: //同步帧请求
/*―――――――――――――END――――――――――――――― */
}
} return;
}
以上利用控制传输实现控制端点0的中断服务程序,完成USB标准请求命令。
3.3 设备固件协议栈
USB设备固件协议栈以设备端点的使用和管理作为基础和核心,而编写USB中断服务程序是整个设备端固件编写的主要内容。固件协议栈主要完成以下功能:
1) 设备上电复位,系统初始化,并使能中断。
2) 系统等待,直到将Setup包接收到端点0缓冲区为止。
3) 应答设备请求,完成设备枚举。
4) 等待USB中断,有中断发生则进入中断服务程序,完成系统要求。
本文关键字:暂无联系方式接口电路,单元电路 - 接口电路