Xilinx spartan race6 系列 FPGA 的SPI FLASH 接口问题

CY68013是一款USB 2.0芯片,常用作fpga与pc的接口芯片,其硬件可以自动处理USB协议,也可以在里面下载对应的固件程序,由固件程序来完成USB协议的通信。我们只关心USB数据的传输,协议的不作深究,能用就行。

fx2的电气特性,相当于DataSheet,slave fifo各个控制信号的时序图在这份文档中有写
实际上是TRM的翻译,翻得通俗一点
这个是一款飞利浦的USB PHY芯片的参考书,USB协议需要自己处理,有助于理解USB的专业术语的含义及协议

一个是开发固件程序的,里面自带了一个简化版的Keil;另一个是开发上位机软件的,还包含了Cypress默认的驱动程序、API库等等。安装的时候最好默认都安装在C盘下,会省很多麻烦。

安装上驱动以后,可以使用库函数来和fx2芯片进行通讯。
需要修改 cyusb.inf 文件来安装对应的驱动

;在这里添加对应于自己的VID PID的描述

如果连接了eeprom,上电会从eeprom里面启动,已经配置了寄存器;
启动后再下载程序到RAM中运行,寄存器又被配置了一遍,但是这样可能会受到第一次配置的影响,USB通信出现问题。
一般是用哪一位就配置哪一位,其余的寄存器的bit保留原值。

这样其余像 bit7->1 都是保留原值,可能会被第一次配置干扰。

cy7c68013都搭配有eeprom,eeprom里面存的程序,上电启动的时候,先把程序从eeprom加载到内部ram中,即FFF的区域,然后才开始运行;注意与USB相关的寄存器配置以及EP buffer都在上面0xE200-0xFFFF区域!!!这个区域不会有程序,也就是说程序下载的时候不会覆盖到这片区域。初始程序启动后,对usb相关寄存器进行了配置,然后连上usb,驱动配合脚本自动下载固件,这个固件被下载到0xFFF区域去执行,不会覆盖0xE200-0xFFFF区域的USB急促安琪和EP buffers,下载期间不会断电。新下载的固件启动执行,对USB regs 和EP buffers进行操作,但是只是改变指定位的数据,其他设置保留eeprom中初始程序的USB寄存器设置,所以会发现,新固件的代码功能并没有提现出来或者说不正常!!! 直接把程序烧写到eeprom就可以了!!!

上电从eeprom加载程序运行

下载程序到eeprom中造成USB通信异常的案例
一开始的时候,向CY68013的eepron里下载程序,能和pc通信上,只是数据有些不正常;
修改程序以后,重新下载程序到CY68013的eeprom中,再上电,pc提示无法识别的usb设备

usb根本没有通信上!!!!

最后一个版本的程序下载进去有问题,即eeprom里的程序有问题,
然后又每次是通过eeprom来启动,
加载程序运行,然后每次枚举都不成功,所以显示未知设备

最关键的是要擦除eeprom里的原程序,然后更新为新程序即可。

还好,在Crazy Bingo的博客上找到了解决方案:
EZ_USB手册上如是说:

EEPROM是可以配置地址的,A2,A1,A0就是用来配置地址的,而fx2只认 001 的地址,
只要改变了eeprom的地址,eeprom就会失效,fx2就无法从eeprom加载程序,只能硬件回复usb请求

1)先短路J13,使得A0变低
2)usb连接到pc,检测到usb设备,驱动无法自动安装
4)断开J13,使A0变高电平

注意,.a51的文件描述符是用来上报给pc机的,用库函数获取到的描述符都是从这个.a51里来的
相当于这个文件决定了跟pc报告说我有哪些端点,以及端点的大小
.a51文件必须和fx2真正在运行时配置的端点一致才可以,否则会造成,上位机调用库函数和fx2通讯不上

HighSpeedConfigDscr里面需要改成4个端点的,而且下面要写4个端点的描述符!!

端点大小是缓存区的大小,2和6可以配置为512 和 1024两种

2.1.2.5 芯片没办法软件复位!!!!

