初始化:a.主程序一开始首先进行一些全局变量的初始化工作,b.之后调用TD-Init()函数.用户在该函数中添加自己的初始化代码以配置I/O端口.c.初始化工作还包括开中断,清除所有等待的USB中断请求等。
初始化全局变量:
Sleep = FALSE; // Disable sleep mode
Rwuen = FALSE; //Disable remote wakeup
Selfpwr = FALSE; //Disable self powered
GotSUD = FALSE; //Clear "Got setup data" flag
初始化用户变量函数:TD_Init(); //可根据设备功能的需要配置标志的I/O口
void TD_Init(void) // Called once at startup
{
//set the CPU clock to 48MHz 设置CPU时钟48MHz
CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ;
//set the slave FIFO interface to 48MHz 设置 从FIFO为48MHz
IFCONFIG |= 0x40;
//Registers which require a synchronization delay,需要同步延时的寄存器如下
//FIFORESET FIFOPINPOLAR
//INPKTEND OUTPKTEND
//EPxBCH:L REVCTL
//GPIFTCB3 GPIFTCB2
//GPIFTCB1 GPIFTCB0
//EPxFIFOPFH:L EPxAUTOINLENH:L
//EPxFIFOCFG EPxGPIFFLGSEL
//PINFLAGSxx EPxFIFOIRQ
//EPxFIFOIE GPIFIRQ
//GPIFIE GPIFADRH:L
//UDMACRCH:L EPxGPIFTRIG
//GPIFTRIG
//Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
// ...these have beenreplaced by GPIFTC[B3:B0] registers
//default: all endpoints have their VALID bit set
//default: TYPE1 = 1 and TYPE0 = 0 --> BULK
// default: EP2 and EP4 DIR bitsare 0 (OUT direction)
// default: EP6 and EP8 DIRbits are 1 (IN direction)
//default: EP2, EP4, EP6, and EP8 are double buffered
//we are just using the default values, yes this is not necessary...
EP1OUTCFG = 0xA0; //端点1 IN/OUT 配置为块传输
EP1INCFG = 0xA0;
SYNCDELAY; // see TRM section 15.14 延时
EP2CFG = 0xA2; //端点2 配置 out 批量传输,缓冲区大小为双缓冲
SYNCDELAY;
EP4CFG = 0xA0; //端点4 配置 out 批量传输
SYNCDELAY;
EP6CFG = 0xE2; //端点6 配置 IN 批量传输,缓冲区大小为双缓冲
SYNCDELAY;
EP8CFG = 0xE0; //端点8 配置 IN 批量传输
//out endpoints do not come up armed 输出端点不会自动设置,由于默认是双缓冲,需要写两次计数器
//since the defaults are double buffered we must write dummy byte counts twice
SYNCDELAY; //延时
EP2BCL = 0x80; //配置EP2OUT写计数器
SYNCDELAY; //延时
EP2BCL = 0x80;
SYNCDELAY;
EP4BCL = 0x80; //配置EP4OUT写计数器
SYNCDELAY;
EP4BCL = 0x80;
//enable dual autopointer feature
AUTOPTRSETUP |= 0x01;
}
描述符地址重映射:
pDeviceDscr = (WORD)&DeviceDscr; //指针取地址
pDeviceQualDscr = (WORD)&DeviceQualDscr;
pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr;
pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr;
pStringDscr = (WORD)&StringDscr;
重新列举:初始化之后,固件程序将会检测是否收到设置数据(GOTSUD标志位是否为真);如果没有,程序会以1 s为间隔,重新列举设备(即软件模拟设备的断开和重新连接),直到端点0收到设置包为止。
#ifndef NO_RENUM //USB重枚举,如果固件程序从EEPROM中加载则该步骤就没必要
//Renumerate if necessary. Do this bychecking the renum bit. If it
//is already set, there is no need to renumerate. The renum bit will
//already be set if this firmware was loaded from an eeprom.
if(!(USBCS & bmRENUM))
{
EZUSB_Discon(TRUE); //renumerate
}
#endif
最后就是响应设备请求,进入到任务处理器:一旦检测到端点0收到一个设置包,固件程序就开始启动执行一个互操作的任务分配器,这个任务分配器按照给定的顺序重复执行下面的任务:
u 调用函数TD_Poll()。
u 判断是否有标准设备请求等待处理。
u 确定USB核是否报告了USB挂起事件。如果有,则调用用户函数TD_Suspend();如果能够成功返回,任务处理器就测试一个恢复(Resume)事件;如果没有检测到恢复事件,处理器就被设置到挂起模式;如果检测到一个恢复事件,便会调用用户函数TD_Resume()。
下面为任务处理器的部分代码:
while(TRUE) // MainLoop 主循环
{
// Poll User Device
TD_Poll(); //可在此添加需要实现的功能,完成用户指定的任务,因为它会被main函数重复执行
//固件程序会通过此函数不停的轮询设备
// Check for pending SETUP
if(GotSUD) //是否有setup包
{
SetupCommand(); // Implement setup command 执行设置命令
GotSUD = FALSE; // ClearSETUP flag 清除标志
}
// check for and handle suspend. 检查并操作挂起
// NOTE: Idle mode stops the processor clock. There are only two
// ways out of idle mode, the WAKEUP pin, and detection of the USB
// resume state on the USB bus. The timers will stop and the
// processor will not wake up on any other interrupts.
//说明:一旦设备挂起,进入空闲模式,则系统时钟停止,只有两种方式
//可以唤醒USB设备,一是WAKEUP引脚,二是USB总线探测到resume状态
if (Sleep) //检测到sleep标志
{
if(TD_Suspend()) //执行USB挂起子函数
{
Sleep = FALSE; // Clear the"go to sleep" flag. Do it hereto prevent any race condition between wakeup and the next sleep.
do //清除标志
{
EZUSB_Susp(); // Place processor in idle mode. 进入空闲模式
}
while(!Rwuen && EZUSB_EXTWAKEUP());
// above. Must continue to goback into suspend if the host has disabled remote wakeup
// *and* the wakeup was caused by the external wakeup pin.
// 8051 activity will resume here due to USB bus or Wakeup# pinactivity.
EZUSB_Resume(); // If source isthe Wakeup# pin, signal the host to Resume.
TD_Resume(); //从空闲状态恢复
}
}
}
EA-USBFX2提供了两种类型的I/O系统:可编程I/O口和I2C控制器。56脚封装的仅包含PA、PB和PD。I2C总线控制器使用SCL和SDA两个管脚需连接2.2千欧的上拉电阻,其功能实现与EZ-USB相同。
FX2的增强型8051使用特殊功能寄存器OEx(OEA,OEB,OEC,OED,OEE)和IOx(IOA,IOB,IOC,IOD,IOE)来控制其I/O管脚。其中OEx用于控制管脚的输入输出功能(0表示输入,1表示输出),IOx用于读取或写入I/O管脚的数据。
EZ-USBFX2系列芯片的I/O口都具有第二功能,即与其他功能复用(见表1)。增强型8051可通过一系列控制寄存器(见表2中第三列)设置I/O口实现其复用功能。这时,寄存器OEx无效,但IOx始终映射出管脚的当前状态。
表1 EZ-USB FX2 I/O 管脚的定义
I/O 管脚 |
复用功能 |
控制寄存器 |
PA0 |
INT0 |
PORTACFG.0 = 1 |
PA1 |
INT1 |
PORTACFG.1 = 1 |
PA2 |
SLOE |
IFCFG1:0 = 11 |
PA3 |
WU2 |
WU2EN = 1 |
PA4 |
FIFOADR0 |
IFCFIG1:0 = 11 |
PA5 |
FIFOADR1 |
IFCFIG1:0 = 11 |
PA6 |
PKTEND |
IFCFIG1:0 = 11 |
PA7 |
FLAGD |
PORTACFG.7 = 1 |
SLCS |
PORTACFG.6 = 1 或 IFCFG1:0 =11 |
|
PB0-PB7 |
FD0-FD7 |
IFCFG1 = 1 |
PC0 |
GPIFA0 |
PC0 GPIFA0 PORTCCFG.0 = 1 |
PC1 |
GPIFA1 |
PORTCCFG.1 = 1 |
PC2 |
GPIFA2 |
PORTCCFG.2 = 1 |
PC3 |
GPIFA3 |
PORTCCFG.3 = 1 |
PC4 |
GPIFA4 |
PORTCCFG.4 = 1 |
PC5 |
GPIFA5 |
PORTCCFG.5 = 1 |
PC6 |
GPIFA6 |
PORTCCFG.6 = 1 |
PD0-PD7 |
FD8-FD15 |
IFCFG1 = 1 且所有 WORDWIDE 位均为 1 |
PE0 |
T0OUT |
PORTECFG.0 = 1 且 GSTATE = 0 |
PE1 |
T1OUT |
PORTECFG.1 = 1 且 GSTATE = 0 |
PE2 |
T2OUT |
PORTECFG.2 = 1 且 GSTATE = 0 |
PE3 |
RXD0OUT |
PORTECFG.3 = 1 |
PE4 |
RXD1OUT |
PORTECFG.4 = 1 |
PE5 |
INT6 |
PORTECFG.5 = 1 |
PE6 |
T2EX |
PORTECFG.6 = 1 |
PE7 |
GPIFA8 |
PORTECFG.7 = 1 |
从属 FIFO 接口模式
为便于端点2、 端点4、 端点6 和端点8 的数据缓冲区能更好地和外围电路进行通信,FX2 端口除了可作为8051通用I/O口外还提供了 2 种接口模式:从属 FIFO 和 GPIF(General Programmable Interface,通用可编程接口),其由寄存器 IFCFG 控制,表2 列出了 FX2 在这两种模式下 I/O 管脚的功能。
在“从FIFO”模式下,外部逻辑或外部处理器直接与FX2端点FIFO相连。在这种模式下,GPIF不被激活,因为外部逻辑可直接控制FIFO。这种模式下,外部主控端既可以是异步方式,也可以是同步方式,并可以为FX2 接口提供自己的独立时钟。
表2从属FIFO/GPIF 模式下I/O 管脚的功能
IFCFG1:0 = 00(I/O 口) |
IFCFG1:0 = 10(GPIF) |
IFCFG1:0 = 11(从属 FIFO) |
PD7~PD0 |
FD15~FD8 |
FD15~FD8 |
PB7~PB0 |
FD7~FD0 |
FD7~FD0 |
INT0#/PA0 |
INT0#/PA0 |
INT0#/PA0 |
INT1#/PA1 |
INT1#/PA1 |
INT1#/PA1 |
PA2 |
PA2 |
SLOE |
WU2/PA3 |
WU2/PA3 |
WU2/PA3 |
PA4 |
PA4 |
FIFOADR0 |
PA5 |
PA5 |
FIFOADR1 |
PA6 |
PA6 |
PKTEND |
PA7 |
PA7 |
PA7/FLAGD/SLCS# |
PC7~PC0 |
PC7~PC0 |
PC7~PC0 |
PE7~PE0 |
PE7~PE0 |
PE7~PE0 |
当 EZ-USB FX2 工作从属 FIFO 时,外围电路可像普通 FIFO 一样对 FX2 中端点 2、端
点 4、端点 6 和端点 8 的数据缓冲区进行读写。
图1 展示了这种模式下FX2 和外围电路的典型连接。其中,IFCLK 为接口时钟,可由芯片内部产生(30MHz/48MHz),也可由外部输入(5MHz~48MHz);FLAGA-FLAGD 为 FIFO 标志管脚,用于映射 FIFO 的当前状态;SLCS#为从属 FIFO 的片选信号,低电平有效;FD[15:0]为 16 位双向数据总线;FIFOADR[1:0]用于选择和 FD 连接的端点缓冲区(00 代表端点2,01代表端点4,10代表端点6,11代表端点8);SLOE 用于使能数据总线 FD 的输出;SLRD 和 SLWR 可分别作为 FIFO 的读写选通信号;外围电路可通过使能 PKTEND 管脚向 USB 发送一个 IN 数据包,而不用考虑该包的长度。表4 列出了与从属FIFO 模式有关的各种FX2 寄存器。
图 1 EZ-USB FX2 从属 FIFO 模式的典型连接
表 3 从属 FIFO 模式的相关寄存器
IFCONFIG |
FIFOPINPOLAR |
EPxFIFOPFH/L |
EPxFLAGIRQ |
PINFLAGSCD |
EPxCFG |
PORTACFG |
EPxFIFOBCH:L |
PINFLAGSCD |
EPxFIFOCFG |
INPKTEND |
EPxFLAGS |
FIFORESET |
EPxAUTOINLENH:L |
EPxFLAGIE |
EPxBUF |
GPIF 接口模式
在 GPIF 模式下,EZ-USBFX2 可由软件来编程输出读写控制波形。图 2展示了这种模式下 FX2和外围电路的典型连接。 其中, GPIFADR[8:0]用于输出 9 位地址;IFCLK 为接口时钟;FD[15:0]为 16 位双向数据总线;CTL[5:0]用于输出可编程的控制信号,如读写选通等;RDY[5:0]为输入的状态信号;GSTATE[2:0]用于输出当前 GPIF状态码,通常仅在调试时使用。表 2.11 列出了与 GPIF 模式有关的各种 FX2 寄存器。
图 2 EZ-USB FX2 GPIF 模式的典型连接
表 4 GPIF 模式的相关寄存器
GPIFDLECS |
GPIFTCB3:0 |
IFCONFIG |
EPxTRIG |
GPIFDLECTL |
GPIFWFSELECT |
FIFORESET |
GPIFABORT |
GPIFCTLCFG |
EPxGPIFFLGSEL |
EPxCFG |
XGPIFSGLDATH/LX/LNOX |
PORTCCFG |
EPxGPIFPFSTOP |
EPxFIFOCFG |
GPIFSGLDATH/LX/NOX |
PORTECFG |
GPIFREADYCFG |
EPxAUTOINLENH/L |
GPIFRIG |
GPIFADRH/L |
GPIFREADYSTAT |
EPxFIFOPFH/L |
- |
“GPIF主控”接口模式使用PORTB和PORTD 构成通向四个FX2端点FIFO( EP2 ,EP4 , EP6和EP8)的16位数据接口。GPIF 作为内部的主控制器与FIFO直接相连, 并产生用户可编程的控制信号与外部接口进行通信。同时,GPIF 还可以通过RDY引脚采样外部信号并等待外部事件。由于GPIF 的运行速度比FIFO 快得多,因此其时序信号具有很好的编程分辨率。另外,GPIF 既可以使用内部时钟,也可以使用外部时钟。
在进行GPIF波形设计时,使用CyPress公司提供的GPIF Designer开发工具,它提供了一个非常体贴的可视化窗口,只需在图形界面上进行简单的修改,就可以自动生成复杂的波形描述符,大大减轻了编程的工作量。图3.3是它的设置面板,它主要是通过GPIF的脚的连接(如FD[15:0]、CTL[2;0]、RDY[l;01等)来实现对其波形的控制"
图3 GPIF Designe的设置面板
图4 FIFO读波形
l 寄存器操作
在下列条件,读写EZ-USB寄存器需要同步延时:
在写寄存器0XE600-0XE6FF和写表2之中的寄存器之间;
在写表2之中的寄存器和读0XE600-0XE6FF的寄存器之间。
表5 需要同步延时的寄存器
FIFORESET |
FIFOPINPOLAR |
ECCCFG |
INPKTEND |
EPxBCH:L |
ECCRESET |
EPxFIFOPFH:L |
EPxAUTOINLENH:L |
ECC1B0 |
EPxFIFOCFG |
EPxGPIFFLGSEL |
ECC1B1 |
PINFLAGSAB |
PINFLAGSCD |
ECC1B2 |
EPxFIFOIE |
EPxFIFOIRQ |
ECC2B0 |
GPIFIE |
GPIFIRQ |
ECC2B1 |
UDMACRCH:L |
GPIFADRH:L |
ECC2B2 |
GPIFTRIG |
EPxGPIFTRIG |
|
OUTPKTEND |
REVCTL |
|
GPIFTCB3 |
GPIFTCB2 |
|
GPIFTCB1 |
GPIFTCB0 |
|
最小延时时间是IFCLK and CLKOUT (CPU Clock) 频率的函数,公式为:
l USB传输
USB的四种传输类型:1、控制传输,2、中断传输,3、等时传输,4、块传输是端点传输中的概念,是由端点配置寄存器EPxCFG中的为TYPE1、TYPE0决定的。而传输方向也是由其中的位DIR控制,默认端点2,4为IN,端点6,8为OUT。
表6 USB传输类型
传输模式 |
中断传输(Interrupt) |
批量传输(Bulk) |
等时传输(ISO) |
控制传输(Control) |
传输速率 |
12(1.5,低速) |
12 |
12 |
1.5/12 |
数据的最大长度(字节) |
1~16(1~8低速) |
8/16/32/64 |
1~1023 |
1~64(1~8低速) |
数据的周期性 |
有 |
没有 |
有 |
没有 |
发生错误重传 |
可 |
可 |
不可 |
可 |
应用设备 |
鼠标、键盘和摇杆 |
打印机,扫描仪 |
语言 |
|
可得到的最大带宽(Mbps) |
6.762(0.051低速) |
9.728 |
10.240 |
|
1、 固件程序、驱动程序、用户应用程序各自的作用分别是什么?
固件可以理解为单片机里面的整个软件,是嵌入的,相对于上位机软件而言的。
固件程序是所有基于微控制器及其外围电路的功能设备正常工作必不可少的部分,其作用就是辅助硬件,主要有以下几种功能:
A.初始化工作,包括设置一些特殊功能寄存器的初值以实现所需的设备属性或者功能,例如开中断,使能端点,配置端口等。
B.辅助硬件完成设备的重新列举过程,包括模拟设备的断开与重新连接,对接收到的设置包进行分析判断,从而对主机的设备请求作出适当的响应,完成主机对设备的配置任务。
C.对中断的处理。
D.数据的接收和发送。
E.外围电路的控制。
驱动程序则多指带操作系统的软件里面最底层的,和硬件打交道的程序。
用户应用程序也多指带操作系统的软件里面最顶层的,和用户打交道的程序。应用程序应实现的主要功能包括:开启或关闭USB设备、设置图像传感器参数、检测USB设备、设置USB数据传输管道、传输图像数据、调用相关程序打开图像。
2、 摄像头采集到的图像信息经过图像传感器处理之后的数据是什么格式?是几位的数据?
答;经图像传感器输出的16位数据总线接入到CYP768013A的FD0~FD15口,再由USB芯片把数据传输至上位机。
3、 USB如何把数据传输至PC机?从属FIFO方式下端口如何配置?
答:USB接口有四根线,通过D+和D-两根差分信号与与host通信。
“从FIFO”模式下,外部逻辑或外部处理器直接与FX2端点FIFO相连,由IFCFG1:0来配置引脚的功能,具体见表3。
4、 USB负责数据的传输,传输的数据信息,如何把数据在电脑上显示出深度图像?
答;用户应用程序部分的设计负责把采集到数据转换为图像信息。