基于USB2.0总线的高速数据采集系统设计_接口电路论文
摘要:本文主要介绍支持usb2.0高速传输的ez-usb fx2单片机cy7c68013,并详细说明用此芯片实现高速数据采集系统和相应的windows驱动程序及底层固件程序的开发过程。
关键词:cy7c68013 usb2.0 数据采集 固件
1 引言
现代工业生产和研究对数据采集的要求日益提高,在瞬态信号测量、图像处理等一些高速、高精度的测量中,需要进行高速数据采集。现在通用的高速数据采集卡一般多是pci卡或isa卡,存在以下缺点:安装麻烦、价格昂贵;受计算机插槽数量、地址、中断资源限制,可扩展性差;在一些电磁干扰性强的测试现场,无法专门对其做电磁屏蔽,导致采集的数据失真。
通用串行总线usb是1995年康柏、微软、ibm、dec等公司为解决传统总线不足而推广的一种新型的通信标准。该总线接口具有安装方便、高带宽、易于扩展等优点,已逐渐成为现代数据传输的发展趋势。基于usb的高速数据采集卡充分利用usb总线的上述优点,有效解决了传统高速数据采集卡的缺陷。
2 硬件设计
2.1支持usb2.0高速传输的cy7c68013
cypress semiconductor公司的ez-usb fx2是世界上第一款集成usb2.0的微处理器,它集成了usb2.0收发器、sie(串行接口引擎)、增强的8051微控制器和可编程的外围接口。fx2这种独创性结构可使数据传输率达到56mbytes/s,即usb2.0允许的最大带宽。在fx2中,智能sie可以硬件处理许多usb1.1和usb2.0协议,从而减少了开发时间和确保了usb的兼容性。gpif(general programmable interface)和主/从端点fifo(8位或16位数据总线)为ata、utopia、epp、pcmcia和dsp等提供了简单和无缝连接接口。
cy7c68013的gpif引擎具有自动传输数据结构的特性,这种特性使得外围设备和主机通过cy7c68013可以无缝的、高速的传输数据。为了实现高速的数据传输,cy7c68013cpu不会直接参与数据的传输,而是直接利用gpif的自动传输数据模式。图1和图2说明了主机in和out数据传输过程。
2.1.1 端点缓冲区
fx2包含3个64字节端点缓冲区和4k可配置成不同方式的缓冲,其中3个64字节的缓冲区为ep0、ep1in和ep1out。ep0作为控制端点用,它是一个双向端点,既可为in也可为out。当需要控制传输数据时,fx2固件读写ep0缓冲区,但是8个setup字节数据不会出现在这64字节ep0端点缓冲区中。ep1in和ep1out使用独立的64字节缓冲区,fx2固件可配置这些端点为bulk、interrupt或isochronous传输方式,这两个端点和ep0一样只能被固件访问。这一点与大端点缓冲区ep2、ep4、ep6和ep8不同,这四个端点缓冲区主要用来和片上或片外进行高带宽数据传输而无需固件的参与。ep2、ep4、ep6和ep8是高带宽、大缓冲区。它们可被配置成不同的方式来适应带宽的需求。
2.1.2 接口信号
在利用gpif进行高速数据传输系统设计时,gpif waveforms的编辑是非常重要的,它控制着整个数据传输过程的读写时序。此时cpu的作用已经非常小了,它只起着下载代码到内部ram以及在固件中如何触发gpif waveforms的作用。fx2专门为gpif提供了外围接口信号,如8位或16位的数据线、控制信号、ready信号以及地址线。
ifclk(双向时钟信号):ifclk是一个参考时钟,可以配置成输入或输出。当配置为输出时,ifclk被fx2驱动为30mhz或48mhz;当配置为输入时,时钟范围为5-48mhz。
gpifadr[8:0](输出):gpif使用gpifadr信号为外部设备提供地址线,在总线上地址值是自增的。
fd[15:0](双向):这是usb主机通过fx2和外部设备进行数据传输的数据线,它可配置成8位或16位。当16位时,fd[7:0]代表端点fifo中的第一个字节,fd[15:8]代表第二个字节。
ctl[5:0](输出):fx2为外部设备提供了几个控制信号,如读写选通、使能等。
rdy[5:0](输入):fx2提供了几个状态检测信号,它可以检测外部设备的状态,如fifo的空、满、半满等。
gstate[2:0](输出):这是调试信号,表示gpif波形执行的状态,通常连接到逻辑分析仪上。
2.2 ad9238
ad9238是一个双通道的12位a/d转换器,采用单3v供电,速度可以是20msps、40msps和65msps;低功耗,工作在20msps时,功耗为180mw,40msps时,功耗为330mw,65msps时,功耗为600mw;具有500mhz 3db带宽的差分输入;片上参考源及sha;灵活的模拟输入范围:1vp-p~2vp-p;适用于:超声波设备,射频通讯,电池电源仪器,低价示波器等。本系统采用20msps的ad9238,可充分发挥usb在高速传输模式下的数据传输优势。
2.3 数据采集系统
该数据采集系统整个框图如图3所示,该系统由以下几部份组成:usb控制器、fifo、cpld、ad9238以及数据采集前端电路。
图3 数据采集系统框图
cpld主要是控制时序,时钟分频等。fifo主要是起着高速数据缓冲作用,当fifo半满时,数据开始向usb主机发送。我们采用的是同步fifo,时钟信号接ifclk,当fifo的/rd信号和/oe信号有效时,每个ifclk上升沿就输出一个数据;当fifo的/wr信号有效时,ifclk上升沿就读进一个数据。ad9238的20mhz时钟信号是通过cpld分频所得。当程序使能ad9238的/oeb_a和/oeb_b信号时,ad9238双通道开始进行数据采集并向fifo写数据。
系统前端的调理电路采用的是ad公司的ad8138,该放大器具有较宽的模拟带宽(320mhz,-3db,增益1),而且可以实现将单端输入变成差分输出的功能。此项功能在现代高速模数变换电路中非常有用,因为几乎所有的高速a/d芯片都要求模拟信号为差分输入,虽然部分芯片的手册中提到对于单端输入信号也可使用,但这样一来会使a/d转换结果的二次谐波增大,降低信噪比(snr)。ad8138很好的解决了这个问题,用户可以很容易的将单端信号转换成差分输出而不必使用变压器,并且它的输入阻抗高达6mΩ,可以直接与输入信号相连而省略隔离放大器,大大精简了电路结构。图4为ad8138的典型应用电路。
图4 ad8138典型应用电路
3 软件设计
3.1 windows驱动程序设计
usb设备驱动程序基于wdm。wdm型驱动程序是内核程序,与标准的win32用户态程序不同。采用了分层处理的方法。通过它,用户不需要直接与硬件打它道(在usb驱动程序中尤为明显),只需通过下层驱动程序提供的接口号访问硬件。因此,usb设备驱动程序不必具体对硬件编程,所有的usb命令、读写操作通过总线驱动程序转给usb设备。但是,usb设备驱动程序必须定义与外部设备的通讯接口和通讯的数据格式,也必须定义与应用程序的接口。
cypress公司提供了完整的cy7c68013驱动程序源码、控制面板程序及固件的框架,这大大提高了用户开发的进度。用户只需稍加修改或不需任何修改即可使用所带驱动程序,软件开发者大量的时间主要集中在应用程序和固件的开发。本文所述的数据采集系统驱动程序就在原来的基础上进行了简单的修改来满足我们的需要。根据我们自己的需求,一般只需修改deviceiocontrol例程,如我们主要增加了控制数据传输函数、启动和停止ad、复位fifo等,即ioctl_start_ad、ioctl_stop_ad、ioctl_reset_fifo。
3.2 底层固件设计
要实现usb2.0的高带宽数据传输,必须使用它特有的gpif特性,在开发固件前,首先必须根据实际需要对gpif waveform进行编辑。cy7c68013开发工具中带有一个gpif designer,如图5所示,编辑完waveform后,选择tools->export to gpif.c file来输出gpif.c文件,然后将该文件加入keil c工程进行编译。
由于cy7c68013的ep2、ep4、ep6、ep8四个端点共享4k fifo缓冲区,所以在该系统中,我们将ep2配置成4k的缓冲区,并设置为in。用ep1out作为ad的控制参数传递,如启动和停止ad数据输出、复位fifo等。在固件程序中,最重要的就是td_init()和td_poll()两个函数。
图5 gpif designer
在td_init()中主要完成gpif相应寄存器的初始化,如下:
void td_init(void) // called once at startup
{
// set the cpu clock to 48mhz
cpucs = ((cpucs & ~bmclkspd) | bmclkspd1);
syncdelay;
ep2cfg = 0xe8; // ep2in, bulk, size 1024, 4x buffered
syncdelay;
ep4cfg = 0x00; // ep4 not valid
syncdelay;
ep6cfg = 0x00; // ep6 not valid
syncdelay;
ep8cfg = 0x00; // ep8 not valid
syncdelay;
fiforeset = 0x80; // set nakall bit to nak all transfers from host
syncdelay;
fiforeset = 0x02; // reset ep2 fifo
syncdelay;
fiforeset = 0x00; // clear nakall bit to resume normal operation
syncdelay;
ep2fifocfg = 0x01; // allow core to see zero to one transition of auto out bit
syncdelay;
ep2fifocfg = 0x11; // auto out mode, disable pktend zero length send, word ops
syncdelay;
ep6fifocfg = 0x09; // auto in mode, disable pktend zero length send, word ops
syncdelay;
gpifinit (); // initialize gpif registers
syncdelay;
ep2gpifflgsel = 0x02; // for ep2in, gpif uses ff flag
syncdelay;
// global flowstate register initializations
flowlogic = flowstates[19]; // 0011 0110b - lfunc[1:0] = 00 (a and b), //terma/b[2:0]=110 (fifo flag)
syncdelay;
flowstb = flowstates[23]; // 0000 0100b - mstb[2:0] = 100 (ctl4), not //used as strobe
syncdelay;
gpifholdamount = flowstates[26]; // hold data for one half clock (10ns) assuming //48mhz ifclk
syncdelay;
flowstbedge = flowstates[24]; // move data on both edges of clock
syncdelay;
flowstbhperiod = flowstates[25]; // 20.83ns half period
syncdelay;
// reset the external fifo
oea |= 0x07;  
[1]