如果端点fifo满了,仍旧连续发送,芯片会挂点,软件复位没有用,必须重新上电,hard reset!!!

 
 
 
 
 
上下两段换一下先OUTPKTEND 然后再 FIFORESET就会出现上面说的问题

 

 
 

 

 
这里只采用同步读写的方式!!!
读:
ToeOn 以后的数据才是有效的数据。
写:
最坏情况下,写入以后,满的FLAGS需要13.5ns才能出来,超过周期的一半了,得等到下降沿以后才能检测到IN FIFO满

 

 
 

一开始以为是fifo里面有缓存,而且因为配置的是512 x4大小,所以收到了512 x4的 0x00 实际上是fpga实际一直控制在写00 00
用万用表来测量fx2的slwr脚一直显示为0V!!!
后来发现,fpga管脚锁错了!!!!!!没有把slwr脚锁到对应的fx2的slwr脚,造成了slave fifo的异常写入
心中千万只草泥马呼啸而过………………
 
发送短包要拉低pkt_end信号脚,但什么时候拉低,某不知名网友说:
 



尝试pkt_end <= ‘1’; 每次等齐512字节自动发送的话,这样子,flagd就是正常的。
估计是pkt_end的操作有问题


还有TRM里的一句说明


修改后重新下载,实验结果符合预期,能够正常收到短包数据,每次7个16bit数据;
Bulk in failed是故意尝试只让fpga发一次,pc机上请求读取两次中的第二次,返回失败是正常的,因为fifo里确实没有数据了。

另外注意一点,EP6FIFOCNT看起来一直为0,实际上含义不一样,只要pkt_end以后,EP6FIFOCNT就会被清0,说这些数据已经被打包出去了,但是实际还是占用空间的,FIFO的flag该是Full还是full,所以会出现EP6 为Full,但是EP6FIFOCNT= 0。
超过512bytes用pktend发送出现问题:
开启短包发送,但是fpga发送超过512字节给pc的时候出现问题,会收到两个512字节数据,后面的512字节是一串乱码
原因:
fx2程序中开了autoin,然后fpga发送端又有pkt_end拉低一个周期造成的矛盾,到了512字节已经autoin发送了,然后由pkt_end发送一遍,第二遍的时候发送的不知道是什么数据

 

 

连续发9个512byte过去,然后收到的数据并不完整,收到第5包,后面的数据就没有了(工程关闭ep6 autoin,无论是长包还是短包,都是用pkt_end来驱动发送的
ep6fifocnt 一直为2
通过chipscope观察,发现死在了read_sig状态

实际上是因为fpga内部fifo提前发出了full信号,即没到1024就发出了full信号,导致没法把存在EP2OUT端点的6,7,8,9包数据全部都写入fpga内部fifo,还剩了2个byte数据在EP2OUT内,EP2OUT数据又没读空,死在read状态过不去,状态又没法跳转。
修正后,只能读到7包数据,最后两个数还不对,变成了08

发现第7包的前两个字节会丢
在第七包只发了两个字节4C4B的情况下,什么也收不到
chipscope

dout能看到有4C4B说明确实这个值是写入到fpga的fifo中的,但是从fifo中读出然后写入到fx2的slave fifo中是有问题的。
关键的关键是,EP6IN fifo满的时候,按照检测flagd然后控制rden,又由fifo返回的valid信号来驱动slwr_n, 就会造成少写入一个数据到EPIN6
数据通路分析:
EP2OUT 到 fpga内部fifo:
在往fpga内部fifo写的时候,fpga内部fifo会提前一个单元给出fifo满信号,这样会导致有一个单元的数据,这里对应2bytes数据,残留在EPOUT FIFO中,得等到pc把EPIN fifo的数据读掉一些,然后fpga内部fifo释放出来一些空间,才会把EPOUT的残留数据读出来写入fpga内部fifo。但是这个并不影响最终pc接收的情况,因为看起来还是和原来一样512bytes取出来。
fpga内部fifo 到EP6IN:
就是前面关键的关键分析的

 

2.2.2.1 同步电路外面加一层逻辑电路保护,保证不会误读出来然后没人接收

 
 

 
fdata_in专门用作输入,真实值 或者 0
data_out专门用作输出,真实值 或者 0
 
 
 

 
 


一个数 Num = 0x0708;
全部是以高字节在高地址来画的表格,字节数变大时间在后

Num2 和 Num1 的关系为,高低字节倒序排列,然后每16bit内部两字节交换。
想要输入Num 和 读出来的 Num2相等,
必须先对 Num 作 高低字节倒序排列,然后每16bit内部两字节交换

红色线段表示非稳定状态,数值状态为未知,可能的原因如下
② inout口处理不当,两端同时进行out输出造成不稳定状态

这个问题肯定是因为输给chipscope的时钟没有跑起来!!!
有一些复位信号的原因,外部复位信号没有锁定也没有赋值,可能就接到pll的rst上,导致一直在复位,时钟就没有跑起来

今天碰到一个很奇怪的现象,原来的工程死活就不行,fpga程序一烧进去,就收到一大坨数据,EP6直接满了,EP8也有数据,特别奇怪!!!后来换了一个工程就好了

这个函数 IN 和 OUT端点都可以用的, bulkin的话就是接收,bulkout就是发送

1)控制端点操作不成功

