CY7C68013 + FPGA 调试中碰到的怪问题.
使用的端点:EP2 OUT, EP6 IN。 4倍缓存,512字节长。使用驱动:早期 EZUSB驱动
碰到的问题是这样的:现象EP2空的时候,HOST发送数据给FX2 的时候,系统死锁。 主要 是SLAVEFIFO写入大批量数据后,主机发送第四个OUT包死锁。
以为EP2没有ARM,但四 查看了EP2468STAT = 0x99, EP2CS = 0x04;可以排除应用程序的问题,因为我用BUSHOUND调试,也死锁。
还有什么寄存器可以检查吗?
void TD_Init(void) // Called once at startup
{
//--CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ;
CPUCS = bmCLKSPD1; //++. CLKOUT = 48MHz, disable CLKOUT output, portc rd#/wr# disabled.
IFCONFIG = 0xA3; //++.
CKCON |= 0x12; //++. T2M=0; T1M=1; T0M=0; note external memory stretch is defined in fx2.h and set at fw.c
WAKEUPCS = 0x00; //++ disable WU2EN, disable DPEN to disable USB resume.
PORTACFG = 0x40; //++. PA.0/1 is input IO,PA.7 is SLCS.
OEA = 0x08; //++ PA3 is output.
IOA = 0x00; //++ PA3 will will output 0 to reset local CPLD.
I2CTL = 0x01; //++ set IIC 400KHz
// Registers which require a synchronization delay, see section 15.14
// 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 been replaced by GPIFTC registers
// default: all endpoints have their VALID bit set
// default: TYPE1 = 1 and TYPE0 = 0 --> BULK
// default: EP2 and EP4 DIR bits are 0 (OUT direction)
// default: EP6 and EP8 DIR bits are 1 (IN direction)
// default: EP2, EP4, EP6, and EP8 are double buffered
// REVCTL = 0x00; //++.
// SYNCDELAY;
EP1OUTCFG = 0x30; //++. EP1OUT invalid, type is interrupt
SYNCDELAY;
EP1INCFG = 0xb0; //++. EP1IN valid, type is interrupt
SYNCDELAY;
EP2CFG = 0xA0; //++. EP2: valid, OUT, bulk, 512byte packet size, quad buffering. 20091118
SYNCDELAY;
EP4CFG = 0x20; //++. EP4 invalid,
SYNCDELAY;
EP6CFG = 0xE0; //++. EP6: valid, IN, bulk, 512byte packet size, quad buffering
SYNCDELAY;
EP8CFG = 0x20; //++. EP8: invalid
SYNCDELAY;
//reset all FIFO
FIFORESET = 0x80;
SYNCDELAY;
FIFORESET = 0x02;
SYNCDELAY;
FIFORESET = 0x06;
SYNCDELAY;
FIFORESET = 0x00;
SYNCDELAY;
EP2FIFOCFG = 0x01; //EP2 AUTOOUT=0; AUTOIN=0; slave fifo width is 16bit. 20091118
SYNCDELAY;
EP6FIFOCFG = 0x09; //EP6 auto in, slave fifo wide is 16bit.
SYNCDELAY;
// Now EP2 is quad buffer
EP2BCL = 0x80; // arm EP2OUT by writing byte count w/skip.
SYNCDELAY;
EP2BCL = 0x80;
SYNCDELAY;
EP2BCL = 0x80;
SYNCDELAY;
EP2BCL = 0x80;
SYNCDELAY;
PINFLAGSAB = 0x8e; //FLAGA is EP6 full flag; FLAGB is empty flag of EP2. 20091118
SYNCDELAY;
FIFOPINPOLAR = 0x03; //PKTEND,SLOE,SLWR,SLRD are low active, FE,FF is high active
SYNCDELAY;
// enable dual autopointer feature
AUTOPTRSETUP |= 0x01;
} 你后面的要取数据啊。否则不死锁才怪。 数据都被FPGA取走了。附件是图片。
黄线上方是FPGA取走的OUT数据,下面三个OUT包是写到FX2的EP2端点的,也确实是接受到了, 但是下面再想写入OUT包死锁。
这个时候的状态是这样的,EP2467STAT显示EP2空,Firmware 死在
while (EP2468STAT & bmEP2EMPTY) 这里,然而HOST端却死在DeviceIOControl ( EP2OUT ).。 我测量了下 EP2的EMPTY指示管脚好像是FLAGB,发现是非空。 问题是这样的情况不是每次出现,前面已经正确传输了好几个回合了。
wye11083 发表于 2012-8-29 10:40 static/image/common/back.gif
你后面的要取数据啊。否则不死锁才怪。
wye11083 能帮忙一下吗 while (EP2468STAT & bmEP2EMPTY)应写为while(!(EP2468STAT & bmEP2EMPTY))才行。再一个,每收到一个包就要确认一下。 能把你的QQ发信息告诉我吗? wye11083 发表于 2012-8-29 15:58 static/image/common/back.gif
while (EP2468STAT & bmEP2EMPTY)应写为while(!(EP2468STAT & bmEP2EMPTY))才行。再一个,每收到一个包就要 ...
WYE11083 兄, 帮我分析下, 以下是TD_POLL代码, 主机发送三种命令,CBW_CMD_RED_REG,CBW_CMD_WRITE_REG, CBW_CMD_WRITE_DATA .
其中, 前面两个是端点接受或者发送数据。 最后一个命令,是SLAVEFIFO方式,FX2 接受批量数据给FPGA, CPU不干预。
现在的问题是, SLAVEFIFO后,传输不正常了, 就是我前面说的问题。。。
void TD_POLL()
{
if(!(EP2468STAT & bmEP2EMPTY))//检查EP2是否有数据
{
count_low = EP2BCL;
count_high = EP2BCH;
count = ((unsigned long)(count_high)<<8) + (unsigned long)count_low;
if (XferSm == XFERSM_CBW)
{
if (count != 13)//如果CBW长度不等于13
{
//.....这里省去错误处理
}
else//如果长度等于CBW的长度13
{
APTR1H = MSB( &EP2FIFOBUF );
APTR1L = LSB( &EP2FIFOBUF );
for (i=0;i<count;i++) //把CBW保存到sCBW
{
sCBW = EXTAUTODAT1;
}
//取data stage 要处理的数据长度, 以字节为单位
data_length = (unsigned long)sCBW;
data_length += ((unsigned long)sCBW) << 8;
data_length += ((unsigned long)sCBW) << 16;
data_length += ((unsigned long)sCBW) << 24;
EP2BCL = 0x80; // re(arm) EP2OUT
SYNCDELAY;
//处理CBW命令
if (sCBW == CBW_CMD_READ_REG)
{
while(data_length>0)//如果需要处理的数据还没有完成
{
if (!(EP2468STAT & bmEP2EMPTY))
{
if (!(EP2468STAT & bmEP6FULL))
{
count_low = EP2BCL;
count_high = EP2BCH;
count = ((unsigned long)(count_high)<<8) + (unsigned long)count_low;
for (i=0;i<(count/4);i++) //every register information occupy 4 bytes
{
// 这里准备填充EP6的数据
bCmdStatus = CSW_CMD_PASS;//if use parallel register interface, we assume that all access always is correct
}
EP6BCH = count_high;
SYNCDELAY;
EP6BCL = count_low; // arm EP6IN.
SYNCDELAY;
EP2BCL = 0x80; // arm EP2OUT by writing byte count w/skip.
SYNCDELAY;
data_length -= count; //calculate remain byte number
}
}
}
//if data stage completed, return csw
sCSW = bCmdStatus;
Send_Csw();
}
else if (sCBW == CBW_CMD_WRITE_REG)
{
while(data_length>0)//if data stage not complete
{
while(EP2468STAT & bmEP2EMPTY) ;//wait OUT data come,
count_low = EP2BCL;
count_high = EP2BCH;
count = ((unsigned long)(count_high)<<8) + (unsigned long)count_low;
for (i=0;i<(count/4);i++) //every register information occupy 4 bytes
{
// 这里处理数据
bCmdStatus = CSW_CMD_PASS;//if use parallel register interface, we assume that all access always is correct
}
EP2BCL = 0x80; // arm EP2OUT by writing byte count w/skip.
SYNCDELAY;
data_length -= count; //calculate remain byte number
}
//if data stage completed, return csw
sCSW = bCmdStatus;
Send_Csw();
}
else if (sCBW == CBW_CMD_WRITE_DATA)
{
while(data_length>0)//if data stage not complete
{
while(EP2468STAT & bmEP2EMPTY);//wait OUT data come,
count_low = EP2BCL;
count_high = EP2BCH;
count = ((unsigned long)(count_high)<<8) + (unsigned long)count_low;
data_length -= count; //calculate remain byte number
EP2BCL = 0x00;//提交数据,FPGA接受处理
SYNCDELAY;
}
//if data stage completed, return cs
sCSW = CSW_CMD_PASS;
Send_Csw();
}
else//not supported command
{
//return csw with command fail
sCSW = CSW_CMD_FAIL;
Send_Csw();
}
}
}
}
我不知道怎么回事,反正是你把代码结构好好调调,看看哪有问题。你可以一点一点试验。另外有一点,FX2不支持部分端点AUTOIN而另一部分端点不是AUTOOUT。你必须要么全是AUTOARM,要么全不是AUTOARM。 EP2只传数据,AUTOARM,命令由控制端口传,感觉56脚的弄起来是不怎么方便 wye11083 发表于 2012-8-29 18:32 static/image/common/back.gif
我不知道怎么回事,反正是你把代码结构好好调调,看看哪有问题。你可以一点一点试验。另外有一点,FX2不支 ...
FX2 不支持一个端点AUTOIN, 另一个端点Manul OUT???是合格意思吗?在手册上有讲? liurangzhou 发表于 2012-8-29 18:48 static/image/common/back.gif
EP2只传数据,AUTOARM,命令由控制端口传,感觉56脚的弄起来是不怎么方便
我用的是128脚的, EP2 是 ManulOUT,EP6是AutoIN。 beck75 发表于 2012-8-29 21:12 static/image/common/back.gif
FX2 不支持一个端点AUTOIN, 另一个端点Manul OUT???是合格意思吗?在手册上有讲? ...
我都试验上百次了,我会说错吗?我的FX2现在也会因各种各样的问题而挂掉。AUTOARM没有CPUINT模式方便,但是速度要快得多。要么全自动,要么全手动,没别的选择。FX2毕竟不完美,只不过没有比FX2更好的USB控制器而已。 wye11083 发表于 2012-8-29 22:10 static/image/common/back.gif
我都试验上百次了,我会说错吗?我的FX2现在也会因各种各样的问题而挂掉。AUTOARM没有CPUINT模式方便,但 ...
有没有办法知道EP2FIFO(不是端点)里还有多少数据没有取走? 很简单。你发现你写不进去了,就是满了。你可以用128脚的串口调试。 wye11083 发表于 2012-8-30 08:59 static/image/common/back.gif
很简单。你发现你写不进去了,就是满了。你可以用128脚的串口调试。
现在的情况是HOST写不进去,但是FX2的EP2468STAT及EP2CS却显示EP2 为空。
beck75 发表于 2012-8-31 20:43 static/image/common/back.gif
现在的情况是HOST写不进去,但是FX2的EP2468STAT及EP2CS却显示EP2 为空。
我不知道你什么情况,这是我的初始化代码
#ifndef _SET_INTERRUPT
#define _SET_INTERRUPT
void DropEP2Packet()
{
OUTPKTEND = 0x82;
SYNCDELAY;
}
void ResetEndPoint2()
{
FIFORESET = 0x80; SYNCDELAY;
FIFORESET = 0x02; SYNCDELAY;
FIFORESET = 0x04; SYNCDELAY;
FIFORESET = 0x00; SYNCDELAY;
}
void ResetEndPoint6()
{
FIFORESET = 0x80; SYNCDELAY;
FIFORESET = 0x06; SYNCDELAY;
FIFORESET = 0x08; SYNCDELAY;
FIFORESET = 0x00; SYNCDELAY;
}
void SetEPCfg()
{
// Disable EP4 & EP8
EP4CFG = 0x20; SYNCDELAY;
EP2CFG = 0xA0; SYNCDELAY;
ResetEndPoint2();
EP8CFG = 0x60; SYNCDELAY;
EP6CFG = 0xE0; SYNCDELAY;
ResetEndPoint6();
}
void EnterGPIOMode()
{
CPUCS = 0x12; SYNCDELAY;
REVCTL = 0x03; SYNCDELAY;
IFCONFIG = 0xC0; SYNCDELAY;
// Disable Auto-IN and Auto-OUT
EP2FIFOCFG = 0x05; SYNCDELAY;
EP6FIFOCFG = 0x05; SYNCDELAY;
SetEPCfg();
DropEP2Packet();
DropEP2Packet();
DropEP2Packet();
DropEP2Packet();
IOA = 0x8A; //Set IOA = 10001010
OEA = 0x8B; //Set OEA = 10001010
// OED & OEB is set Input
OED = 0x00;
OEB = 0x00;
}
void EnterSlaveFIFOMode()
{
OEA = 0x8B;
IOA = 0x8A;
SYNCDELAY;
CPUCS = 0x12; SYNCDELAY;
REVCTL = 0x00; SYNCDELAY;
IFCONFIG = 0x03; SYNCDELAY;
// Sync, IFCLK Input
EP2FIFOCFG = 0x05; SYNCDELAY;
EP6FIFOCFG = 0x05; SYNCDELAY;
SetEPCfg();
DropEP2Packet();
DropEP2Packet();
DropEP2Packet();
DropEP2Packet();
EP2FIFOCFG = 0x15; SYNCDELAY;
EP6FIFOCFG = 0x4D; SYNCDELAY;
}
#endif 关注下,接下来也准备搞! 可以加你为好友吗?我也遇到了类似的问题。我的QQ:641464726. wye11083 发表于 2012-8-29 22:10
我都试验上百次了,我会说错吗?我的FX2现在也会因各种各样的问题而挂掉。AUTOARM没有CPUINT模式方便,但 ...
刚刚也发现这个问题了,
这都10多年了也没修正,
还准备发e-mail去问cypress,看来省了。
消费电子的坑真大,除了demo提供的case,其它都不可靠啊 xycfwrj 发表于 2017-11-7 12:19
刚刚也发现这个问题了,
这都10多年了也没修正,
还准备发e-mail去问cypress,看来省了。
我晕,这坟挖得也太牛B了。
现在已经不建议用ezusb了,全部转向cyusb了。cyusb在用fx2时请注意每次要么取512B,要么取128KB及以上(可以有PKTEND),否则传输会出错。 本帖最后由 xycfwrj 于 2017-11-7 12:58 编辑
wye11083 发表于 2017-11-7 12:28
我晕,这坟挖得也太牛B了。
现在已经不建议用ezusb了,全部转向cyusb了。cyusb在用fx2时请注意每次要么 ...
用的就是新的驱动,
而且发现ep2 autoin,ep4 manul out,容易死不说,连out的数据都不对,
换ep6 manual out数据才对
512B那个问题我也发现了,ftdi也有类似问题。
不过需要指出的是,你说的128KB,其实是驱动层面的事,包上限512B不能再高了,
只不过驱动层面一次指定大于512B的传输,它把数据处理在驱动层面搞定再提交,overhead低所以速度快,
而指定512B他需要每包进行交互,overhead大,速率就上不去。
我是因为ftdi linux驱动性能不行(后来自己基于libusb用并发搞定了),而且逻辑不够灵活才转过来的,
结果好了,转过来发现灵活的优点就是纸面的,而且引入固件带来额外的麻烦,太坑人了!
页:
[1]