使用该芯片时,传输了699050个数据时会出现丢失一个,导致整个数据产生突变,后续数据稳定,但下位机接收到的数据会移位,产生错误;上位机准备的数据采用监听软件未发现丢失以及异常,signaltap抓取USB输入数据,发现的异常 一个数据是16位
如下为USB的iic代码:
void TD_Init(void) // Called once at startup
{
BYTE dum;
Rwuen = TRUE; // Enable remote-wakeup
// Indicate if it is a dual byte address part
DB_Addr = 1; // hard-wire for large EEPROM
I2CTL &= ~bm400KHZ; // 0: 100 KHz
EZUSB_InitI2C(); // Initialize I2C bus
CPUCS = 0x12; // CLKSPD[1:0]=10, for 48MHz operation, output CLKOUT
PINFLAGSAB = 0xC8; // FLAGA - EP2EF
SYNCDELAY;
PINFLAGSCD = 0xDE; // FLAGD - EP6FF
SYNCDELAY;
SYNCDELAY;
PORTACFG = 0x40; // func. of PA7 pin is SLCS#
SYNCDELAY;
FIFOPINPOLAR = 0x00; // all signals active low
SYNCDELAY;
IFCONFIG |= 0x4B; //Internal clock, 48 MHz, Slave FIFO interface
SYNCDELAY;
// EP4 and EP8 are not used in this implementation...
EP2CFG = 0xA0; //out 512 bytes, 4x, bulk
SYNCDELAY;
EP6CFG = 0xE0; // in 512 bytes, 4x, bulk
SYNCDELAY;
EP4CFG = 0x02; //clear valid bit
SYNCDELAY;
EP8CFG = 0x02; //clear valid bit
SYNCDELAY;
SYNCDELAY;
FIFORESET = 0x80; // activate NAK-ALL to avoid race conditions
SYNCDELAY; // see TRM section 15.14
FIFORESET = 0x02; // reset, FIFO 2
SYNCDELAY; //
FIFORESET = 0x04; // reset, FIFO 4
SYNCDELAY; //
FIFORESET = 0x06; // reset, FIFO 6
SYNCDELAY; //
FIFORESET = 0x08; // reset, FIFO 8
SYNCDELAY; //
FIFORESET = 0x00; // deactivate NAK-ALL
// handle the case where we were already in AUTO mode...
// ...for example: back to back firmware downloads...
SYNCDELAY; //
EP2FIFOCFG = 0x00; // AUTOOUT=0, WORDWIDE=1
// core needs to see AUTOOUT=0 to AUTOOUT=1 switch to arm endp's
SYNCDELAY; //
EP2FIFOCFG = 0x11; // AUTOOUT=1, WORDWIDE=1
SYNCDELAY; //
EP6FIFOCFG = 0x0D; // AUTOIN=1, ZEROLENIN=1, WORDWIDE=1
SYNCDELAY;
}
使用的是状态机,这个是底层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