一个是因为地址不对,另一个是因为长度不对,length必须是LONG,然后如果有连续的函数套用,必须把长度设成可更改的引用,LONG &lenth,否则会返回失败。

2)上位机短包发送限制

每一个短包实际上占用了一个buffer缓冲,512x4 16bit的端点配置,一共就只能发送4次短包就会满
每次发送12字节,只能发送4次,再发送就失败了!!!!
而且一旦出现发送失败,无论是软件复位还是其他什么的都不好使!!!必须重新上电才可以!!!

要注意,无论是发还是收,都是小端序。
另外pc机内部于是小端序,所以

然后outbuf发送,在fpga端收到的就是0x0403,正好和发送的时候的数据是一样的!!!

CY68013是一款USB 2.0芯片,常用作fpga与pc的接口芯片,其硬件可以自动处理USB协议,也可以在里面下载对应的固件程序,由固件程序来完成USB协议的通信。我们只关心USB数据的传输,协议的不作深究,能用就行。

fx2的电气特性,相当于DataSheet,slave fifo各个控制信号的时序图在这份文档中有写
实际上是TRM的翻译,翻得通俗一点
这个是一款飞利浦的USB PHY芯片的参考书,USB协议需要自己处理,有助于理解USB的专业术语的含义及协议

一个是开发固件程序的,里面自带了一个简化版的Keil;另一个是开发上位机软件的,还包含了Cypress默认的驱动程序、API库等等。安装的时候最好默认都安装在C盘下,会省很多麻烦。

安装上驱动以后,可以使用库函数来和fx2芯片进行通讯。
需要修改 cyusb.inf 文件来安装对应的驱动

;在这里添加对应于自己的VID PID的描述

如果连接了eeprom,上电会从eeprom里面启动,已经配置了寄存器;
启动后再下载程序到RAM中运行,寄存器又被配置了一遍,但是这样可能会受到第一次配置的影响,USB通信出现问题。
一般是用哪一位就配置哪一位,其余的寄存器的bit保留原值。

这样其余像 bit7->1 都是保留原值,可能会被第一次配置干扰。

cy7c68013都搭配有eeprom,eeprom里面存的程序,上电启动的时候,先把程序从eeprom加载到内部ram中,即FFF的区域,然后才开始运行;注意与USB相关的寄存器配置以及EP buffer都在上面0xE200-0xFFFF区域!!!这个区域不会有程序,也就是说程序下载的时候不会覆盖到这片区域。初始程序启动后,对usb相关寄存器进行了配置,然后连上usb,驱动配合脚本自动下载固件,这个固件被下载到0xFFF区域去执行,不会覆盖0xE200-0xFFFF区域的USB急促安琪和EP buffers,下载期间不会断电。新下载的固件启动执行,对USB regs 和EP buffers进行操作,但是只是改变指定位的数据,其他设置保留eeprom中初始程序的USB寄存器设置,所以会发现,新固件的代码功能并没有提现出来或者说不正常!!! 直接把程序烧写到eeprom就可以了!!!

