beck75 发表于 2012-8-29 02:28:33

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;

}

wye11083 发表于 2012-8-29 10:40:01

你后面的要取数据啊。否则不死锁才怪。

beck75 发表于 2012-8-29 11:44:29

数据都被FPGA取走了。附件是图片。
黄线上方是FPGA取走的OUT数据,下面三个OUT包是写到FX2的EP2端点的,也确实是接受到了, 但是下面再想写入OUT包死锁。
这个时候的状态是这样的,EP2467STAT显示EP2空,Firmware 死在
while (EP2468STAT & bmEP2EMPTY) 这里,然而HOST端却死在DeviceIOControl ( EP2OUT ).。 我测量了下 EP2的EMPTY指示管脚好像是FLAGB,发现是非空。   问题是这样的情况不是每次出现,前面已经正确传输了好几个回合了。

beck75 发表于 2012-8-29 15:43:18

wye11083 发表于 2012-8-29 10:40 static/image/common/back.gif
你后面的要取数据啊。否则不死锁才怪。

wye11083 能帮忙一下吗

wye11083 发表于 2012-8-29 15:58:55

while (EP2468STAT & bmEP2EMPTY)应写为while(!(EP2468STAT & bmEP2EMPTY))才行。再一个,每收到一个包就要确认一下。

beck75 发表于 2012-8-29 16:25:36

能把你的QQ发信息告诉我吗?

beck75 发表于 2012-8-29 17:50:36

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();
      }
      }

   }

}

wye11083 发表于 2012-8-29 18:32:51

我不知道怎么回事,反正是你把代码结构好好调调,看看哪有问题。你可以一点一点试验。另外有一点,FX2不支持部分端点AUTOIN而另一部分端点不是AUTOOUT。你必须要么全是AUTOARM,要么全不是AUTOARM。

liurangzhou 发表于 2012-8-29 18:48:11

EP2只传数据,AUTOARM,命令由控制端口传,感觉56脚的弄起来是不怎么方便

beck75 发表于 2012-8-29 21:12:56

wye11083 发表于 2012-8-29 18:32 static/image/common/back.gif
我不知道怎么回事,反正是你把代码结构好好调调,看看哪有问题。你可以一点一点试验。另外有一点,FX2不支 ...

FX2 不支持一个端点AUTOIN, 另一个端点Manul OUT???是合格意思吗?在手册上有讲?

beck75 发表于 2012-8-29 21:14:32

liurangzhou 发表于 2012-8-29 18:48 static/image/common/back.gif
EP2只传数据,AUTOARM,命令由控制端口传,感觉56脚的弄起来是不怎么方便

我用的是128脚的, EP2 是 ManulOUT,EP6是AutoIN。

wye11083 发表于 2012-8-29 22:10:10

beck75 发表于 2012-8-29 21:12 static/image/common/back.gif
FX2 不支持一个端点AUTOIN, 另一个端点Manul OUT???是合格意思吗?在手册上有讲? ...

我都试验上百次了,我会说错吗?我的FX2现在也会因各种各样的问题而挂掉。AUTOARM没有CPUINT模式方便,但是速度要快得多。要么全自动,要么全手动,没别的选择。FX2毕竟不完美,只不过没有比FX2更好的USB控制器而已。

beck75 发表于 2012-8-29 23:54:15

wye11083 发表于 2012-8-29 22:10 static/image/common/back.gif
我都试验上百次了,我会说错吗?我的FX2现在也会因各种各样的问题而挂掉。AUTOARM没有CPUINT模式方便,但 ...

有没有办法知道EP2FIFO(不是端点)里还有多少数据没有取走?

wye11083 发表于 2012-8-30 08:59:26

很简单。你发现你写不进去了,就是满了。你可以用128脚的串口调试。

beck75 发表于 2012-8-31 20:43:47

wye11083 发表于 2012-8-30 08:59 static/image/common/back.gif
很简单。你发现你写不进去了,就是满了。你可以用128脚的串口调试。

现在的情况是HOST写不进去,但是FX2的EP2468STAT及EP2CS却显示EP2 为空。

wye11083 发表于 2012-8-31 21:49:53

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

hbchf 发表于 2012-9-1 19:10:08

关注下,接下来也准备搞!

hheehhaa520 发表于 2012-9-4 17:22:59

可以加你为好友吗?我也遇到了类似的问题。我的QQ:641464726.

xycfwrj 发表于 2017-11-7 12:19:34

wye11083 发表于 2012-8-29 22:10
我都试验上百次了,我会说错吗?我的FX2现在也会因各种各样的问题而挂掉。AUTOARM没有CPUINT模式方便,但 ...

刚刚也发现这个问题了,
这都10多年了也没修正,
还准备发e-mail去问cypress,看来省了。
消费电子的坑真大,除了demo提供的case,其它都不可靠啊

wye11083 发表于 2017-11-7 12:28:42

xycfwrj 发表于 2017-11-7 12:19
刚刚也发现这个问题了,
这都10多年了也没修正,
还准备发e-mail去问cypress,看来省了。


我晕,这坟挖得也太牛B了。

现在已经不建议用ezusb了,全部转向cyusb了。cyusb在用fx2时请注意每次要么取512B,要么取128KB及以上(可以有PKTEND),否则传输会出错。

xycfwrj 发表于 2017-11-7 12:30:35

本帖最后由 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]
查看完整版本: CY7C68013 + FPGA 调试中碰到的怪问题.