搜索
bottom↓
回复: 20

CY7C68013 + FPGA 调试中碰到的怪问题.

[复制链接]

出0入0汤圆

发表于 2012-8-29 02:28:33 | 显示全部楼层 |阅读模式
使用的端点: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[B3:B0] 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;

}

出0入442汤圆

发表于 2012-8-29 10:40:01 | 显示全部楼层
你后面的要取数据啊。否则不死锁才怪。

出0入0汤圆

 楼主| 发表于 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,发现是非空。   问题是这样的情况不是每次出现,前面已经正确传输了好几个回合了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2012-8-29 15:43:18 | 显示全部楼层
wye11083 发表于 2012-8-29 10:40
你后面的要取数据啊。否则不死锁才怪。

wye11083 能帮忙一下吗

出0入442汤圆

发表于 2012-8-29 15:58:55 | 显示全部楼层
while (EP2468STAT & bmEP2EMPTY)应写为while(!(EP2468STAT & bmEP2EMPTY))才行。再一个,每收到一个包就要确认一下。

出0入0汤圆

 楼主| 发表于 2012-8-29 16:25:36 | 显示全部楼层
能把你的QQ发信息告诉我吗?

出0入0汤圆

 楼主| 发表于 2012-8-29 17:50:36 | 显示全部楼层
wye11083 发表于 2012-8-29 15:58
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[9];
        data_length += ((unsigned long)sCBW[10]) << 8;
        data_length += ((unsigned long)sCBW[11]) << 16;
        data_length += ((unsigned long)sCBW[12]) << 24;
                  
        EP2BCL = 0x80;          // re(arm) EP2OUT
        SYNCDELAY;

        //处理CBW命令
        if (sCBW[8] == 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[8] = bCmdStatus;
          Send_Csw();
         
        }
        else if (sCBW[8] == 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[8] = bCmdStatus;
          Send_Csw();         
        }
        else if (sCBW[8] == 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[8] = CSW_CMD_PASS;
          Send_Csw();
        }      
      
        else  //not supported command
        {
          //return csw with command fail
          sCSW[8] = CSW_CMD_FAIL;
      
          Send_Csw();
        }
      }

   }

}

出0入442汤圆

发表于 2012-8-29 18:32:51 | 显示全部楼层
我不知道怎么回事,反正是你把代码结构好好调调,看看哪有问题。你可以一点一点试验。另外有一点,FX2不支持部分端点AUTOIN而另一部分端点不是AUTOOUT。你必须要么全是AUTOARM,要么全不是AUTOARM。

出0入0汤圆

发表于 2012-8-29 18:48:11 | 显示全部楼层
EP2只传数据,AUTOARM,命令由控制端口传,感觉56脚的弄起来是不怎么方便

出0入0汤圆

 楼主| 发表于 2012-8-29 21:12:56 | 显示全部楼层
wye11083 发表于 2012-8-29 18:32
我不知道怎么回事,反正是你把代码结构好好调调,看看哪有问题。你可以一点一点试验。另外有一点,FX2不支 ...

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

出0入0汤圆

 楼主| 发表于 2012-8-29 21:14:32 | 显示全部楼层
liurangzhou 发表于 2012-8-29 18:48
EP2只传数据,AUTOARM,命令由控制端口传,感觉56脚的弄起来是不怎么方便

我用的是128脚的, EP2 是 Manul  OUT,  EP6是AutoIN。

出0入442汤圆

发表于 2012-8-29 22:10:10 | 显示全部楼层
beck75 发表于 2012-8-29 21:12
FX2 不支持一个端点AUTOIN, 另一个端点Manul OUT???是合格意思吗?在手册上有讲? ...

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

出0入0汤圆

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

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

出0入442汤圆

发表于 2012-8-30 08:59:26 | 显示全部楼层
很简单。你发现你写不进去了,就是满了。你可以用128脚的串口调试。

出0入0汤圆

 楼主| 发表于 2012-8-31 20:43:47 | 显示全部楼层
wye11083 发表于 2012-8-30 08:59
很简单。你发现你写不进去了,就是满了。你可以用128脚的串口调试。

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

出0入442汤圆

发表于 2012-8-31 21:49:53 | 显示全部楼层
beck75 发表于 2012-8-31 20:43
现在的情况是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

出0入0汤圆

发表于 2012-9-1 19:10:08 | 显示全部楼层
关注下,接下来也准备搞!

出0入0汤圆

发表于 2012-9-4 17:22:59 | 显示全部楼层
可以加你为好友吗?我也遇到了类似的问题。我的QQ:641464726.

出0入0汤圆

发表于 2017-11-7 12:19:34 | 显示全部楼层
wye11083 发表于 2012-8-29 22:10
我都试验上百次了,我会说错吗?我的FX2现在也会因各种各样的问题而挂掉。AUTOARM没有CPUINT模式方便,但 ...

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

出0入442汤圆

发表于 2017-11-7 12:28:42 来自手机 | 显示全部楼层
xycfwrj 发表于 2017-11-7 12:19
刚刚也发现这个问题了,
这都10多年了也没修正,
还准备发e-mail去问cypress,看来省了。

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

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

出0入0汤圆

发表于 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用并发搞定了),而且逻辑不够灵活才转过来的,
结果好了,转过来发现灵活的优点就是纸面的,而且引入固件带来额外的麻烦,太坑人了!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-18 15:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表