上电从eeprom加载程序运行

下载程序到eeprom中造成USB通信异常的案例
一开始的时候,向CY68013的eepron里下载程序,能和pc通信上,只是数据有些不正常;
修改程序以后,重新下载程序到CY68013的eeprom中,再上电,pc提示无法识别的usb设备

usb根本没有通信上!!!!

最后一个版本的程序下载进去有问题,即eeprom里的程序有问题,
然后又每次是通过eeprom来启动,
加载程序运行,然后每次枚举都不成功,所以显示未知设备

最关键的是要擦除eeprom里的原程序,然后更新为新程序即可。

还好,在Crazy Bingo的博客上找到了解决方案:
EZ_USB手册上如是说:

EEPROM是可以配置地址的,A2,A1,A0就是用来配置地址的,而fx2只认 001 的地址,
只要改变了eeprom的地址,eeprom就会失效,fx2就无法从eeprom加载程序,只能硬件回复usb请求

1)先短路J13,使得A0变低
2)usb连接到pc,检测到usb设备,驱动无法自动安装
4)断开J13,使A0变高电平

注意,.a51的文件描述符是用来上报给pc机的,用库函数获取到的描述符都是从这个.a51里来的
相当于这个文件决定了跟pc报告说我有哪些端点,以及端点的大小
.a51文件必须和fx2真正在运行时配置的端点一致才可以,否则会造成,上位机调用库函数和fx2通讯不上

HighSpeedConfigDscr里面需要改成4个端点的,而且下面要写4个端点的描述符!!

端点大小是缓存区的大小,2和6可以配置为512 和 1024两种

2.1.2.5 芯片没办法软件复位!!!!

如果端点fifo满了,仍旧连续发送,芯片会挂点,软件复位没有用,必须重新上电,hard reset!!!

 
 
 
 
 
上下两段换一下先OUTPKTEND 然后再 FIFORESET就会出现上面说的问题

 

 
 

 

 
这里只采用同步读写的方式!!!
读:
ToeOn 以后的数据才是有效的数据。
写:
最坏情况下,写入以后,满的FLAGS需要13.5ns才能出来,超过周期的一半了,得等到下降沿以后才能检测到IN FIFO满

 

 
 

一开始以为是fifo里面有缓存,而且因为配置的是512 x4大小,所以收到了512 x4的 0x00 实际上是fpga实际一直控制在写00 00
用万用表来测量fx2的slwr脚一直显示为0V!!!
后来发现,fpga管脚锁错了!!!!!!没有把slwr脚锁到对应的fx2的slwr脚,造成了slave fifo的异常写入
心中千万只草泥马呼啸而过………………
 
发送短包要拉低pkt_end信号脚,但什么时候拉低,某不知名网友说:
 



尝试pkt_end <= ‘1’; 每次等齐512字节自动发送的话,这样子,flagd就是正常的。
估计是pkt_end的操作有问题


还有TRM里的一句说明


修改后重新下载,实验结果符合预期,能够正常收到短包数据,每次7个16bit数据;
Bulk in failed是故意尝试只让fpga发一次,pc机上请求读取两次中的第二次,返回失败是正常的,因为fifo里确实没有数据了。

另外注意一点,EP6FIFOCNT看起来一直为0,实际上含义不一样,只要pkt_end以后,EP6FIFOCNT就会被清0,说这些数据已经被打包出去了,但是实际还是占用空间的,FIFO的flag该是Full还是full,所以会出现EP6 为Full,但是EP6FIFOCNT= 0。
超过512bytes用pktend发送出现问题:
开启短包发送,但是fpga发送超过512字节给pc的时候出现问题,会收到两个512字节数据,后面的512字节是一串乱码
原因:
fx2程序中开了autoin,然后fpga发送端又有pkt_end拉低一个周期造成的矛盾,到了512字节已经autoin发送了,然后由pkt_end发送一遍,第二遍的时候发送的不知道是什么数据

 

 

