Isue: No se reciben paquetes ACK después del procedimiento de configuración
Posible motivo: USB PHY se ha configurado mal o es una mala interpretación de la representación de líneas de datos
Pregunta : ¿Qué debo hacer para averiguar el problema? ¿Hay algo que me falta y cómo debo solucionar el problema?
Equipo:
- FPGA de la familia Xilinx Spartan 6
- Beagle USB 5000 v2 SuperSpeed Protocol Analyzer
- Nexys 3 Development Board
- Función IP 1.1 USB Core ( enlace )
- Velocidad del reloj 'clk_i' a 100MHz
Configuración del experimento: Esta es una foto de cómo lo he conectado todo
Captura de pantalla del análisis del protocolo USB: No hay respuesta ACK del dispositivo
Nivel Nexys 3 TOP (Verilog):
'timescale 1ns / 1ps
'include "usb1_defines.v"
module Nexys3_TOP(
input clk_i,
input rst_i,
// Pmod outputs to USB 1.1 interface
inout dp,
inout dn,
// Leds
output reg [7:0] Led
);
// Physical interface wires
wire tx_dp;
wire tx_dn;
wire tx_oe;
wire rx_d;
wire rx_dp;
wire rx_dn;
// bi-directional lines
assign dp = tx_oe ? tx_dp : 1'bZ ;
assign dn = tx_oe ? tx_dn : 1'bZ ;
assign rx_dp = dp;
assign rx_dn = dn;
// USB configuration bits
wire phy_tx_mode = 1'b0;
wire usb_rst;
wire dropped_frame;
wire misaligned_frame;
wire crc16_err;
// Vendor Defined Features
wire v_set_int;
wire v_set_feature;
wire [15:0] wValue;
wire [15:0] wIndex;
reg [15:0] vendor_data;
// end point in use
wire usb_busy;
wire [3:0] ep_sel;
// configure end points
wire [13:0] ep1_cfg;
wire [13:0] ep2_cfg;
wire ep1_bf_en;
wire [6:0] ep1_bf_size;
wire ep2_bf_en;
wire [6:0] ep2_bf_size;
assign ep1_cfg = 'INT | 'IN | 14'd064;
assign ep2_cfg = 'INT | 'OUT | 14'd064;
assign ep1_bf_en = 0;
assign ep1_bf_size = 7'b0000000;
assign ep2_bf_en = 0;
assign ep2_bf_size = 7'b0000000;
// Endpoint Interface
// Endpoint 1
reg [7:0] ep1_din;
wire [7:0] ep1_dout = 8'b0000_0000;
wire ep1_we;
wire ep1_re;
reg ep1_empty;
reg ep1_full;
// Endpoint 2
wire [7:0] ep2_din = 8'b0000_0000;
wire [7:0] ep2_dout;
wire ep2_we;
wire ep2_re;
reg ep2_empty;
reg ep2_full;
always @(posedge clk_i) begin
ep1_empty = 0;
ep1_full = 0;
if (ep1_we) begin
ep1_din = 8'hAB;
ep1_empty = 0;
ep1_full = 1;
end
end
initial begin
Led = 8'b0000_1111;
end
always begin
Led[6] = dp;
Led[7] = dn;
end
// Instantiate the module
usb1_core instance_name (
.clk_i(clk_i),
.rst_i(rst_i),
.tx_dp(tx_dp),
.tx_dn(tx_dn),
.tx_oe(tx_oe),
.rx_d(rx_d),
.rx_dp(rx_dp),
.rx_dn(rx_dn),
.phy_tx_mode(phy_tx_mode),
.usb_rst(usb_rst),
.dropped_frame(dropped_frame),
.misaligned_frame(misaligned_frame),
.crc16_err(crc16_err),
.v_set_int(v_set_int),
.v_set_feature(v_set_feature),
.wValue(wValue),
.wIndex(wIndex),
.vendor_data(vendor_data),
.usb_busy(usb_busy),
.ep_sel(ep_sel),
.ep1_cfg(ep1_cfg),
.ep1_din(ep1_din),
.ep1_we(ep1_we),
.ep1_full(ep1_full),
.ep1_dout(ep1_dout),
.ep1_re(ep1_re),
.ep1_empty(ep1_empty),
.ep1_bf_en(ep1_bf_en),
.ep1_bf_size(ep1_bf_size),
.ep2_cfg(ep2_cfg),
.ep2_din(ep2_din),
.ep2_we(ep2_we),
.ep2_full(ep2_full),
.ep2_dout(ep2_dout),
.ep2_re(ep2_re),
.ep2_empty(ep2_empty),
.ep2_bf_en(ep2_bf_en),
.ep2_bf_size(ep2_bf_size)
// .ep3_cfg(ep3_cfg),
// .ep3_din(ep3_din),
// .ep3_we(ep3_we),
// .ep3_full(ep3_full),
// .ep3_dout(ep3_dout),
// .ep3_re(ep3_re),
// .ep3_empty(ep3_empty),
// .ep3_bf_en(ep3_bf_en),
// .ep3_bf_size(ep3_bf_size),
// .ep4_cfg(ep4_cfg),
// .ep4_din(ep4_din),
// .ep4_we(ep4_we),
// .ep4_full(ep4_full),
// .ep4_dout(ep4_dout),
// .ep4_re(ep4_re),
// .ep4_empty(ep4_empty),
// .ep4_bf_en(ep4_bf_en),
// .ep4_bf_size(ep4_bf_size),
// .ep5_cfg(ep5_cfg),
// .ep5_din(ep5_din),
// .ep5_we(ep5_we),
// .ep5_full(ep5_full),
// .ep5_dout(ep5_dout),
// .ep5_re(ep5_re),
// .ep5_empty(ep5_empty),
// .ep5_bf_en(ep5_bf_en),
// .ep5_bf_size(ep5_bf_size),
// .ep6_cfg(ep6_cfg),
// .ep6_din(ep6_din),
// .ep6_we(ep6_we),
// .ep6_full(ep6_full),
// .ep6_dout(ep6_dout),
// .ep6_re(ep6_re),
// .ep6_empty(ep6_empty),
// .ep6_bf_en(ep6_bf_en),
// .ep6_bf_size(ep6_bf_size),
// .ep7_cfg(ep7_cfg),
// .ep7_din(ep7_din),
// .ep7_we(ep7_we),
// .ep7_full(ep7_full),
// .ep7_dout(ep7_dout),
// .ep7_re(ep7_re),
// .ep7_empty(ep7_empty),
// .ep7_bf_en(ep7_bf_en),
// .ep7_bf_size(ep7_bf_size)
);
endmodule
Mi ROM de descriptor editado:
/////////////////////////////////////////////////////////////////////
//// ////
//// Descriptor ROM ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// [email protected] ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/usb1_funct/////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
//// www.asics.ws ////
//// [email protected] ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ''AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: usb1_rom1.v,v 1.1.1.1 2002-09-19 12:07:29 rudi Exp $
//
// $Date: 2002-09-19 12:07:29 $
// $Revision: 1.1.1.1 $
// $Author: rudi $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
//
//
//
//
//
'include "usb1_defines.v"
module usb1_rom1(clk, adr, dout);
input clk;
input [6:0] adr;
output [7:0] dout;
reg [7:0] dout;
always @(posedge clk)
case(adr) // synopsys full_case parallel_case
// ====================================
// ===== DEVICE Descriptor =====
// ====================================
7'h00: dout <= #1 8'd18; // this descriptor length
7'h01: dout <= #1 8'h01; // descriptor type
7'h02: dout <= #1 8'h00; // USB version low byte
7'h03: dout <= #1 8'h01; // USB version high byte
7'h04: dout <= #1 8'h00; // device class // (0x00 = HID - Human Interface Device) to be dealt with in interface descriptor
7'h05: dout <= #1 8'h00; // device sub class
7'h06: dout <= #1 8'h00; // device protocol
7'h07: dout <= #1 8'd64; // max packet size
7'h08: dout <= #1 8'h34; // vendor ID low byte
7'h09: dout <= #1 8'h12; // vendor ID high byte
7'h0a: dout <= #1 8'h78; // product ID low byte
7'h0b: dout <= #1 8'h56; // product ID high byte
7'h0c: dout <= #1 8'h01; // device rel. number low byte
7'h0d: dout <= #1 8'h00; // device rel. number high byte
7'h0e: dout <= #1 8'h50; // Manufacturer String Index
7'h0f: dout <= #1 8'h60; // Product Descr. String Index
7'h10: dout <= #1 8'h70; // S/N String Index
7'h11: dout <= #1 8'h01; // Number of possible config.
// ====================================
// ===== Configuration Descriptor =====
// ====================================
7'h12: dout <= #1 8'h09; // this descriptor length
7'h13: dout <= #1 8'h02; // descriptor type
7'h14: dout <= #1 8'd53; // total data length low byte
7'h15: dout <= #1 8'd00; // total data length high byte
7'h16: dout <= #1 8'h01; // number of interfaces
7'h17: dout <= #1 8'h01; // number of configurations
7'h18: dout <= #1 8'h00; // Conf. String Index
7'h19: dout <= #1 8'h40; // Config. Characteristics
7'h1a: dout <= #1 8'hff; // Max. Power Consumption
// ====================================
// ===== Interface Descriptor =====
// ====================================
7'h1b: dout <= #1 8'h09; // this descriptor length
7'h1c: dout <= #1 8'h04; // descriptor type
7'h1d: dout <= #1 8'h00; // interface number
7'h1e: dout <= #1 8'h00; // alternate setting
7'h1f: dout <= #1 8'h05; // number of endpoints
7'h20: dout <= #1 8'h03; // interface class // 0x03 = HID
7'h21: dout <= #1 8'h00; // interface sub class
7'h22: dout <= #1 8'h00; // interface protocol
7'h23: dout <= #1 8'h00; // interface string index
// ====================================
// ===== Endpoint 1 Descriptor =====
// ====================================
7'h24: dout <= #1 8'h07; // this descriptor length
7'h25: dout <= #1 8'h05; // descriptor type
7'h26: dout <= #1 8'h81; // endpoint address // endpoint = 1, direction = IN
7'h27: dout <= #1 8'h03; // endpoint attributes // interrupt
7'h28: dout <= #1 8'h00; // max packet size low byte
7'h29: dout <= #1 8'h01; // max packet size high byte
7'h2a: dout <= #1 8'h01; // polling interval
// ====================================
// ===== Endpoint 2 Descriptor =====
// ====================================
7'h2b: dout <= #1 8'h07; // this descriptor length
7'h2c: dout <= #1 8'h05; // descriptor type
7'h2d: dout <= #1 8'h02; // endpoint address // endpoint = 2, direction = OUT
7'h2e: dout <= #1 8'h01; // endpoint attributes
7'h2f: dout <= #1 8'h00; // max packet size low byte
7'h30: dout <= #1 8'h01; // max packet size high byte
7'h31: dout <= #1 8'h01; // polling interval
// ====================================
// ===== Endpoint 3 Descriptor =====
// ====================================
7'h32: dout <= #1 8'h07; // this descriptor length
7'h33: dout <= #1 8'h05; // descriptor type
7'h34: dout <= #1 8'h83; // endpoint address
7'h35: dout <= #1 8'h02; // endpoint attributes
7'h36: dout <= #1 8'd64; // max packet size low byte
7'h37: dout <= #1 8'd00; // max packet size high byte
7'h38: dout <= #1 8'h01; // polling interval
// ====================================
// ===== Endpoint 4 Descriptor =====
// ====================================
7'h39: dout <= #1 8'h07; // this descriptor length
7'h3a: dout <= #1 8'h05; // descriptor type
7'h3b: dout <= #1 8'h04; // endpoint address
7'h3c: dout <= #1 8'h02; // endpoint attributes
7'h3d: dout <= #1 8'd64; // max packet size low byte
7'h3e: dout <= #1 8'd00; // max packet size high byte
7'h3f: dout <= #1 8'h01; // polling interval
// ====================================
// ===== Endpoint 5 Descriptor =====
// ====================================
7'h40: dout <= #1 8'h07; // this descriptor length
7'h41: dout <= #1 8'h05; // descriptor type
7'h42: dout <= #1 8'h85; // endpoint address
7'h43: dout <= #1 8'h03; // endpoint attributes
7'h44: dout <= #1 8'd64; // max packet size low byte
7'h45: dout <= #1 8'd00; // max packet size high byte
7'h46: dout <= #1 8'h01; // polling interval
// ====================================
// ===== String Descriptor Lang ID=====
// ====================================
7'h47: dout <= #1 8'h06; // this descriptor length
7'h48: dout <= #1 8'h03; // descriptor type
7'h49: dout <= #1 8'h09; // Language ID 0 low byte
7'h4a: dout <= #1 8'h04; // Language ID 0 high byte
//7'h4b: dout <= #1 8'h09; // Language ID 1 low byte
//7'h4c: dout <= #1 8'h04; // Language ID 1 high byte
//7'h4d: dout <= #1 8'h09; // Language ID 2 low byte
//7'h4e: dout <= #1 8'h04; // Language ID 2 high byte
// ====================================
// ===== String Descriptor 0 =====
// ====================================
7'h50: dout <= #1 8'd010; // this descriptor length
7'h51: dout <= #1 8'd03; // descriptor type
7'h52: dout <= #1 "0";
7'h53: dout <= #1 " ";
7'h54: dout <= #1 "j";
7'h55: dout <= #1 "i";
7'h56: dout <= #1 "m";
7'h57: dout <= #1 "m";
7'h58: dout <= #1 "y";
7'h59: dout <= #1 "t";
// ====================================
// ===== String Descriptor 1 =====
// ====================================
7'h60: dout <= #1 8'd010; // this descriptor length
7'h61: dout <= #1 8'd03; // descriptor type
7'h62: dout <= #1 "1";
7'h63: dout <= #1 " ";
7'h64: dout <= #1 "m";
7'h65: dout <= #1 "y";
7'h66: dout <= #1 " ";
7'h67: dout <= #1 "U";
7'h68: dout <= #1 "S";
7'h69: dout <= #1 "B";
// ====================================
// ===== String Descriptor 2 =====
// ====================================
7'h70: dout <= #1 8'd010; // this descriptor length
7'h71: dout <= #1 8'd03; // descriptor type
7'h72: dout <= #1 "2";
7'h73: dout <= #1 " ";
7'h74: dout <= #1 "1";
7'h75: dout <= #1 "2";
7'h76: dout <= #1 "3";
7'h77: dout <= #1 "4";
7'h78: dout <= #1 "5";
7'h79: dout <= #1 "6";
// ====================================
// ====================================
//default: dout <= #1 8'd00;
endcase
endmodule
El archivo de restricciones
# Clock signal
NET "clk_i" LOC = "V10" | IOSTANDARD = "LVCMOS33"; #Bank = 2, pin name = IO_L30N_GCLK0_USERCCLK, Sch name = GCLK
Net "clk_i" TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;
# Leds
NET "Led<0>" LOC = "U16" | IOSTANDARD = "LVCMOS33"; #Bank = 2, Pin name = IO_L2P_CMPCLK, Sch name = LD0
NET "Led<1>" LOC = "V16" | IOSTANDARD = "LVCMOS33"; #Bank = 2, Pin name = IO_L2N_CMPMOSI, Sch name = LD1
NET "Led<2>" LOC = "U15" | IOSTANDARD = "LVCMOS33"; #Bank = 2, Pin name = IO_L5P, Sch name = LD2
NET "Led<3>" LOC = "V15" | IOSTANDARD = "LVCMOS33"; #Bank = 2, Pin name = IO_L5N, Sch name = LD3
NET "Led<4>" LOC = "M11" | IOSTANDARD = "LVCMOS33"; #Bank = 2, Pin name = IO_L15P, Sch name = LD4
NET "Led<5>" LOC = "N11" | IOSTANDARD = "LVCMOS33"; #Bank = 2, Pin name = IO_L15N, Sch name = LD5
NET "Led<6>" LOC = "R11" | IOSTANDARD = "LVCMOS33"; #Bank = 2, Pin name = IO_L16P, Sch name = LD6
NET "Led<7>" LOC = "T11" | IOSTANDARD = "LVCMOS33"; #Bank = 2, Pin name = IO_L16N_VREF, Sch name = LD7
## 12 pin connectors
NET "dn" LOC = "G11" | IOSTANDARD = "LVCMOS33";
NET "dp" LOC = "F10" | IOSTANDARD = "LVCMOS33";
usb_phy.v
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 PHY ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// [email protected] ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
//// www.asics.ws ////
//// [email protected] ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ''AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: usb_phy.v,v 1.4 2003-10-21 05:58:40 rudi Exp $
//
// $Date: 2003-10-21 05:58:40 $
// $Revision: 1.4 $
// $Author: rudi $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.3 2003/10/19 17:40:13 rudi
// - Made core more robust against line noise
// - Added Error Checking and Reporting
// (See README.txt for more info)
//
// Revision 1.2 2002/09/16 16:06:37 rudi
// Changed top level name to be consistent ...
//
// Revision 1.1.1.1 2002/09/16 14:26:59 rudi
// Created Directory Structure
//
//
//
//
//
//
//
//
'include "timescale.v"
module usb_phy(clk, rst, phy_tx_mode, usb_rst,
// Transciever Interface
txdp, txdn, txoe,
rxd, rxdp, rxdn,
// UTMI Interface
DataOut_i, TxValid_i, TxReady_o, RxValid_o,
RxActive_o, RxError_o, DataIn_o, LineState_o
);
input clk;
input rst;
input phy_tx_mode;
output usb_rst;
output txdp, txdn, txoe;
input rxd, rxdp, rxdn;
input [7:0] DataOut_i;
input TxValid_i;
output TxReady_o;
output [7:0] DataIn_o;
output RxValid_o;
output RxActive_o;
output RxError_o;
output [1:0] LineState_o;
///////////////////////////////////////////////////////////////////
//
// Local Wires and Registers
//
reg [4:0] rst_cnt;
reg usb_rst;
wire fs_ce;
wire rst;
///////////////////////////////////////////////////////////////////
//
// Misc Logic
//
///////////////////////////////////////////////////////////////////
//
// TX Phy
//
usb_tx_phy i_tx_phy(
.clk( clk ),
.rst( rst ),
.fs_ce( fs_ce ),
.phy_mode( phy_tx_mode ),
// Transciever Interface
.txdp( txdp ),
.txdn( txdn ),
.txoe( txoe ),
// UTMI Interface
.DataOut_i( DataOut_i ),
.TxValid_i( TxValid_i ),
.TxReady_o( TxReady_o )
);
///////////////////////////////////////////////////////////////////
//
// RX Phy and DPLL
//
usb_rx_phy i_rx_phy(
.clk( clk ),
.rst( rst ),
.fs_ce( fs_ce ),
// Transciever Interface
.rxd( rxd ),
.rxdp( rxdp ),
.rxdn( rxdn ),
// UTMI Interface
.DataIn_o( DataIn_o ),
.RxValid_o( RxValid_o ),
.RxActive_o( RxActive_o ),
.RxError_o( RxError_o ),
.RxEn_i( txoe ),
.LineState( LineState_o )
);
///////////////////////////////////////////////////////////////////
//
// Generate an USB Reset is we see SE0 for at least 2.5uS
//
'ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
'else
always @(posedge clk)
'endif
if(!rst) rst_cnt <= 5'h0;
else
if(LineState_o != 2'h0) rst_cnt <= 5'h0;
else
if(!usb_rst && fs_ce) rst_cnt <= rst_cnt + 5'h1;
always @(posedge clk)
usb_rst <= (rst_cnt == 5'h1f);
endmodule
Se omitieron los módulos USB tx y rx phy