一、概述
CYUSB3014是赛普拉斯在近几年推出的新一代USB3.0的外设控制器,可以解决USB2.0带宽限制,或者单独开发USB协议和驱动的难题。赛普拉斯将CYUSB3014简称为EZ-USB FX3,具有高度的灵活特性,开发人员只需要下载FX3的固件库,就能使用USB3.0的功能。
目前在一些电子产品中,使用主控器加PHY芯片最流行的方式是用FPGA+FX3这种搭配来实现USB3.0接口的。
赛普拉斯官方数据手册中对FX3的描述如下:EZ-USB FX3 具有一个可进行完全配置的并行通用可编程接口GPIF II,它可与任何处理器、ASIC 或 FPGA 连接。这个通用可编程接口 GPIF II 是赛普拉斯旗舰 USB 2.0 产品 FX2LP 中的GPIF的增强版本。它可轻松无缝地连接至多种常用接口,比如异步 SRAM、异步和同步地址数据复用式接口、并行 ATA 等等。
EZ-USB FX3 集成了 USB 3.0 和 USB 2.0 物理层 (PHY) 以及 32位ARM926EJ-S 微处理器,具有强大的数据处理能力,并可用于构建定制应用。采用了一种巧妙的架构,使从 GPIF II 到USB 接口的数据传输速度可达 320 MBps[1]。通过集成的 USB 2.0 OTG 控制器,可以实现需要双角色使用场合的应用。例如EZ-USB FX3 可以作为 MSC 和 HID 级设备的 OTG主机使用。
二、CYUSB3014内部逻辑框图
FX3的功能是在FPGA/MCU/CPU这些控制器和USB接口之间作为一个桥梁。CPU将需要发送的并行数据,通过GPIF II接口传给FX3,FX3内部将数据打包成带有USB3.0协议的数据包,通过USB标准接口对外传输。这样开发人员即不用掌握USB3.0协议的底层架构,还能使用UVC的协议将数据传输到带有USB3.0接口的主机(电脑)上。
在FX3的内部,具有一个ARM9的核,内部集成了存储代码和数据的512KB片上SRAM,通过JTAG口烧写程序,FX3就能作为ARM使用。常见的应用场景如下所示.
三、CYUSB3014硬件配置
电源
FX3电源有3个部分:内核电源;数字I/O口电源;I/0模拟电源
内核电源
-
VDD :逻辑内核的供电电压。额定供电电压为 1.2 V。该电域为内核逻辑电路供电。下列也必须使用同样的供电:
-
AVDD :用于 PLL、晶体振荡器和其他内核模拟电路的 1.2 V供电。
-
U3TXVDDQ/U3RXVDDQ :用于 USB 3.0 接口的 1.2 V 供电电压。
数字I/O口电源
-
IO_VDDQ:指用于数字 I/O 的一组独立供电。供电电压为 1.8V 至 3.3V。EZ- USB FX3 为数字I/O 提供下列六个独立供电
-
VIO2 - IO2 供电
-
VIO3 - IO3 供电
-
VIO4 -UART/SPI/I2S 供电
-
VIO5 - I2C 和 JTAG 供电(支持 1.2V 至3.3V)
-
CVDDQ - 时钟供电电域
I/0模拟电源
VBATT/VBUS :用于 USB I/O 和模拟电路的 3.2V 至 6V 电池供电。通过 EZ-USB FX3 的内部电压调节器向 USB 收发器供电。VBATT 将内部调节为 3.3V。
3.2启动配置
CYUSB3014的启动配置,主要是通过PMODE三个管脚实现的,将PMODE管脚上拉,悬空,接地就可以实现不同的启动配置。具体方法见下表。
时钟配置
FX3支持两种时钟配置,一种是使用无源的外部晶振,另外一种是在CLKIN专用时钟引进上连接外部的时钟。
常见的使用方式是配置为000,使用一颗19.2MHz的晶振就可以。
四、GPIFII接口
GPIFII接口手册中描述如下:
EZ-USB FX3 具有高性能通用可编程接口 GPIF II。此接口能实现类似于 FX2LP 的 GPIF 和从器件 FIFO 接口的功能,但更为高级。
GPIF II 是一种可编程状态机,其所启用的灵活接口可用作工业标准或专用接口中的主控或从器件。并行和串行接口均可通过GPIF II 实现。
GPIF II 的特性总结如下:
-
可用作主控或从器件
-
提供 256 种固件可编程状态
-
支持 8 位、16 位和 32 位并行数据总线
-
接口频率可高达 100 MHz。
-
使用 32 位数据总线时支持 14 根可配置控制引脚。所有控制引脚可作为输入/ 输出或双向引脚。
-
使用 16/8 位数据总线时支持 16 根可配置控制引脚。所有控制引脚可作为输入/ 输出或双向引脚。
使用方式如下:
上面这幅框图的意思是,GPIF II口用作32位并行数据总线,其中A[1:0]的功能是指内部在使用4个缓冲器区的哪一个。FLAG信号是FX3内部SLAVE FIFO状态的标志信息。其他几根信号属于控制信号。
五、开发环境
-
FPGA 开发板(内含CYUSB3014芯片)
-
quartus prime17.1
-
操作系统win10
-
带usb3.0接口的电脑
-
只要带CYUSB3014芯片的fpga开发板都可以参考本教程
六、准备工作
缓冲区可以通过固件来配置,上图是2缓存,每个缓冲区是1kB,为了提高性能,我在固件中设置的是4缓存,每个缓冲区16KB.数据总线32位宽,时钟100MHz,实测上下行通信都能达到338MB/s。
-
CYUSB3014芯片与fpga连接使用的是GPIF接口,我们只需要把CYUSB3014当成fifo来使用即可。
-
七、驱动
-
先安装FX3_SDK_Windows_v1.3.3,这个软件安装目录,下面有简称为SDK
-
在SDK目录中,有提供很多文档、固件实例和相应的驱动
-
在进行试验前要先安装好cypress提供的usb驱动,插上usb后,电脑就会检测到未识别的设备,这时打开设备管理器,右键未识别的usb,然后手动选择驱动。
-
八、固件
-
对于固件这块,有兴趣的同学可以自己去研究一下,如果只是使用的话,就可以直接使用本教程提供的固件。使用本实例的固件,你就可以基本可以把当成usb2.0一样使用了,因为他们都是slave fifo模块。
-
如果自己想折腾一下的话,需要注意的就是标志信号的设置,usb标志信号比较灵活。下面主要讲解一下标志信号的设置。
-
九、GPIF II Designer
-
Cypress官方提供了一个软件,可以用来设置gpif接口信号(包括标志信号),本教程只针对slave fifo,其他的模式自己去查看文档。
-
打开GPIF II软件
2. 点击红色圈的地方
3. 想要编辑更多的信息,点击 File->Save project as Editable…
4. 编辑区按上图设置,右边的框图主要是设置标志信号FLAGA/FLAGB/FLAGC/FLAGD.双击右边的标志,各标志设置如下所示:
5.四个标志都设置为低有效!!!初始值倒无所谓,并且都设置为专用标志,设置完后,只需要编译一下就可以了生成我们需要的头文件了。
6.将这个.h文件放到固件的工程中,替换固件相应的.h文件即可。
7.这些在本工程里面都已经做好了,如果没有说明特别的需要,就直接使用本项目提供的固件工程即可,就不需要自己再去设计GPIF接口了。
-
10 写标志
-
flag_a和flag_b设置成线程0(P2U,即FPGA往CYUSB3014写)专用标志,flag_b为有水印值标志,
-
当写满时,正常的flag_a会拉低,但是拉低的时间有点迟了,导致fpga检测到flag_a为低时,已经写溢出了,而flag_b的水印值可以使标志提前拉低,以便fpga检测到flag_b为低,不会发生写溢出。
因为我们slwr信号是要根据flag来驱动的,假如没有水印值标志,使用flag_a,检测到flag_a == 0时,再将slwr拉高,是不是就会发生写溢出了。通过上图不难发现只需要将flag_a提前4个周期拉低就可以满足我们的要求了。所以我们设置水印值为4.到时候看看signal_tap抓的图就知道了。
CyU3PGpifSocketConfigure设置水印值
-
读标志
-
flag_c 和 flag_d 设置成线程3(U2P,即FPGA从CYUSB3014读)专用标志,flag_d为有水印值标志,
-
当读空时,正常的flag_c会拉低,但是拉低的时间有点迟了,导致fpga检测到flag_a为低时,已经读空了,而flag_d的水印值可以使标志提前拉低,以便fpga检测到flag_b为低,不会发生读空
-
和写操作类似,slrd信号是要根据flag来驱动的,假如没有水印值标志,使用flag_c,检测到flag_c == 0时,再将slrd拉高,是不是就会发生读空了。通过上图不难发现只需要将flag_c提前3个周期拉低就可以满足我们的要求了。所以我们设置水印值为3.到时候看看signal_tap抓的图就知道了
-
另外需要主要的地方是fifo_addr到数据有效有3个周期延迟
-
打开ezUsbSuite.exe
-
导入本教程提供的固件工程
-
最后再提醒一下,fifo的大小是16k,P2U的缓冲区设置为8个,U2P缓冲区设置为4个,这种配置可以最大的提高传输速度。需要注意的是,不管是写还是读,都是以16k为单位的,也就是说即便你只是想发送一个4字节的指令,你也要发送16k字节,多余发0就可以了。
-
-
设置完后,就可以编译了,画重点了,使用debug编译的速度大概在252MB/s,使用release编译的速度大概在338MB/s.
-
测试
-
本教程提供的固件,是同时支持读写的。
-
下载固件
-
在调试期间,先将引导方式设置为usb引导
-
读测试
-
打开本教程提供的fpga程序,设置slrd下降沿触发。
-
-
因为读缓冲区的大小是16k字节,而我们发送数据一般都是一些指令,数据量比较小,所以我在数据结构做了个调整,前4个字节是你要发送的数据的长度(32位),在fpga中,有cmd_flag和cmd_data信号,根据这两个信号就知道读的数据了。具体自己看我的代码。
-
写测试
-
写测试就简单了,点击transfer data-in,pc就会读取16k数据。数据为0-16‘h0000_0FFF。
-
测速
-
打开streamer软件
可以看出读写速度都差不多在338MB/s左右。性能还是不错。