连续发9个512byte过去,然后收到的数据并不完整,收到第5包,后面的数据就没有了(工程关闭ep6 autoin,无论是长包还是短包,都是用pkt_end来驱动发送的
ep6fifocnt 一直为2
通过chipscope观察,发现死在了read_sig状态

实际上是因为fpga内部fifo提前发出了full信号,即没到1024就发出了full信号,导致没法把存在EP2OUT端点的6,7,8,9包数据全部都写入fpga内部fifo,还剩了2个byte数据在EP2OUT内,EP2OUT数据又没读空,死在read状态过不去,状态又没法跳转。
修正后,只能读到7包数据,最后两个数还不对,变成了08

发现第7包的前两个字节会丢
在第七包只发了两个字节4C4B的情况下,什么也收不到
chipscope

dout能看到有4C4B说明确实这个值是写入到fpga的fifo中的,但是从fifo中读出然后写入到fx2的slave fifo中是有问题的。
关键的关键是,EP6IN fifo满的时候,按照检测flagd然后控制rden,又由fifo返回的valid信号来驱动slwr_n, 就会造成少写入一个数据到EPIN6
数据通路分析:
EP2OUT 到 fpga内部fifo:
在往fpga内部fifo写的时候,fpga内部fifo会提前一个单元给出fifo满信号,这样会导致有一个单元的数据,这里对应2bytes数据,残留在EPOUT FIFO中,得等到pc把EPIN fifo的数据读掉一些,然后fpga内部fifo释放出来一些空间,才会把EPOUT的残留数据读出来写入fpga内部fifo。但是这个并不影响最终pc接收的情况,因为看起来还是和原来一样512bytes取出来。
fpga内部fifo 到EP6IN:
就是前面关键的关键分析的

 

2.2.2.1 同步电路外面加一层逻辑电路保护,保证不会误读出来然后没人接收

 
 

 
fdata_in专门用作输入,真实值 或者 0
data_out专门用作输出,真实值 或者 0
 
 
 

 
 


一个数 Num = 0x0708;
全部是以高字节在高地址来画的表格,字节数变大时间在后

Num2 和 Num1 的关系为,高低字节倒序排列,然后每16bit内部两字节交换。
想要输入Num 和 读出来的 Num2相等,
必须先对 Num 作 高低字节倒序排列,然后每16bit内部两字节交换

红色线段表示非稳定状态,数值状态为未知,可能的原因如下
② inout口处理不当,两端同时进行out输出造成不稳定状态

这个问题肯定是因为输给chipscope的时钟没有跑起来!!!
有一些复位信号的原因,外部复位信号没有锁定也没有赋值,可能就接到pll的rst上,导致一直在复位,时钟就没有跑起来

今天碰到一个很奇怪的现象,原来的工程死活就不行,fpga程序一烧进去,就收到一大坨数据,EP6直接满了,EP8也有数据,特别奇怪!!!后来换了一个工程就好了

这个函数 IN 和 OUT端点都可以用的, bulkin的话就是接收,bulkout就是发送

1)控制端点操作不成功

一个是因为地址不对,另一个是因为长度不对,length必须是LONG,然后如果有连续的函数套用,必须把长度设成可更改的引用,LONG &lenth,否则会返回失败。

2)上位机短包发送限制

每一个短包实际上占用了一个buffer缓冲,512x4 16bit的端点配置,一共就只能发送4次短包就会满
每次发送12字节,只能发送4次,再发送就失败了!!!!
而且一旦出现发送失败,无论是软件复位还是其他什么的都不好使!!!必须重新上电才可以!!!

要注意,无论是发还是收,都是小端序。
另外pc机内部于是小端序,所以

然后outbuf发送,在fpga端收到的就是0x0403,正好和发送的时候的数据是一样的!!!

我要回帖

更多关于 spartan 的文章

 

随机推荐