第一次玩博客也不知道该写什么,正好这几天在折腾一块USB数据采集板的程序,那就写一下最近调试CY7C68013遇到的一些问题吧。
自己做了一块GPS中频数据采集板,CY7C68013的作用就是把AD采样后的GPS中频数据通过USB传给PC,大致结构是这样的:
MAX2769(GPS射频前端芯片,包括2bit的ADC) -> EP2C5T144(FPGA,外挂了一片512KBYTE的SRAM) -> CY7C68013
由于是第一次用CY7C68013,调试花了很长的时间(尽管代码很少),每当芯片工作不正常时,只能通过极少的信息去猜测问题原因。
在这个设计中,我最初采用了SLAVE FIFO模式下同步写的方式传输数据(AUTOIN),由FPGA提供时钟IFCLK,BULK传输,
我第一个遇到的问题是AUTOIN模式没有开启,现象是当FIFO FULL信号(FLAGB拉低)有效后除非我复位FIFO,不然FIFO一直保持FULL状态,上位机程序读不到任何数据,因此我认为芯片在FIFO写满后没有打包发送出去,这也说明AUTOIN没有启动。由于AUTOIN是通过EPXFIFOCFG设置的,EP2FIFOCFG = EP2FIFOCFG | 0x08 (在这里我用的是端点2),为了进一步验证我的猜测,我在BOOL DR_VendorCmnd(void)函数里里加了一个寄存器读写的Vendor Request,代码如下:
1 switch(SETUPDAT[1]){
2 case ...:
3 ...; break;
4
5 case VR_REG_WR:
6 index = SETUPDAT[4];
7 index |= SETUPDAT[5] << 8;
8 EP0BCH = 0;
9 EP0BCL = 0;
10 while(EP0CS & bmEPBUSY);
11 valueL = *EP0BUF;
12 valueL |= *(EP0BUF+1) << 8;
13 value = *(EP0BUF+2);
14 value |= *(EP0BUF+3) << 8;
15
16 writeReg(index, value, valueL);
17 EP0CS |= bmHSNAK;
18 break;
19
20 case VR_REG_RD:
21 index = SETUPDAT[4];
22 index |= SETUPDAT[5] << 8;
23 value = readReg(index);
24 *EP0BUF = value & 0x00FF;
25 *(EP0BUF+1) = value >> 8;
26 EP0BCH = 0;
27 EP0BCL = 2; // Arm endpoint with # bytes to transfer
28 EP0CS |= bmHSNAK;
29 break;
30
31 case ...:
32 ...; break;
33 }
writeReg和readReg这两个函数要做的事情及时读写寄存器或变量,这样就可以通过自己的上位机程序观察CY7C68013的寄存器了。在完成这一步之后,就可以观察EP2FIFOCFG这个寄存器了,结果发现AUTOIN真的没有被启动,即EP2FIFOCFG的bit4没有被置位。这个问题很奇怪,就算是复制官方的参考初始化代码也不行,另外跟FIFO功能有关的EPxFIFOFLGS寄存器也不能被设置,即写寄存器后马上读出来发现寄存器值未变,但是IFCONFIG和EP2CFG这两个寄存器是可以被修改的。接下来我注意到一个问题,在板子上电之后,如果先配置FPGA(此时FPGA已经开始输出IFCLK)后下载固件则会出现上述问题,而先下载CY7C68013固件再配置FPGA就能够正常传输数据。注意到IFCLK的这个情况后,我修改了FPGA的代码,在CY7C68013发出开始传输指令(一个PIN上出现下降沿)之前FPGA不会输出IFCLK,这样在两种配置顺序下都可以正常传输了。
导致这个问题的真正原因我还不知道,或许是代码还存在问题,也可能是芯片BUG(说不定买到了次品),总之外部IFCLK输入很有可能导致芯片工作异常。
现在我已经改用了异步写FIFO方式,FPGA代码改动不大,同时也避开了IFCLK的问题(折腾了一周,真心怕了...)。
接下来再说一个粗心导致的错误。在CY7C68013初始化的时候,我不小心将:
1 EP2AUTOINLENH = 0x02;
2 SYNCDELAY;
3 EP2AUTOINLENL = 0x00;
4 SYNCDELAY;
错写成:
1 EP2AUTOINLENH = 0x02;
2 SYNCDELAY;
3 EP2AUTOINLENH = 0x00;
4 SYNCDELAY;
又因为芯片默认ZEROLENIN是开启的(在EP2FIFOCFG里设置),导致我的PC程序一直读到空包。
另外,由于我将FIFO的SLWR信号的极性弄反了,同样导致了一个现象很奇怪的错误。芯片上初始化后FIFO非满(FLAGB高),然后我用错误的SLWR信号“写满”了FIFO(FLAGB置低),在我确定已经开启了AUTOIN的情况下,芯片不会自动打包发送,并且FLAGB会一直保持低电平(就算是重置FIFO也不行,除非板子重新上电)。
总之折腾手上这片CY7C68013花了太多时间,调试方式的限制以及出现错误时会出现各种奇怪的现象,让我的调试过程很痛苦。。。。
玩这个芯片要注意,虽然固件代码很简单很少,但是弄错一点细节都会导致很奇怪的现象出现。。。。