Cypress技术论坛
直播中

张英

7年用户 1401经验值
私信 关注

CY7C68013A-100AXC数据丢失怎么处理?

使用该芯片时,传输了[size=12.0000pt]699050个数据时会出现丢失一个,导致整个数据产生突变,后续数据稳定,但下位机接收到的数据会移位,产生错误;上位机准备的数据采用监听软件未发现丢失以及异常,[size=12.0000pt]signaltap抓取USB输入数据,发现的异常 一个数据是16位
[size=12.0000pt]
[size=10.5000pt]如下为USBiic代码:


[size=10.5000pt]void TD_Init(void) [size=10.5000pt]// Called once at startup

[size=10.5000pt]{

[size=10.5000pt]    BYTE dum;

[size=10.5000pt]Rwuen = TRUE; [size=10.5000pt]// Enable remote-wakeup


[size=10.5000pt]    // Indicate if it is a dual byte address part

[size=10.5000pt]    DB_Addr = 1; [size=10.5000pt]// hard-wire for large EEPROM


[size=10.5000pt]I2CTL  = ~bm400KHZ; [size=10.5000pt]// 0: 100 KHz


[size=10.5000pt]EZUSB_Initi2C();    // Initialize I2C bus







[size=10.5000pt]  CPUCS = 0x12; // CLKSPD[1:0]=10, for 48MHz operation, output CLKOUT


[size=10.5000pt]  PINFLAGSAB = 0xC8; [size=10.5000pt]// FLAGA - EP2EF

[size=10.5000pt]  SYNCDELAY;

[size=10.5000pt]  PINFLAGSCD = 0xDE; [size=10.5000pt]// FLAGD - EP6FF

[size=10.5000pt]  SYNCDELAY;


[size=10.5000pt]  SYNCDELAY;

[size=10.5000pt]  PORTACFG = 0x40;             // func. of PA7 pin is SLCS#

[size=10.5000pt]  SYNCDELAY;

[size=10.5000pt]  FIFOPINPOLAR = 0x00;          // all signals active low

[size=10.5000pt]  SYNCDELAY;


[size=10.5000pt]  IFCONFIG |= 0x4B; //Internal clock, 48 MHz, Slave FIFO interface

[size=10.5000pt]  SYNCDELAY;



[size=10.5000pt]    // EP4 and EP8 are not used in this implementation...



[size=10.5000pt]  EP2CFG = 0xA0;                //out 512 bytes, 4x, bulk

[size=10.5000pt]  SYNCDELAY;                    

[size=10.5000pt]  EP6CFG = 0xE0;                // in 512 bytes, 4x, bulk

[size=10.5000pt]  SYNCDELAY;              

[size=10.5000pt]  EP4CFG = 0x02;                //clear valid bit

[size=10.5000pt]  SYNCDELAY;                     

[size=10.5000pt]  EP8CFG = 0x02;                //clear valid bit

[size=10.5000pt]  SYNCDELAY;   



[size=10.5000pt]  SYNCDELAY;

[size=10.5000pt]  FIFORESET = 0x80;             // activate NAK-ALL to avoid race conditions

[size=10.5000pt]  SYNCDELAY;                    // see TRM section 15.14

[size=10.5000pt]  FIFORESET = 0x02;             // reset, FIFO 2

[size=10.5000pt]  SYNCDELAY;                    //

[size=10.5000pt]  FIFORESET = 0x04;             // reset, FIFO 4

[size=10.5000pt]  SYNCDELAY;                    //

[size=10.5000pt]  FIFORESET = 0x06;             // reset, FIFO 6

[size=10.5000pt]  SYNCDELAY;                    //

[size=10.5000pt]  FIFORESET = 0x08;             // reset, FIFO 8

[size=10.5000pt]  SYNCDELAY;                    //

[size=10.5000pt]  FIFORESET = 0x00;             // deactivate NAK-ALL


[size=10.5000pt]    // handle the case where we were already in AUTO mode...

[size=10.5000pt]  // ...for example: back to back firmware downloads...

[size=10.5000pt]  SYNCDELAY;                    //

[size=10.5000pt]  EP2FIFOCFG = 0x00;            // AUTOOUT=0, WORDWIDE=1



[size=10.5000pt]  // core needs to see AUTOOUT=0 to AUTOOUT=1 switch to arm endp's



[size=10.5000pt]  SYNCDELAY;                    //

[size=10.5000pt]  EP2FIFOCFG = 0x11;            // AUTOOUT=1, WORDWIDE=1



[size=10.5000pt]  SYNCDELAY;                    //

[size=10.5000pt]  EP6FIFOCFG = 0x0D;            // AUTOIN=1, ZEROLENIN=1, WORDWIDE=1


[size=10.5000pt]  SYNCDELAY;


[size=10.5000pt]}

                                                                                                                                                                                                                                                                                                                                                                                                        
                                                        

