USB小白学习之路(8)FX2LP cy7c68013A——Slave FIFO 与FPGA通信(转)
此博客转自CSDN:http://blog.csdn.net/xx116213/article/details/50535682
这个博客只对自己理解CY7C68013的配置有一定的帮助,对于配置CY7C68013,使其与FPGA通信,还是官方给的文档AN61345以及附件代码更详细直观。
1 USB 概述
USB名称解释
USB是通用串行总线(Universal Serial Bus)的缩写。能过在计算机运行过程中随意地接入,并且立刻就能投入工作,那么这样的特性叫做即插即用PnP(Plug and Play)。由于USB是主从模式的结构,设备与设备之间、主机与主机之间不能互连。为了解决这个问题,出现了USB OTG(On the go),它的做法:同一个设备,在不同场合下可以在主机与从机之间切换。
USB系统组成
usb系统的三个组成:Host、HUB和Device。
- Host:主控器,能读写usb设备的设备。例如插有U盘的电脑,那么PC就是主控器。
- HUB:扩充USB接口。
- Device(USB Device):如硬盘、打印机、U盘等。
USB设备组成
每一个USB设备由一个或多个配置来控制其行为,使用多配置原因是对操作系统的支持;一个配置是由接口(Interface)组成;接口则是由管道(Pipe)组成;管道是和USB设备的端点(Endpoint)对应,端点都是输入输出成对的。在固件编程中,USB设备、配置、接口和管道都来描述符来报告其属性。
一个端点(Endpoint)建立一个管道。管道的端点总是成对出现,即In Endpoint和Out Endpoint。端点0默认为控制管道,其它端点可以配置成数据管道。一个具体的端点,只能工作在一种传输模式下。
- In Endpoint:由device向Host发送数据的端点。
- Out Endpoint:由Host向device发送数据的端点。
USB传输速度
USB1.0和USB1.1版本中,只支持1.5Mb/s的低速(low-speed)模式和12Mb/s的全速模式。在USB2.0种,又加入了速度更快(480Mb/s)的高速模式。而USB3.0的最大传输带宽高达5.0Gbps(625MB/s)。
USB可扩展设备
USB1.1规定最多为4层,USB2.0规定最多为6层。理论上,一个USB主控制器最多可接127个设备,这是因为协议规定每个USB设备具有一个7 bit的地址(取值范围0~127),而地址0是保留给未初始化的设备使用。
USB传输类型
虽然USB定义了数据在总线上传输的基本单位是包,但是我们还不能随意地使用包来传输数据,必须按照一定的关系把这些不同的包组织成事务才能传输数据。
事务通常由两个或者三个包组成:令牌包,数据包和握手包。
- 令牌包用来启动一个事务,总是由主机发送。
- 数据包传送数据,可以从主机到设备,也可以从设备到主机,方向由令牌包来制定。
- 握手包的发送者通常为数据接收者,当数据接收正确后,发送握手包。设备也可以使用NAK握手包来表示数据还未准备好。
USB协议规定了4种传输类型:批量传输、等时传输(同步传输),中断传输和控制传输。其中,批量传输、等时传输、中断传输每传输一次数据都是一个事务;控制传输包括三个过程,建立过程和状态过程分别是一个事务,数据过程则可能包含多个事务。4种数据传输的相关特性(仅限USB1.1协议)如下表。
传输模式 | 中断传输Interrupt | 批量传输Bulk | 等时传输ISO | 控制传输Control |
---|---|---|---|---|
传输速率/Mbps | 12(1.5,低速) | 12 | 12 | 1.5/12 |
数据的最大长度/Byte | 1~64(1~8,低速) | 8/16/32/64 | 1~1023 | 1~64(1~8,低速) |
数据周期性 | 有 | 没有 | 有 | 没有 |
发送错误重传 | 是 | 是 | 否 | 是 |
应用设备 | 鼠标键盘 | 打印机 | 语音 | |
可得到的最大宽度/Mbps | 6.762(0.051低速) | 9.728 | 10.240 |
批量传输使用批量事务传输数据。一个批量事务由三个阶段:令牌包阶段,数据包阶段和握手包阶段。每个阶段都是一个独立的包。批量传输通常用于数据量大,对数据的实时性要求不高的场合。
USB2.0 数据帧
USB2.0和USB1.1规范的最大不同就是数据帧。在USB1.1规范中,USB数据采用每毫秒一个数据帧的方式进行数据传输,在毫秒数据帧的开始,USB主机首先产生帧开始(SOF)数据包,并传输当前数据帧号,后面是传输数据。对于USB2.0规范,为了支持480Mbps高速传输速度,USB2.0提出了微帧的概念,每毫秒数据帧又包含8个微帧。
USB2.0 端点缓冲区
传输类型 | USB1.1数据包大小 | USB2.0数据包大小 |
---|---|---|
控制传输 | 8,16,32,64 | 64 |
批量传输 | 8,16,32,64 | 512 |
中断传输 | 1~64 | 1024 |
等时传输 | 1023 | 1024 |
2 CY7C68013与FPGA
官方资料AN61345 提供了一个示例项目,用以通过从设备 FIFO 接口将 FX2LP 连接至 FPGA。示例实现中描述的接口为各个应用执行高速度的 USB 连接事项,如数据采集、工业控制和监控以及图像处理。
可以通过两个不同的模式将 FX2LP 连接至 FPGA。这两个模式分别为通用可编程接口( GPIF)模式和从设备 FIFO模式。
2.1 硬件连接
引脚名称 | 说明 |
---|---|
SLRD | SLRD 引脚应由主设备激活,用以从 FIFO 读取数据。 |
SLWR | SLWR 引脚应该由主设备激活,以将数据写入到 FIFO 内。 |
SLOE | 是指 FIFO 输出驱动器的使能信号。 |
FIFOADR[1:0] | 这些信号用于选择有效的端点。 |
FD[15:0] | 16 位数据总线 |
FLAGA/FLAGB/FLAGC/FLAGD | FIFO 使用这些标志来表示各种状态(满、空、可编程)。 |
IFCLK | 是指与从设备 FIFO 接口同步的时钟。在本应用笔记所提供的设计中,该时钟的频率被配置为 48 MHz,并由连接至 FX2LP 的 FPGA 生成。 |
CLKOUT | FX2LP 的 CLKOUT 引脚可以提供的时钟频率分别为 12、 24 或 48 MHz |
2.2 固件的实现
利用Cypress Suite USB提供的资源,在此基础上修改例程。
FX2LP固件
Fw.c 文件包含 main 函数。它执行了 USB 维持的大部分操作(如进行枚举),并且每当需要自定义时,它将调用应用代码( Slave.c)中特定名称的外部函数。一般情况下,不需要修改 Fw.c 文件。执行各个日常操作的步骤后,该函数将调用 Slave.c 所提供的外部函数,即 TD_init。(前缀TD 表示“任务调度” 。然后,它进入一个无限循环,以通过 CONTROL 端点 0 检查 SETUP 数据包的到来。该循环还会检查 USB 暂停事件,但从设备 FIFO 应用不会使用该循环。每次进入该循环时,该函数都将调用 Slave.c 文件中提供的外部函数 TD_Poll。 TD_Poll 函数用于同步化 FPGA 和 FX2LP 间所传输的数据。开始传输数据时,由于 FIFO 被配置为自动模式,因此该函数不会进行任何操作。
每个 USB 外设通过它们的 CONTROL 端点接收两个请求类型:枚举和操作。
枚举
当 与 USB 器 件 连 接 时 , 主 机 PC 将 发 送 多 个GET_DESCRIPTOR 请求以确定器件类型及其要求。这些操作属于枚举过程的一部分。 fw.c 代码截取这些请求,并通过使用 dscr.a51 文件中所存储的数值处理请求。
操作
需要用户代码时, fw.c 将调用一个带有特定名称前缀为 DR(器件请求)的外部函数(存储在 Slave.c 文件中)。对于从设备 FIFO 这种简单的应用,只会使用一个配置和一个接口。因此, 图 14 中所显示的两对 DR_Set-Get 函数只存储由主机发送的“ Set” 值,并在主机发出“ Get” 请求时对该值进行随路。对于更加复杂的配置,您可以使用这些 DR调用( “ hooks” )更改摄像机的分辨率或将请求路由到两个不同的接口等。
固件代码
#pragma NOIV // Do not generate interrupt vectors
#include "fx2.h"
#include "fx2regs.h"
#include "fx2sdly.h" // SYNCDELAY macro extern BOOL GotSUD; // Received setup data flag
extern BOOL Sleep;
extern BOOL Rwuen;
extern BOOL Selfpwr; BYTE Configuration; // Current configuration
BYTE AlternateSetting; // Alternate settings //-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
void TD_Init( void )
{ // Called once at startup CPUCS = 0x10; // CLKSPD[1:0]=10, for 48MHz operation, output CLKOUT PINFLAGSAB = 0x08; // FLAGA - EP2EF
SYNCDELAY;
PINFLAGSCD = 0x60; // FLAGD - EP6PF
SYNCDELAY;
PORTACFG |= 0x80;
SYNCDELAY;
IFCONFIG = 0xE3; // for async? for sync?
SYNCDELAY;
CPUCS |= 0x02; // EP4 and EP8 are not used in this implementation...
EP2CFG = 0xA0; //out 512 bytes, 4x, bulk
SYNCDELAY;
EP6CFG = 0xE0; // in 512 bytes, 4x, bulk
SYNCDELAY;
EP4CFG = 0x02; //clear valid bit
SYNCDELAY;
EP8CFG = 0x02; //clear valid bit
SYNCDELAY; SYNCDELAY;
FIFORESET = 0x80; // activate NAK-ALL to avoid race conditions
SYNCDELAY; // see TRM section 15.14
FIFORESET = 0x02; // reset, FIFO 2
SYNCDELAY; //
FIFORESET = 0x04; // reset, FIFO 4
SYNCDELAY; //
FIFORESET = 0x06; // reset, FIFO 6
SYNCDELAY; //
FIFORESET = 0x08; // reset, FIFO 8
SYNCDELAY; //
FIFORESET = 0x00; // deactivate NAK-ALL // handle the case where we were already in AUTO mode...
// ...for example: back to back firmware downloads...
SYNCDELAY; //
EP2FIFOCFG = 0x00; // AUTOOUT=0, WORDWIDE=0 // core needs to see AUTOOUT=0 to AUTOOUT=1 switch to arm endp's
SYNCDELAY; //
EP2FIFOCFG = 0x11; // AUTOOUT=1, WORDWIDE
SYNCDELAY; //
EP6FIFOCFG = 0x0D; // AUTOIN=1, ZEROLENIN=1, WORDWIDE=1
SYNCDELAY;
} void TD_Poll( void )
{ // Called repeatedly while the device is idle // ...nothing to do... slave fifo's are in AUTO mode... }
TD_Init
该函数执行以下操作:
- 将 8051 时钟频率设置为 48 MHz。
CPUCS = 0x10;
……
CPUCS |= 0x02;
- 配置 FIFO 标志输出。 FLAGA 被配置为 EP2 OUTFIFO 的空标志, FLAGD 被配置为 EP6 IN FIFO可编程标志(官方的例程:配置为EP6 IN FIFO 的满标志)。
PINFLAGSAB = 0x08; // FLAGA - EP2EF
SYNCDELAY;
PINFLAGSCD = 0x60; // FLAGD - EP6PF
SYNCDELAY;
- 对从设备 FIFO 接口进行配置,使之使用 48 MHz 大小的内部时钟。
IFCONFIG = 0xE3;
- 将 EP2 配置为 BULK-OUT 端点,并将 EP6 配置为BULK-IN 端点。该两个端点均为四倍缓冲,并使用512 字节的 FIFO。由于本设计中没有使用 EP4 和 EP8,所以它们均被取消激活。
EP2CFG = 0xA0; //out 512 bytes, 4x, bulk
SYNCDELAY;
EP6CFG = 0xE0; // in 512 bytes, 4x, bulk
SYNCDELAY;
EP4CFG = 0x02; //clear valid bit
SYNCDELAY;
EP8CFG = 0x02; //clear valid bit
SYNCDELAY;
- 复位 FIFO。
FIFORESET = 0x80; // activate NAK-ALL to avoid race conditions
SYNCDELAY; // see TRM section 15.14
FIFORESET = 0x02; // reset, FIFO 2
SYNCDELAY; //
FIFORESET = 0x04; // reset, FIFO 4
SYNCDELAY; //
FIFORESET = 0x06; // reset, FIFO 6
SYNCDELAY; //
FIFORESET = 0x08; // reset, FIFO 8
SYNCDELAY; //
FIFORESET = 0x00; // deactivate NAK-ALL
SYNCDELAY;
- 分别将端点 2 FIFO 和端点 6 配置为自动输出模式和自动输入模式,同时使用 16 位接口。
EP2FIFOCFG = 0x00; // AUTOOUT=0, WORDWIDE=0
// core needs to see AUTOOUT=0 to AUTOOUT=1 switch to arm endp's
SYNCDELAY; //
EP2FIFOCFG = 0x11; // AUTOOUT=1, WORDWIDE=1
SYNCDELAY; //
EP6FIFOCFG = 0x0D; // AUTOIN=1, ZEROLENIN=1, WORDWIDE=1
SYNCDELAY;
TD_Poll
在 fw.c 文件的无限循环中调用了 TD_Poll。因为EP2和EP6配置为自动输出和输入模式,所以不必要添加代码进行手动操作。
2.3 FPGA代码
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; entity fpga_master is
Port (
fdata : inout STD_LOGIC_VECTOR( downto ); -- FIFO data lines.
faddr : out STD_LOGIC_VECTOR( downto ); -- FIFO select lines
slrd : out STD_LOGIC; -- Read control line
slwr : out STD_LOGIC; -- Write control line
gstate : out STD_LOGIC_VECTOR( downto ); -- debug lines flagd : in STD_LOGIC; --EP6 full flag
flaga : in STD_LOGIC; --EP2 empty flag
clk : in STD_LOGIC; --Interface Clock
sloe : out STD_LOGIC --Slave Output Enable control
);
end fpga_master; architecture rtl of fpga_master is signal faddr_i : STD_LOGIC_VECTOR( downto ); signal slrd_i : STD_LOGIC;
signal slwr_i : STD_LOGIC; signal gstate_i : STD_LOGIC_VECTOR( downto ); signal MasterState : STD_LOGIC_VECTOR( downto ); -- Counter to sequence the fifo signals. signal sloe_i : STD_LOGIC; shared variable cnt : integer range to := ; CONSTANT A: STD_LOGIC_VECTOR ( DownTo ) := "";
CONSTANT B: STD_LOGIC_VECTOR ( DownTo ) := "";
CONSTANT C: STD_LOGIC_VECTOR ( DownTo ) := "";
CONSTANT D: STD_LOGIC_VECTOR ( DownTo ) := "";
CONSTANT E: STD_LOGIC_VECTOR ( DownTo ) := "";
CONSTANT F: STD_LOGIC_VECTOR ( DownTo ) := "";
CONSTANT G: STD_LOGIC_VECTOR ( DownTo ) := "";
CONSTANT H: STD_LOGIC_VECTOR ( DownTo ) := "";
begin slrd <= slrd_i;
slwr <= slwr_i;
faddr <= faddr_i;
gstate<= gstate_i;
sloe <= sloe_i; process(clk) variable fdatawe : natural := ;
variable fifodatabyte : STD_LOGIC_VECTOR( downto ) := ""; -- Local for now. begin
if(rising_edge(clk)) then case MasterState( downto ) is when A => -- IDLE STATE sloe_i <= '';
faddr_i <= "";
slrd_i <= '';
slwr_i <= '';
MasterState <= E;
fdatawe := ;
gstate_i <= ""; when E => faddr_i <= "";
slrd_i <= '';
sloe_i <= '';
if (flagd = '') then -- if Full flag is in a deasserted state
slwr_i <= ''; --assert slave write control signal
fdatawe := ;
fdata <= fifodatabyte;
fifodatabyte := fifodatabyte + '';
MasterState <= E; -- stay in state E
else
slwr_i <= '';
MasterState <= A; --when Full flag gets asserted, move to state A end if; gstate_i <= ""; when others =>--if an undefined state move to IDLE faddr_i <= ""; slrd_i <= '';
sloe_i <= '';
slwr_i <= ''; gstate_i <= "";
MasterState <= A;
end case;
end if;
end process;
end rtl;
3 总结
CYPRESS提供了FX2LP的固件框架,使得固件开发只需修改TD_Init和TD_Poll(如果采用中断,那就修改中断函数)两个函数即可,大大缩短了开发时间。
USB小白学习之路(8)FX2LP cy7c68013A——Slave FIFO 与FPGA通信(转)的更多相关文章
- USB小白学习之路(10) CY7C68013A Slave FIFO模式下的标志位(转)
转自良子:http://www.eefocus.com/liangziusb/blog/12-11/288618_bdaf9.html CY7C68013含有4个大端点,可以用来处理数据量较大的传输, ...
- USB小白学习之路(12) Cy7c68013A固件之Slave FIFO(转)
Cy7c68013固件之Slave FIFO 转自:http://blog.csdn.net/zengshaoqing/article/details/53053539 选择SlaveFIFO传输方式 ...
- USB小白学习之路(11) Cy7c68013A驱动电路设计注意事项(转)
Cy7c68013A驱动电路设计注意事项 转自:http://group.chinaaet.com/116/79029#0-tsina-1-71467-397232819ff9a47a7b7e80a4 ...
- USB小白学习之路(3) 通过自定义请求存取外部RAM
通过自定义请求存取外部RAM 1. 实验简述 此实验是对自定义的供应商特殊命令(vendor specific command bRequest = 0xA3)进行解析,程序中的read me说明如下 ...
- USB小白学习之路(1) Cypress固件架构解析
Cypress固件架构彻底解析及USB枚举 1. RAM的区别 56pin或者100pin的cy7c68013A,只有内部RAM,不支持外部RAM 128pin的cy7c68013A在pin脚EA=0 ...
- USB小白学习之路(6) IIC EEPROM读取解析
IIC EEPROM读取解析 1. 编译错误处理(这里可以忽略) 在解压包解压了程序后,直接编译,出现如下错误. *** WARNING L14: INCOMPATIBLE MEMORY MODEL ...
- USB小白学习之路(5) HID鼠标程序
HID鼠标程序 1. 特别注意 需要特别注意,各个例程中的设备描述符,配置描述符等各种描述符都是已经配置好了的,我们需要做的只是在例程中将代码修改为自己需要的部分即可,一般情况下是不可以串搭配的. 2 ...
- USB小白学习之路(4)HID键盘程序
HID键盘程序 1. 特别注意 需要特别注意,各个例程中的设备描述符,配置描述符等各种描述符都是已经配置好了的,我们需要做的只是在例程中将代码修改为自己需要的部分即可,一般情况下是不可以串搭配的. 2 ...
- USB小白学习之路(2)端点IN/OUT互换
端点2(out)和端点6(in)的out_in互换 注:这里的out和in都是以host为标准说的,out是host的out,在设备(Cy7c68013)这里其实是输入端口:in是host的in,在设 ...
随机推荐
- SpringBoot 1.5.x 集成 Quartz 任务调度框架
Quartz 有分 内存方式 和 数据库方式 内存方式任务信息保存在内存中, 停机会丢失, 需手动重新执行, 数据库方式: 任务信息保存在数据库中, 重点是支持集群. 内存方式 RAMJobStore ...
- Opencv笔记(十五)——图像金字塔
参考文献 目标 学习图像金字塔 学习函数cv2.pyrUp()和cv2.pyrDown() 原理 当我们需要将图像转换到另一个尺寸的时候, 有两种可能,一种是放大图像,另一种是缩小图像.尽管在Open ...
- 算法笔记 4.4 贪心 问题 A: 看电视
问题 A: 看电视 题目描述 暑假到了,小明终于可以开心的看电视了.但是小明喜欢的节目太多了,他希望尽量多的看到完整的节目. 现在他把他喜欢的电视节目的转播时间表给你,你能帮他合理安排吗? 输入 输入 ...
- 扩展 ajaxupload.js ,支持客户端判断上传文件的大小
onSubmit: function(file, extension){}, 修改为 onSubmit: function(file, extension, size){}, if (! (setti ...
- Minimum Sum
题目描述 One day, Snuke was given a permutation of length N, a1,a2,…,aN, from his friend. Find the follo ...
- android形状属性、锁屏密码、动态模糊、kotlin项目、抖音动画、记账app、视频播放器等源码
Android精选源码 直观了解Android的"形状"属性如何影响Drawable的外观. 一个灵活的视频播放器, 可替换播放器内核. android锁屏输入密码功能源码 背景动 ...
- matplotlib.pyplot.contour 简单等高线绘制
contour(X, Y, Z) X,Y是与Z形状相同的二维数组,可以通过 numpy.meshgrid()创建. numpy.meshgrid()----从坐标向量返回坐标矩阵 生成的x,y坐标矩阵 ...
- Leetcode13_罗马数字转整数
题目 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1. ...
- 前端之css引入方式/长度及颜色单位/常用样式
1.css三种引入方式 <!DOCTYPE html><html><head> <meta charset="UTF-8"> < ...
- JavaWeb防注入知识点(一)
一.防sql注入办法 在apache commons-lang(2.3以上版本)中为我们提供了一个方便做转义的工具类,主要是为了防止sql注入,xss注入攻击的功能.总共提供了以下几个方法: 1.es ...