回帖(1)

孟薇

2024-2-28 14:50:00
使用的是状态机,这个是底层FPGA程序,测了flag信号丢数据时没有异常,丢数据时测试了signaltap抓取了所有与USB连接的信号,与之前的正常数据的一样

FPGA代码如下:
                                                                                                  `timescale 10ns/1ns
//////////////////////////////////////////////////////////////////////////////////
//    Module Name:    usb_test
//    Description: If the FIFO of EP2 is not empty and
//    the EP6 is not full, Read the 16bit data from EP2 FIFO
//    and send to EP6 FIFO.  
//////////////////////////////////////////////////////////////////////////////////
module USB_TRANSMISSION(
    input              fpga_gclk       ,         //FPGA Clock Input 50Mhz
    input              reset_n         ,         //FPGA Reset input
    output reg [1:0]   usb_fifoaddr    ,         //CY68013 FIFO Address
    output reg         usb_slcs        ,         //CY68013 Chipset select
    output reg         usb_sloe        ,         //CY68013 Data output enable
    output reg         usb_slrd        ,         //CY68013 READ indication
    output reg         usb_slwr        ,         //CY68013 Write indication
    output reg         wr_fifo_wr      ,      
    output reg[15:0]   data_reg        ,   
  output reg         sdwrad_clr      ,         
    inout [15:0]       usb_fd          ,         //CY68013 Data
    input              usb_flaga       ,         //CY68013 EP2 FIFO empty indication; 1:not empty; 0: empty
    input              usb_flagb       ,         //CY68013 EP4 FIFO empty indication; 1:not empty; 0: empty
    input              usb_flagc       ,            //CY68013 EP6 FIFO full indication; 1:not full; 0: full
  input              flag_clr
    );
//reg[15:0] data_reg;
reg      bus_busy           ;                              
reg      access_req         ;                           
reg      usb_fd_en          ;                        //控制USB Data的方向
reg[4:0] usb_state          ;
reg[4:0] i                  ;
parameter IDLE=5'd0         ;
parameter EP2_RD_CMD=5'd1   ;
parameter EP2_RD_DATA=5'd2  ;
parameter EP2_RD_OVER=5'd3  ;
parameter EP6_WR_CMD=5'd4   ;
parameter EP6_WR_OVER=5'd5  ;            
/* Generate USB read/write access request*/
always @(negedge fpga_gclk or negedge reset_n)
begin
   if (~reset_n ) begin
      access_req<=1'b0;
   end
   else begin
      if (usb_flaga   usb_flagc   (bus_busy==1'b0))     //如果EP2的FIFO不空,EP6的FIFO不满,而且状态为idle
          access_req<=1'b1;                             //USB读写请求
      else
          access_req<=1'b0;
   end
end
always @(negedge fpga_gclk or negedge reset_n)
begin
    if (~reset_n )
      usb_slcs<=1'b1;
  else
    usb_slcs<=1'b0;
end  
  
/* 完成一次读EP2 FIFO的数据和一次写EP6 FIFO数据的过程*/
always @(posedge fpga_gclk or negedge reset_n)
  begin
   if (~reset_n) begin
  usb_fifoaddr<=2'b00;  
  usb_sloe<=1'b1;  
      usb_slrd<=1'b1;
    usb_slwr<=1'b1;
      usb_fd_en<=1'b0;
    usb_state<=IDLE;
      wr_fifo_wr<=0;
    bus_busy <=0;
   end  
   else begin
    case(usb_state)
        IDLE:begin                                            //Idle状态
      usb_fifoaddr<=2'b00;                              //地址选择EP2 FIFO
    i<=0;
    usb_fd_en<=1'b0;      
        if (access_req==1'b1) begin                                   
         usb_state<=EP2_RD_CMD;                         //开始读EP2 FIFO的数据
       bus_busy<=1'b1;                                //状态变忙
      end   
            else begin
       bus_busy<=1'b0;   
       usb_state<=IDLE;  
      end  
        end
        EP2_RD_CMD:begin                                      //EP2 FIFO Read Command
      if(i==2) begin
               usb_slrd<=1'b1;
               usb_sloe<=1'b0;                              //OE信号变低,EP2 FIFO数据输出有效   
               i<=i+1'b1;
            end
            else if(i==8) begin
               usb_slrd<=1'b0;                                //RD信号变低,读EP2 FIFO,RD低电平需要>50ns   
               usb_sloe<=1'b0;      
               i<=0;
       usb_state<=EP2_RD_DATA;
            end
            else begin
      i<=i+1'b1;
      end
        end   
    EP2_RD_DATA:begin                                    //EP2 FIFO Read Data
              if(i==8) begin
                 usb_slrd<=1'b1;                            //RD信号变高,读取数据   
                 usb_sloe<=1'b0;      
                  i<=0;
          usb_state<=EP2_RD_OVER;
            data_reg<=usb_fd;                          //读取数据
              end
              else begin
                 usb_slrd<=1'b0;                        
                 usb_sloe<=1'b0;      
          i<=i+1'b1;
        end
   end   
   EP2_RD_OVER:begin                                     //读完成
              if(i==4) begin
                 usb_slrd<=1'b1;     
                 usb_sloe<=1'b1;      
                  i<=0;
            usb_fifoaddr<=2'b10;                       //地址选择EP6 FIFO
     // usb_state<=EP6_WR_CMD;
        usb_state<=IDLE;
              end
              else if(i==1)begin
           wr_fifo_wr<=1;
          i<=i+1'b1;
        end
              else begin
                 usb_slrd<=1'b1;                        
                 usb_sloe<=1'b0;
                  wr_fifo_wr<=0;      
          i<=i+1'b1;
        end
   end
   EP6_WR_CMD:begin                                  //写EP6 FIFO  
              if(i==8) begin
                  usb_slwr<=1'b1;                          //EP6写结束
                  i<=0;      
            usb_state<=EP6_WR_OVER;
              end
              else begin
                 usb_slwr<=1'b0;                          //异步写时,slwr低电平需要>50ns
           usb_fd_en<=1'b1;                         //数据输出到总线
           i<=i+1'b1;
        end
   end   
   EP6_WR_OVER:begin                                //写EP6 FIFO完成     
              if(i==4) begin
                usb_fd_en<=1'b0;
          bus_busy<=1'b0;
                i<=0;      
          usb_state<=IDLE;
              end
              else begin   
          i<=i+1'b1;
        end
   end
       default:usb_state<=IDLE;
       endcase
  end
  end  
assign usb_fd = usb_fd_en?data_reg:16'bz;                //USB总线数据输入输出选择
//-------------上电延迟1S使能FIFO,1S内FIFO数据清0----------//
//-------------------------------------------------------//
/*
always @(posedge fpga_gclk or negedge reset_n)
begin
   if(~reset_n )
      sdwrad_clr<=1'b1;
   else
      sdwrad_clr<=1'b0;
end
*/
reg[27:0]     en_cnt            ;

always @(posedge fpga_gclk or negedge reset_n)begin
  if(reset_n==1'b0)begin
        en_cnt <= 28'd0;
  end
  else begin
    if(en_cnt<=28'd50000000)
       en_cnt <= en_cnt + 1'b1;
  else
      en_cnt <= en_cnt;
  end
end
always @(posedge fpga_gclk or negedge reset_n)begin//使能延时1us  
  if(reset_n==1'b0)begin
         sdwrad_clr <= 1'b1;
  end
  else begin
         if(en_cnt>28'd50000000 | flag_clr==1)
   sdwrad_clr <= 0;
   else
   sdwrad_clr <= 1;
  end
end

//------------------------------------------------------//
endmodule
举报

更多回帖

发帖
×
20
完善资料,
赚取积分