URL
https://opencores.org/ocsvn/usb_device_core/usb_device_core/trunk
Subversion Repositories usb_device_core
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 4 to Rev 5
- ↔ Reverse comparison
Rev 4 → Rev 5
/usb_device_core/trunk/rtl/usbf_sie.v
File deleted
/usb_device_core/trunk/rtl/usbf_fifo.v
File deleted
/usb_device_core/trunk/rtl/phy/usb_rx_phy.v
File deleted
/usb_device_core/trunk/rtl/phy/usb_tx_phy.v
File deleted
/usb_device_core/trunk/rtl/phy/README.txt
File deleted
/usb_device_core/trunk/rtl/phy/usb_phy.v
File deleted
/usb_device_core/trunk/rtl/usbf_crc16.v
File deleted
/usb_device_core/trunk/rtl/usbf_device.v
File deleted
/usb_device_core/trunk/README.md
0,0 → 1,131
### USB Peripheral Interface |
|
Github: [http://github.com/ultraembedded/cores](https://github.com/ultraembedded/cores/tree/master/usb_device) |
|
This component is a simple USB Peripheral Interface (Device) implementation with an AXI4-Lite slave register interface, and |
with a UTMI interface for connection to a USB PHY. |
|
It has been designed to support USB2.0, but currently has been only tested in Full Speed peripheral mode (12Mbit/s). |
|
##### Features |
* USB 2.0 Device mode support. |
* Simple register data read/write interface (low performance / not DMA based). |
* UTMI PHY interface (see my UTMI to ULPI Conversion wrapper project to allow connection to a ULPI PHY e.g. USB3300) |
* Current build configuration has 4 endpoints |
|
##### Limitations |
* Only tested for USB-FS (Full Speed / 12Mbit/s) only. |
* AXI4-L address and data must arrive in the same cycle. |
|
##### Software |
Provided with a USB-CDC test stack (USB Serial port) with loopback/echo example. |
|
To make this functional on your platform; |
* Set USB_DEV_BASE to the correct address for the peripheral. |
* Implement the millisecond timer functions in timer.h. |
* Change USB_BYTE_SWAP16 in usbf_defs.h if your CPU is big endian. |
|
##### Testing |
Verified under simulation then tested on FPGA as a USB-CDC mode peripheral (USB serial port) against Linux & Windows PCs. |
|
##### References |
* [USB 2.0 Specification](https://usb.org/developers/docs/usb20_docs) |
* [UTMI Specification](https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/usb2-transceiver-macrocell-interface-specification.pdf) |
* [USB Made Simple](http://www.usbmadesimple.co.uk/) |
* [UTMI to ULPI Conversion](https://github.com/ultraembedded/cores/tree/master/ulpi_wrapper) |
|
##### Register Map |
|
| Offset | Name | Description | |
| ------ | ---- | ------------- | |
| 0x00 | USB_FUNC_CTRL | [RW] Control Register | |
| 0x04 | USB_FUNC_STAT | [RW] Status Register | |
| 0x08 | USB_FUNC_ADDR | [RW] Address Register | |
| 0x0c | USB_EP0_CFG | [RW] Endpoint 0 Configuration | |
| 0x10 | USB_EP0_TX_CTRL | [RW] Endpoint 0 Tx Control | |
| 0x14 | USB_EP0_RX_CTRL | [W] Endpoint 0 Rx Control | |
| 0x18 | USB_EP0_STS | [R] Endpoint 0 status | |
| 0x1c | USB_EP0_DATA | [RW] Endpoint Data FIFO | |
| 0x20 | USB_EP1_CFG | [RW] Endpoint 1 Configuration | |
| 0x24 | USB_EP1_TX_CTRL | [RW] Endpoint 1 Tx Control | |
| 0x28 | USB_EP1_RX_CTRL | [W] Endpoint 1 Rx Control | |
| 0x2c | USB_EP1_STS | [R] Endpoint 1 status | |
| 0x30 | USB_EP1_DATA | [RW] Endpoint Data FIFO | |
| 0x34 | USB_EP2_CFG | [RW] Endpoint 2 Configuration | |
| 0x38 | USB_EP2_TX_CTRL | [RW] Endpoint 2 Tx Control | |
| 0x3c | USB_EP2_RX_CTRL | [W] Endpoint 2 Rx Control | |
| 0x40 | USB_EP2_STS | [R] Endpoint 2 status | |
| 0x44 | USB_EP2_DATA | [RW] Endpoint Data FIFO | |
| 0x48 | USB_EP3_CFG | [RW] Endpoint 3 Configuration | |
| 0x4c | USB_EP3_TX_CTRL | [RW] Endpoint 3 Tx Control | |
| 0x50 | USB_EP3_RX_CTRL | [W] Endpoint 3 Rx Control | |
| 0x54 | USB_EP3_STS | [R] Endpoint 3 status | |
| 0x58 | USB_EP3_DATA | [RW] Endpoint Data FIFO | |
|
##### Register: USB_FUNC_CTRL |
|
| Bits | Name | Description | |
| ---- | ---- | -------------- | |
| 8 | HS_CHIRP_EN | High-speed Chirp Enable | |
| 7 | PHY_DMPULLDOWN | UTMI PHY D+ Pulldown Enable | |
| 6 | PHY_DPPULLDOWN | UTMI PHY D+ Pulldown Enable | |
| 5 | PHY_TERMSELECT | UTMI PHY Termination Select | |
| 4:3 | PHY_XCVRSELECT | UTMI PHY Transceiver Select | |
| 2:1 | PHY_OPMODE | UTMI PHY Output Mode | |
| 0 | INT_EN_SOF | Interrupt enable - SOF reception | |
|
##### Register: USB_FUNC_STAT |
|
| Bits | Name | Description | |
| ---- | ---- | -------------- | |
| 13 | RST | USB Reset Detected (cleared on write) | |
| 12:11 | LINESTATE | USB line state (bit 1 = D+, bit 0 = D-) | |
| 10:0 | FRAME | Frame number | |
|
##### Register: USB_FUNC_ADDR |
|
| Bits | Name | Description | |
| ---- | ---- | -------------- | |
| 6:0 | DEV_ADDR | Device address | |
|
##### Register: USB_EPx_CFG |
|
| Bits | Name | Description | |
| ---- | ---- | -------------- | |
| 3 | INT_RX | Interrupt on Rx ready | |
| 2 | INT_TX | Interrupt on Tx complete | |
| 1 | STALL_EP | Stall endpoint | |
| 0 | ISO | Isochronous endpoint | |
|
##### Register: USB_EPx_TX_CTRL |
|
| Bits | Name | Description | |
| ---- | ---- | -------------- | |
| 17 | TX_FLUSH | Invalidate Tx buffer | |
| 16 | TX_START | Transmit start - enable transmit of endpoint data | |
| 10:0 | TX_LEN | Transmit length | |
|
##### Register: USB_EPx_RX_CTRL |
|
| Bits | Name | Description | |
| ---- | ---- | -------------- | |
| 1 | RX_FLUSH | Invalidate Rx buffer | |
| 0 | RX_ACCEPT | Receive data accepted (read) | |
|
##### Register: USB_EPx_STS |
|
| Bits | Name | Description | |
| ---- | ---- | -------------- | |
| 20 | TX_ERR | Transmit error (buffer underrun) | |
| 19 | TX_BUSY | Transmit busy (active) | |
| 18 | RX_ERR | Receive error - CRC mismatch or buffer overflow | |
| 17 | RX_SETUP | SETUP request received | |
| 16 | RX_READY | Receive ready (data available) | |
| 10:0 | RX_COUNT | Endpoint received length (RD) | |
|
##### Register: USB_EPx_DATA |
|
| Bits | Name | Description | |
| ---- | ---- | -------------- | |
| 7:0 | DATA | Read or write from Rx or Tx endpoint FIFO | |
|
/usb_device_core/trunk/src_v/usbf_crc16.v
0,0 → 1,79
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
|
module usbf_crc16 |
( |
// Inputs |
input [ 15:0] crc_in_i |
,input [ 7:0] din_i |
|
// Outputs |
,output [ 15:0] crc_out_o |
); |
|
|
|
//----------------------------------------------------------------- |
// Logic |
//----------------------------------------------------------------- |
assign crc_out_o[15] = din_i[0] ^ din_i[1] ^ din_i[2] ^ din_i[3] ^ din_i[4] ^ din_i[5] ^ din_i[6] ^ din_i[7] ^ |
crc_in_i[7] ^ crc_in_i[6] ^ crc_in_i[5] ^ crc_in_i[4] ^ crc_in_i[3] ^ crc_in_i[2] ^ crc_in_i[1] ^ crc_in_i[0]; |
assign crc_out_o[14] = din_i[0] ^ din_i[1] ^ din_i[2] ^ din_i[3] ^ din_i[4] ^ din_i[5] ^ din_i[6] ^ |
crc_in_i[6] ^ crc_in_i[5] ^ crc_in_i[4] ^ crc_in_i[3] ^ crc_in_i[2] ^ crc_in_i[1] ^ crc_in_i[0]; |
assign crc_out_o[13] = din_i[6] ^ din_i[7] ^ |
crc_in_i[7] ^ crc_in_i[6]; |
assign crc_out_o[12] = din_i[5] ^ din_i[6] ^ |
crc_in_i[6] ^ crc_in_i[5]; |
assign crc_out_o[11] = din_i[4] ^ din_i[5] ^ |
crc_in_i[5] ^ crc_in_i[4]; |
assign crc_out_o[10] = din_i[3] ^ din_i[4] ^ |
crc_in_i[4] ^ crc_in_i[3]; |
assign crc_out_o[9] = din_i[2] ^ din_i[3] ^ |
crc_in_i[3] ^ crc_in_i[2]; |
assign crc_out_o[8] = din_i[1] ^ din_i[2] ^ |
crc_in_i[2] ^ crc_in_i[1]; |
assign crc_out_o[7] = din_i[0] ^ din_i[1] ^ |
crc_in_i[15] ^ crc_in_i[1] ^ crc_in_i[0]; |
assign crc_out_o[6] = din_i[0] ^ |
crc_in_i[14] ^ crc_in_i[0]; |
assign crc_out_o[5] = crc_in_i[13]; |
assign crc_out_o[4] = crc_in_i[12]; |
assign crc_out_o[3] = crc_in_i[11]; |
assign crc_out_o[2] = crc_in_i[10]; |
assign crc_out_o[1] = crc_in_i[9]; |
assign crc_out_o[0] = din_i[0] ^ din_i[1] ^ din_i[2] ^ din_i[3] ^ din_i[4] ^ din_i[5] ^ din_i[6] ^ din_i[7] ^ |
crc_in_i[8] ^ crc_in_i[7] ^ crc_in_i[6] ^ crc_in_i[5] ^ crc_in_i[4] ^ crc_in_i[3] ^ crc_in_i[2] ^ crc_in_i[1] ^ crc_in_i[0]; |
|
|
endmodule |
/usb_device_core/trunk/src_v/usbf_defs.v
0,0 → 1,60
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
//----------------------------------------------------------------- |
// Definitions |
//----------------------------------------------------------------- |
|
// Tokens |
`define PID_OUT 8'hE1 |
`define PID_IN 8'h69 |
`define PID_SOF 8'hA5 |
`define PID_SETUP 8'h2D |
|
// Data |
`define PID_DATA0 8'hC3 |
`define PID_DATA1 8'h4B |
`define PID_DATA2 8'h87 |
`define PID_MDATA 8'h0F |
|
// Handshake |
`define PID_ACK 8'hD2 |
`define PID_NAK 8'h5A |
`define PID_STALL 8'h1E |
`define PID_NYET 8'h96 |
|
// Special |
`define PID_PRE 8'h3C |
`define PID_ERR 8'h3C |
`define PID_SPLIT 8'h78 |
`define PID_PING 8'hB4 |
/usb_device_core/trunk/src_v/usbf_device.v
0,0 → 1,1896
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
|
`include "usbf_device_defs.v" |
|
//----------------------------------------------------------------- |
// Module: USB Device Endpoint |
//----------------------------------------------------------------- |
module usbf_device |
( |
// Inputs |
input clk_i |
,input rst_i |
,input cfg_awvalid_i |
,input [31:0] cfg_awaddr_i |
,input cfg_wvalid_i |
,input [31:0] cfg_wdata_i |
,input [3:0] cfg_wstrb_i |
,input cfg_bready_i |
,input cfg_arvalid_i |
,input [31:0] cfg_araddr_i |
,input cfg_rready_i |
,input [7:0] utmi_data_in_i |
,input utmi_txready_i |
,input utmi_rxvalid_i |
,input utmi_rxactive_i |
,input utmi_rxerror_i |
,input [1:0] utmi_linestate_i |
|
// Outputs |
,output cfg_awready_o |
,output cfg_wready_o |
,output cfg_bvalid_o |
,output [1:0] cfg_bresp_o |
,output cfg_arready_o |
,output cfg_rvalid_o |
,output [31:0] cfg_rdata_o |
,output [1:0] cfg_rresp_o |
,output intr_o |
,output [7:0] utmi_data_out_o |
,output utmi_txvalid_o |
,output [1:0] utmi_op_mode_o |
,output [1:0] utmi_xcvrselect_o |
,output utmi_termselect_o |
,output utmi_dppulldown_o |
,output utmi_dmpulldown_o |
); |
|
//----------------------------------------------------------------- |
// Retime write data |
//----------------------------------------------------------------- |
reg [31:0] wr_data_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
wr_data_q <= 32'b0; |
else |
wr_data_q <= cfg_wdata_i; |
|
//----------------------------------------------------------------- |
// Request Logic |
//----------------------------------------------------------------- |
wire read_en_w = cfg_arvalid_i & cfg_arready_o; |
wire write_en_w = cfg_awvalid_i & cfg_awready_o; |
|
//----------------------------------------------------------------- |
// Accept Logic |
//----------------------------------------------------------------- |
assign cfg_arready_o = ~cfg_rvalid_o; |
assign cfg_awready_o = ~cfg_bvalid_o && ~cfg_arvalid_i; |
assign cfg_wready_o = cfg_awready_o; |
|
|
//----------------------------------------------------------------- |
// Register usb_func_ctrl |
//----------------------------------------------------------------- |
reg usb_func_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_CTRL)) |
usb_func_ctrl_wr_q <= 1'b1; |
else |
usb_func_ctrl_wr_q <= 1'b0; |
|
// usb_func_ctrl_hs_chirp_en [internal] |
reg usb_func_ctrl_hs_chirp_en_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_ctrl_hs_chirp_en_q <= 1'd`USB_FUNC_CTRL_HS_CHIRP_EN_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_CTRL)) |
usb_func_ctrl_hs_chirp_en_q <= cfg_wdata_i[`USB_FUNC_CTRL_HS_CHIRP_EN_R]; |
|
wire usb_func_ctrl_hs_chirp_en_out_w = usb_func_ctrl_hs_chirp_en_q; |
|
|
// usb_func_ctrl_phy_dmpulldown [internal] |
reg usb_func_ctrl_phy_dmpulldown_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_ctrl_phy_dmpulldown_q <= 1'd`USB_FUNC_CTRL_PHY_DMPULLDOWN_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_CTRL)) |
usb_func_ctrl_phy_dmpulldown_q <= cfg_wdata_i[`USB_FUNC_CTRL_PHY_DMPULLDOWN_R]; |
|
wire usb_func_ctrl_phy_dmpulldown_out_w = usb_func_ctrl_phy_dmpulldown_q; |
|
|
// usb_func_ctrl_phy_dppulldown [internal] |
reg usb_func_ctrl_phy_dppulldown_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_ctrl_phy_dppulldown_q <= 1'd`USB_FUNC_CTRL_PHY_DPPULLDOWN_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_CTRL)) |
usb_func_ctrl_phy_dppulldown_q <= cfg_wdata_i[`USB_FUNC_CTRL_PHY_DPPULLDOWN_R]; |
|
wire usb_func_ctrl_phy_dppulldown_out_w = usb_func_ctrl_phy_dppulldown_q; |
|
|
// usb_func_ctrl_phy_termselect [internal] |
reg usb_func_ctrl_phy_termselect_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_ctrl_phy_termselect_q <= 1'd`USB_FUNC_CTRL_PHY_TERMSELECT_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_CTRL)) |
usb_func_ctrl_phy_termselect_q <= cfg_wdata_i[`USB_FUNC_CTRL_PHY_TERMSELECT_R]; |
|
wire usb_func_ctrl_phy_termselect_out_w = usb_func_ctrl_phy_termselect_q; |
|
|
// usb_func_ctrl_phy_xcvrselect [internal] |
reg [1:0] usb_func_ctrl_phy_xcvrselect_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_ctrl_phy_xcvrselect_q <= 2'd`USB_FUNC_CTRL_PHY_XCVRSELECT_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_CTRL)) |
usb_func_ctrl_phy_xcvrselect_q <= cfg_wdata_i[`USB_FUNC_CTRL_PHY_XCVRSELECT_R]; |
|
wire [1:0] usb_func_ctrl_phy_xcvrselect_out_w = usb_func_ctrl_phy_xcvrselect_q; |
|
|
// usb_func_ctrl_phy_opmode [internal] |
reg [1:0] usb_func_ctrl_phy_opmode_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_ctrl_phy_opmode_q <= 2'd`USB_FUNC_CTRL_PHY_OPMODE_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_CTRL)) |
usb_func_ctrl_phy_opmode_q <= cfg_wdata_i[`USB_FUNC_CTRL_PHY_OPMODE_R]; |
|
wire [1:0] usb_func_ctrl_phy_opmode_out_w = usb_func_ctrl_phy_opmode_q; |
|
|
// usb_func_ctrl_int_en_sof [internal] |
reg usb_func_ctrl_int_en_sof_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_ctrl_int_en_sof_q <= 1'd`USB_FUNC_CTRL_INT_EN_SOF_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_CTRL)) |
usb_func_ctrl_int_en_sof_q <= cfg_wdata_i[`USB_FUNC_CTRL_INT_EN_SOF_R]; |
|
wire usb_func_ctrl_int_en_sof_out_w = usb_func_ctrl_int_en_sof_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_func_stat |
//----------------------------------------------------------------- |
reg usb_func_stat_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_stat_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_STAT)) |
usb_func_stat_wr_q <= 1'b1; |
else |
usb_func_stat_wr_q <= 1'b0; |
|
// usb_func_stat_rst [external] |
wire usb_func_stat_rst_out_w = wr_data_q[`USB_FUNC_STAT_RST_R]; |
|
|
// usb_func_stat_linestate [external] |
wire [1:0] usb_func_stat_linestate_out_w = wr_data_q[`USB_FUNC_STAT_LINESTATE_R]; |
|
|
// usb_func_stat_frame [external] |
wire [10:0] usb_func_stat_frame_out_w = wr_data_q[`USB_FUNC_STAT_FRAME_R]; |
|
|
//----------------------------------------------------------------- |
// Register usb_func_addr |
//----------------------------------------------------------------- |
reg usb_func_addr_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_addr_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_ADDR)) |
usb_func_addr_wr_q <= 1'b1; |
else |
usb_func_addr_wr_q <= 1'b0; |
|
// usb_func_addr_dev_addr [internal] |
reg [6:0] usb_func_addr_dev_addr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_func_addr_dev_addr_q <= 7'd`USB_FUNC_ADDR_DEV_ADDR_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_FUNC_ADDR)) |
usb_func_addr_dev_addr_q <= cfg_wdata_i[`USB_FUNC_ADDR_DEV_ADDR_R]; |
|
wire [6:0] usb_func_addr_dev_addr_out_w = usb_func_addr_dev_addr_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep0_cfg |
//----------------------------------------------------------------- |
reg usb_ep0_cfg_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_cfg_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_CFG)) |
usb_ep0_cfg_wr_q <= 1'b1; |
else |
usb_ep0_cfg_wr_q <= 1'b0; |
|
// usb_ep0_cfg_int_rx [internal] |
reg usb_ep0_cfg_int_rx_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_cfg_int_rx_q <= 1'd`USB_EP0_CFG_INT_RX_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_CFG)) |
usb_ep0_cfg_int_rx_q <= cfg_wdata_i[`USB_EP0_CFG_INT_RX_R]; |
|
wire usb_ep0_cfg_int_rx_out_w = usb_ep0_cfg_int_rx_q; |
|
|
// usb_ep0_cfg_int_tx [internal] |
reg usb_ep0_cfg_int_tx_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_cfg_int_tx_q <= 1'd`USB_EP0_CFG_INT_TX_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_CFG)) |
usb_ep0_cfg_int_tx_q <= cfg_wdata_i[`USB_EP0_CFG_INT_TX_R]; |
|
wire usb_ep0_cfg_int_tx_out_w = usb_ep0_cfg_int_tx_q; |
|
|
// usb_ep0_cfg_stall_ep [clearable] |
reg usb_ep0_cfg_stall_ep_q; |
|
wire usb_ep0_cfg_stall_ep_ack_in_w; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_cfg_stall_ep_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_CFG)) |
usb_ep0_cfg_stall_ep_q <= cfg_wdata_i[`USB_EP0_CFG_STALL_EP_R]; |
else if (usb_ep0_cfg_stall_ep_ack_in_w) |
usb_ep0_cfg_stall_ep_q <= 1'b0; |
|
wire usb_ep0_cfg_stall_ep_out_w = usb_ep0_cfg_stall_ep_q; |
|
|
// usb_ep0_cfg_iso [internal] |
reg usb_ep0_cfg_iso_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_cfg_iso_q <= 1'd`USB_EP0_CFG_ISO_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_CFG)) |
usb_ep0_cfg_iso_q <= cfg_wdata_i[`USB_EP0_CFG_ISO_R]; |
|
wire usb_ep0_cfg_iso_out_w = usb_ep0_cfg_iso_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep0_tx_ctrl |
//----------------------------------------------------------------- |
reg usb_ep0_tx_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_tx_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_TX_CTRL)) |
usb_ep0_tx_ctrl_wr_q <= 1'b1; |
else |
usb_ep0_tx_ctrl_wr_q <= 1'b0; |
|
// usb_ep0_tx_ctrl_tx_flush [auto_clr] |
reg usb_ep0_tx_ctrl_tx_flush_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_tx_ctrl_tx_flush_q <= 1'd`USB_EP0_TX_CTRL_TX_FLUSH_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_TX_CTRL)) |
usb_ep0_tx_ctrl_tx_flush_q <= cfg_wdata_i[`USB_EP0_TX_CTRL_TX_FLUSH_R]; |
else |
usb_ep0_tx_ctrl_tx_flush_q <= 1'd`USB_EP0_TX_CTRL_TX_FLUSH_DEFAULT; |
|
wire usb_ep0_tx_ctrl_tx_flush_out_w = usb_ep0_tx_ctrl_tx_flush_q; |
|
|
// usb_ep0_tx_ctrl_tx_start [auto_clr] |
reg usb_ep0_tx_ctrl_tx_start_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_tx_ctrl_tx_start_q <= 1'd`USB_EP0_TX_CTRL_TX_START_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_TX_CTRL)) |
usb_ep0_tx_ctrl_tx_start_q <= cfg_wdata_i[`USB_EP0_TX_CTRL_TX_START_R]; |
else |
usb_ep0_tx_ctrl_tx_start_q <= 1'd`USB_EP0_TX_CTRL_TX_START_DEFAULT; |
|
wire usb_ep0_tx_ctrl_tx_start_out_w = usb_ep0_tx_ctrl_tx_start_q; |
|
|
// usb_ep0_tx_ctrl_tx_len [internal] |
reg [10:0] usb_ep0_tx_ctrl_tx_len_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_tx_ctrl_tx_len_q <= 11'd`USB_EP0_TX_CTRL_TX_LEN_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_TX_CTRL)) |
usb_ep0_tx_ctrl_tx_len_q <= cfg_wdata_i[`USB_EP0_TX_CTRL_TX_LEN_R]; |
|
wire [10:0] usb_ep0_tx_ctrl_tx_len_out_w = usb_ep0_tx_ctrl_tx_len_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep0_rx_ctrl |
//----------------------------------------------------------------- |
reg usb_ep0_rx_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_rx_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_RX_CTRL)) |
usb_ep0_rx_ctrl_wr_q <= 1'b1; |
else |
usb_ep0_rx_ctrl_wr_q <= 1'b0; |
|
// usb_ep0_rx_ctrl_rx_flush [auto_clr] |
reg usb_ep0_rx_ctrl_rx_flush_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_rx_ctrl_rx_flush_q <= 1'd`USB_EP0_RX_CTRL_RX_FLUSH_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_RX_CTRL)) |
usb_ep0_rx_ctrl_rx_flush_q <= cfg_wdata_i[`USB_EP0_RX_CTRL_RX_FLUSH_R]; |
else |
usb_ep0_rx_ctrl_rx_flush_q <= 1'd`USB_EP0_RX_CTRL_RX_FLUSH_DEFAULT; |
|
wire usb_ep0_rx_ctrl_rx_flush_out_w = usb_ep0_rx_ctrl_rx_flush_q; |
|
|
// usb_ep0_rx_ctrl_rx_accept [auto_clr] |
reg usb_ep0_rx_ctrl_rx_accept_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_rx_ctrl_rx_accept_q <= 1'd`USB_EP0_RX_CTRL_RX_ACCEPT_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_RX_CTRL)) |
usb_ep0_rx_ctrl_rx_accept_q <= cfg_wdata_i[`USB_EP0_RX_CTRL_RX_ACCEPT_R]; |
else |
usb_ep0_rx_ctrl_rx_accept_q <= 1'd`USB_EP0_RX_CTRL_RX_ACCEPT_DEFAULT; |
|
wire usb_ep0_rx_ctrl_rx_accept_out_w = usb_ep0_rx_ctrl_rx_accept_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep0_sts |
//----------------------------------------------------------------- |
reg usb_ep0_sts_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_sts_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_STS)) |
usb_ep0_sts_wr_q <= 1'b1; |
else |
usb_ep0_sts_wr_q <= 1'b0; |
|
|
|
|
|
|
|
//----------------------------------------------------------------- |
// Register usb_ep0_data |
//----------------------------------------------------------------- |
reg usb_ep0_data_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep0_data_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP0_DATA)) |
usb_ep0_data_wr_q <= 1'b1; |
else |
usb_ep0_data_wr_q <= 1'b0; |
|
// usb_ep0_data_data [external] |
wire [7:0] usb_ep0_data_data_out_w = wr_data_q[`USB_EP0_DATA_DATA_R]; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep1_cfg |
//----------------------------------------------------------------- |
reg usb_ep1_cfg_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_cfg_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_CFG)) |
usb_ep1_cfg_wr_q <= 1'b1; |
else |
usb_ep1_cfg_wr_q <= 1'b0; |
|
// usb_ep1_cfg_int_rx [internal] |
reg usb_ep1_cfg_int_rx_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_cfg_int_rx_q <= 1'd`USB_EP1_CFG_INT_RX_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_CFG)) |
usb_ep1_cfg_int_rx_q <= cfg_wdata_i[`USB_EP1_CFG_INT_RX_R]; |
|
wire usb_ep1_cfg_int_rx_out_w = usb_ep1_cfg_int_rx_q; |
|
|
// usb_ep1_cfg_int_tx [internal] |
reg usb_ep1_cfg_int_tx_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_cfg_int_tx_q <= 1'd`USB_EP1_CFG_INT_TX_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_CFG)) |
usb_ep1_cfg_int_tx_q <= cfg_wdata_i[`USB_EP1_CFG_INT_TX_R]; |
|
wire usb_ep1_cfg_int_tx_out_w = usb_ep1_cfg_int_tx_q; |
|
|
// usb_ep1_cfg_stall_ep [clearable] |
reg usb_ep1_cfg_stall_ep_q; |
|
wire usb_ep1_cfg_stall_ep_ack_in_w; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_cfg_stall_ep_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_CFG)) |
usb_ep1_cfg_stall_ep_q <= cfg_wdata_i[`USB_EP1_CFG_STALL_EP_R]; |
else if (usb_ep1_cfg_stall_ep_ack_in_w) |
usb_ep1_cfg_stall_ep_q <= 1'b0; |
|
wire usb_ep1_cfg_stall_ep_out_w = usb_ep1_cfg_stall_ep_q; |
|
|
// usb_ep1_cfg_iso [internal] |
reg usb_ep1_cfg_iso_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_cfg_iso_q <= 1'd`USB_EP1_CFG_ISO_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_CFG)) |
usb_ep1_cfg_iso_q <= cfg_wdata_i[`USB_EP1_CFG_ISO_R]; |
|
wire usb_ep1_cfg_iso_out_w = usb_ep1_cfg_iso_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep1_tx_ctrl |
//----------------------------------------------------------------- |
reg usb_ep1_tx_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_tx_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_TX_CTRL)) |
usb_ep1_tx_ctrl_wr_q <= 1'b1; |
else |
usb_ep1_tx_ctrl_wr_q <= 1'b0; |
|
// usb_ep1_tx_ctrl_tx_flush [auto_clr] |
reg usb_ep1_tx_ctrl_tx_flush_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_tx_ctrl_tx_flush_q <= 1'd`USB_EP1_TX_CTRL_TX_FLUSH_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_TX_CTRL)) |
usb_ep1_tx_ctrl_tx_flush_q <= cfg_wdata_i[`USB_EP1_TX_CTRL_TX_FLUSH_R]; |
else |
usb_ep1_tx_ctrl_tx_flush_q <= 1'd`USB_EP1_TX_CTRL_TX_FLUSH_DEFAULT; |
|
wire usb_ep1_tx_ctrl_tx_flush_out_w = usb_ep1_tx_ctrl_tx_flush_q; |
|
|
// usb_ep1_tx_ctrl_tx_start [auto_clr] |
reg usb_ep1_tx_ctrl_tx_start_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_tx_ctrl_tx_start_q <= 1'd`USB_EP1_TX_CTRL_TX_START_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_TX_CTRL)) |
usb_ep1_tx_ctrl_tx_start_q <= cfg_wdata_i[`USB_EP1_TX_CTRL_TX_START_R]; |
else |
usb_ep1_tx_ctrl_tx_start_q <= 1'd`USB_EP1_TX_CTRL_TX_START_DEFAULT; |
|
wire usb_ep1_tx_ctrl_tx_start_out_w = usb_ep1_tx_ctrl_tx_start_q; |
|
|
// usb_ep1_tx_ctrl_tx_len [internal] |
reg [10:0] usb_ep1_tx_ctrl_tx_len_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_tx_ctrl_tx_len_q <= 11'd`USB_EP1_TX_CTRL_TX_LEN_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_TX_CTRL)) |
usb_ep1_tx_ctrl_tx_len_q <= cfg_wdata_i[`USB_EP1_TX_CTRL_TX_LEN_R]; |
|
wire [10:0] usb_ep1_tx_ctrl_tx_len_out_w = usb_ep1_tx_ctrl_tx_len_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep1_rx_ctrl |
//----------------------------------------------------------------- |
reg usb_ep1_rx_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_rx_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_RX_CTRL)) |
usb_ep1_rx_ctrl_wr_q <= 1'b1; |
else |
usb_ep1_rx_ctrl_wr_q <= 1'b0; |
|
// usb_ep1_rx_ctrl_rx_flush [auto_clr] |
reg usb_ep1_rx_ctrl_rx_flush_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_rx_ctrl_rx_flush_q <= 1'd`USB_EP1_RX_CTRL_RX_FLUSH_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_RX_CTRL)) |
usb_ep1_rx_ctrl_rx_flush_q <= cfg_wdata_i[`USB_EP1_RX_CTRL_RX_FLUSH_R]; |
else |
usb_ep1_rx_ctrl_rx_flush_q <= 1'd`USB_EP1_RX_CTRL_RX_FLUSH_DEFAULT; |
|
wire usb_ep1_rx_ctrl_rx_flush_out_w = usb_ep1_rx_ctrl_rx_flush_q; |
|
|
// usb_ep1_rx_ctrl_rx_accept [auto_clr] |
reg usb_ep1_rx_ctrl_rx_accept_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_rx_ctrl_rx_accept_q <= 1'd`USB_EP1_RX_CTRL_RX_ACCEPT_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_RX_CTRL)) |
usb_ep1_rx_ctrl_rx_accept_q <= cfg_wdata_i[`USB_EP1_RX_CTRL_RX_ACCEPT_R]; |
else |
usb_ep1_rx_ctrl_rx_accept_q <= 1'd`USB_EP1_RX_CTRL_RX_ACCEPT_DEFAULT; |
|
wire usb_ep1_rx_ctrl_rx_accept_out_w = usb_ep1_rx_ctrl_rx_accept_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep1_sts |
//----------------------------------------------------------------- |
reg usb_ep1_sts_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_sts_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_STS)) |
usb_ep1_sts_wr_q <= 1'b1; |
else |
usb_ep1_sts_wr_q <= 1'b0; |
|
|
|
|
|
|
|
//----------------------------------------------------------------- |
// Register usb_ep1_data |
//----------------------------------------------------------------- |
reg usb_ep1_data_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep1_data_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP1_DATA)) |
usb_ep1_data_wr_q <= 1'b1; |
else |
usb_ep1_data_wr_q <= 1'b0; |
|
// usb_ep1_data_data [external] |
wire [7:0] usb_ep1_data_data_out_w = wr_data_q[`USB_EP1_DATA_DATA_R]; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep2_cfg |
//----------------------------------------------------------------- |
reg usb_ep2_cfg_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_cfg_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_CFG)) |
usb_ep2_cfg_wr_q <= 1'b1; |
else |
usb_ep2_cfg_wr_q <= 1'b0; |
|
// usb_ep2_cfg_int_rx [internal] |
reg usb_ep2_cfg_int_rx_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_cfg_int_rx_q <= 1'd`USB_EP2_CFG_INT_RX_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_CFG)) |
usb_ep2_cfg_int_rx_q <= cfg_wdata_i[`USB_EP2_CFG_INT_RX_R]; |
|
wire usb_ep2_cfg_int_rx_out_w = usb_ep2_cfg_int_rx_q; |
|
|
// usb_ep2_cfg_int_tx [internal] |
reg usb_ep2_cfg_int_tx_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_cfg_int_tx_q <= 1'd`USB_EP2_CFG_INT_TX_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_CFG)) |
usb_ep2_cfg_int_tx_q <= cfg_wdata_i[`USB_EP2_CFG_INT_TX_R]; |
|
wire usb_ep2_cfg_int_tx_out_w = usb_ep2_cfg_int_tx_q; |
|
|
// usb_ep2_cfg_stall_ep [clearable] |
reg usb_ep2_cfg_stall_ep_q; |
|
wire usb_ep2_cfg_stall_ep_ack_in_w; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_cfg_stall_ep_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_CFG)) |
usb_ep2_cfg_stall_ep_q <= cfg_wdata_i[`USB_EP2_CFG_STALL_EP_R]; |
else if (usb_ep2_cfg_stall_ep_ack_in_w) |
usb_ep2_cfg_stall_ep_q <= 1'b0; |
|
wire usb_ep2_cfg_stall_ep_out_w = usb_ep2_cfg_stall_ep_q; |
|
|
// usb_ep2_cfg_iso [internal] |
reg usb_ep2_cfg_iso_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_cfg_iso_q <= 1'd`USB_EP2_CFG_ISO_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_CFG)) |
usb_ep2_cfg_iso_q <= cfg_wdata_i[`USB_EP2_CFG_ISO_R]; |
|
wire usb_ep2_cfg_iso_out_w = usb_ep2_cfg_iso_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep2_tx_ctrl |
//----------------------------------------------------------------- |
reg usb_ep2_tx_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_tx_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_TX_CTRL)) |
usb_ep2_tx_ctrl_wr_q <= 1'b1; |
else |
usb_ep2_tx_ctrl_wr_q <= 1'b0; |
|
// usb_ep2_tx_ctrl_tx_flush [auto_clr] |
reg usb_ep2_tx_ctrl_tx_flush_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_tx_ctrl_tx_flush_q <= 1'd`USB_EP2_TX_CTRL_TX_FLUSH_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_TX_CTRL)) |
usb_ep2_tx_ctrl_tx_flush_q <= cfg_wdata_i[`USB_EP2_TX_CTRL_TX_FLUSH_R]; |
else |
usb_ep2_tx_ctrl_tx_flush_q <= 1'd`USB_EP2_TX_CTRL_TX_FLUSH_DEFAULT; |
|
wire usb_ep2_tx_ctrl_tx_flush_out_w = usb_ep2_tx_ctrl_tx_flush_q; |
|
|
// usb_ep2_tx_ctrl_tx_start [auto_clr] |
reg usb_ep2_tx_ctrl_tx_start_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_tx_ctrl_tx_start_q <= 1'd`USB_EP2_TX_CTRL_TX_START_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_TX_CTRL)) |
usb_ep2_tx_ctrl_tx_start_q <= cfg_wdata_i[`USB_EP2_TX_CTRL_TX_START_R]; |
else |
usb_ep2_tx_ctrl_tx_start_q <= 1'd`USB_EP2_TX_CTRL_TX_START_DEFAULT; |
|
wire usb_ep2_tx_ctrl_tx_start_out_w = usb_ep2_tx_ctrl_tx_start_q; |
|
|
// usb_ep2_tx_ctrl_tx_len [internal] |
reg [10:0] usb_ep2_tx_ctrl_tx_len_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_tx_ctrl_tx_len_q <= 11'd`USB_EP2_TX_CTRL_TX_LEN_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_TX_CTRL)) |
usb_ep2_tx_ctrl_tx_len_q <= cfg_wdata_i[`USB_EP2_TX_CTRL_TX_LEN_R]; |
|
wire [10:0] usb_ep2_tx_ctrl_tx_len_out_w = usb_ep2_tx_ctrl_tx_len_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep2_rx_ctrl |
//----------------------------------------------------------------- |
reg usb_ep2_rx_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_rx_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_RX_CTRL)) |
usb_ep2_rx_ctrl_wr_q <= 1'b1; |
else |
usb_ep2_rx_ctrl_wr_q <= 1'b0; |
|
// usb_ep2_rx_ctrl_rx_flush [auto_clr] |
reg usb_ep2_rx_ctrl_rx_flush_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_rx_ctrl_rx_flush_q <= 1'd`USB_EP2_RX_CTRL_RX_FLUSH_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_RX_CTRL)) |
usb_ep2_rx_ctrl_rx_flush_q <= cfg_wdata_i[`USB_EP2_RX_CTRL_RX_FLUSH_R]; |
else |
usb_ep2_rx_ctrl_rx_flush_q <= 1'd`USB_EP2_RX_CTRL_RX_FLUSH_DEFAULT; |
|
wire usb_ep2_rx_ctrl_rx_flush_out_w = usb_ep2_rx_ctrl_rx_flush_q; |
|
|
// usb_ep2_rx_ctrl_rx_accept [auto_clr] |
reg usb_ep2_rx_ctrl_rx_accept_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_rx_ctrl_rx_accept_q <= 1'd`USB_EP2_RX_CTRL_RX_ACCEPT_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_RX_CTRL)) |
usb_ep2_rx_ctrl_rx_accept_q <= cfg_wdata_i[`USB_EP2_RX_CTRL_RX_ACCEPT_R]; |
else |
usb_ep2_rx_ctrl_rx_accept_q <= 1'd`USB_EP2_RX_CTRL_RX_ACCEPT_DEFAULT; |
|
wire usb_ep2_rx_ctrl_rx_accept_out_w = usb_ep2_rx_ctrl_rx_accept_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep2_sts |
//----------------------------------------------------------------- |
reg usb_ep2_sts_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_sts_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_STS)) |
usb_ep2_sts_wr_q <= 1'b1; |
else |
usb_ep2_sts_wr_q <= 1'b0; |
|
|
|
|
|
|
|
//----------------------------------------------------------------- |
// Register usb_ep2_data |
//----------------------------------------------------------------- |
reg usb_ep2_data_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep2_data_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP2_DATA)) |
usb_ep2_data_wr_q <= 1'b1; |
else |
usb_ep2_data_wr_q <= 1'b0; |
|
// usb_ep2_data_data [external] |
wire [7:0] usb_ep2_data_data_out_w = wr_data_q[`USB_EP2_DATA_DATA_R]; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep3_cfg |
//----------------------------------------------------------------- |
reg usb_ep3_cfg_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_cfg_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_CFG)) |
usb_ep3_cfg_wr_q <= 1'b1; |
else |
usb_ep3_cfg_wr_q <= 1'b0; |
|
// usb_ep3_cfg_int_rx [internal] |
reg usb_ep3_cfg_int_rx_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_cfg_int_rx_q <= 1'd`USB_EP3_CFG_INT_RX_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_CFG)) |
usb_ep3_cfg_int_rx_q <= cfg_wdata_i[`USB_EP3_CFG_INT_RX_R]; |
|
wire usb_ep3_cfg_int_rx_out_w = usb_ep3_cfg_int_rx_q; |
|
|
// usb_ep3_cfg_int_tx [internal] |
reg usb_ep3_cfg_int_tx_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_cfg_int_tx_q <= 1'd`USB_EP3_CFG_INT_TX_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_CFG)) |
usb_ep3_cfg_int_tx_q <= cfg_wdata_i[`USB_EP3_CFG_INT_TX_R]; |
|
wire usb_ep3_cfg_int_tx_out_w = usb_ep3_cfg_int_tx_q; |
|
|
// usb_ep3_cfg_stall_ep [clearable] |
reg usb_ep3_cfg_stall_ep_q; |
|
wire usb_ep3_cfg_stall_ep_ack_in_w; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_cfg_stall_ep_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_CFG)) |
usb_ep3_cfg_stall_ep_q <= cfg_wdata_i[`USB_EP3_CFG_STALL_EP_R]; |
else if (usb_ep3_cfg_stall_ep_ack_in_w) |
usb_ep3_cfg_stall_ep_q <= 1'b0; |
|
wire usb_ep3_cfg_stall_ep_out_w = usb_ep3_cfg_stall_ep_q; |
|
|
// usb_ep3_cfg_iso [internal] |
reg usb_ep3_cfg_iso_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_cfg_iso_q <= 1'd`USB_EP3_CFG_ISO_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_CFG)) |
usb_ep3_cfg_iso_q <= cfg_wdata_i[`USB_EP3_CFG_ISO_R]; |
|
wire usb_ep3_cfg_iso_out_w = usb_ep3_cfg_iso_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep3_tx_ctrl |
//----------------------------------------------------------------- |
reg usb_ep3_tx_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_tx_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_TX_CTRL)) |
usb_ep3_tx_ctrl_wr_q <= 1'b1; |
else |
usb_ep3_tx_ctrl_wr_q <= 1'b0; |
|
// usb_ep3_tx_ctrl_tx_flush [auto_clr] |
reg usb_ep3_tx_ctrl_tx_flush_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_tx_ctrl_tx_flush_q <= 1'd`USB_EP3_TX_CTRL_TX_FLUSH_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_TX_CTRL)) |
usb_ep3_tx_ctrl_tx_flush_q <= cfg_wdata_i[`USB_EP3_TX_CTRL_TX_FLUSH_R]; |
else |
usb_ep3_tx_ctrl_tx_flush_q <= 1'd`USB_EP3_TX_CTRL_TX_FLUSH_DEFAULT; |
|
wire usb_ep3_tx_ctrl_tx_flush_out_w = usb_ep3_tx_ctrl_tx_flush_q; |
|
|
// usb_ep3_tx_ctrl_tx_start [auto_clr] |
reg usb_ep3_tx_ctrl_tx_start_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_tx_ctrl_tx_start_q <= 1'd`USB_EP3_TX_CTRL_TX_START_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_TX_CTRL)) |
usb_ep3_tx_ctrl_tx_start_q <= cfg_wdata_i[`USB_EP3_TX_CTRL_TX_START_R]; |
else |
usb_ep3_tx_ctrl_tx_start_q <= 1'd`USB_EP3_TX_CTRL_TX_START_DEFAULT; |
|
wire usb_ep3_tx_ctrl_tx_start_out_w = usb_ep3_tx_ctrl_tx_start_q; |
|
|
// usb_ep3_tx_ctrl_tx_len [internal] |
reg [10:0] usb_ep3_tx_ctrl_tx_len_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_tx_ctrl_tx_len_q <= 11'd`USB_EP3_TX_CTRL_TX_LEN_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_TX_CTRL)) |
usb_ep3_tx_ctrl_tx_len_q <= cfg_wdata_i[`USB_EP3_TX_CTRL_TX_LEN_R]; |
|
wire [10:0] usb_ep3_tx_ctrl_tx_len_out_w = usb_ep3_tx_ctrl_tx_len_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep3_rx_ctrl |
//----------------------------------------------------------------- |
reg usb_ep3_rx_ctrl_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_rx_ctrl_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_RX_CTRL)) |
usb_ep3_rx_ctrl_wr_q <= 1'b1; |
else |
usb_ep3_rx_ctrl_wr_q <= 1'b0; |
|
// usb_ep3_rx_ctrl_rx_flush [auto_clr] |
reg usb_ep3_rx_ctrl_rx_flush_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_rx_ctrl_rx_flush_q <= 1'd`USB_EP3_RX_CTRL_RX_FLUSH_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_RX_CTRL)) |
usb_ep3_rx_ctrl_rx_flush_q <= cfg_wdata_i[`USB_EP3_RX_CTRL_RX_FLUSH_R]; |
else |
usb_ep3_rx_ctrl_rx_flush_q <= 1'd`USB_EP3_RX_CTRL_RX_FLUSH_DEFAULT; |
|
wire usb_ep3_rx_ctrl_rx_flush_out_w = usb_ep3_rx_ctrl_rx_flush_q; |
|
|
// usb_ep3_rx_ctrl_rx_accept [auto_clr] |
reg usb_ep3_rx_ctrl_rx_accept_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_rx_ctrl_rx_accept_q <= 1'd`USB_EP3_RX_CTRL_RX_ACCEPT_DEFAULT; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_RX_CTRL)) |
usb_ep3_rx_ctrl_rx_accept_q <= cfg_wdata_i[`USB_EP3_RX_CTRL_RX_ACCEPT_R]; |
else |
usb_ep3_rx_ctrl_rx_accept_q <= 1'd`USB_EP3_RX_CTRL_RX_ACCEPT_DEFAULT; |
|
wire usb_ep3_rx_ctrl_rx_accept_out_w = usb_ep3_rx_ctrl_rx_accept_q; |
|
|
//----------------------------------------------------------------- |
// Register usb_ep3_sts |
//----------------------------------------------------------------- |
reg usb_ep3_sts_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_sts_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_STS)) |
usb_ep3_sts_wr_q <= 1'b1; |
else |
usb_ep3_sts_wr_q <= 1'b0; |
|
|
|
|
|
|
|
//----------------------------------------------------------------- |
// Register usb_ep3_data |
//----------------------------------------------------------------- |
reg usb_ep3_data_wr_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
usb_ep3_data_wr_q <= 1'b0; |
else if (write_en_w && (cfg_awaddr_i[7:0] == `USB_EP3_DATA)) |
usb_ep3_data_wr_q <= 1'b1; |
else |
usb_ep3_data_wr_q <= 1'b0; |
|
// usb_ep3_data_data [external] |
wire [7:0] usb_ep3_data_data_out_w = wr_data_q[`USB_EP3_DATA_DATA_R]; |
|
|
wire usb_func_stat_rst_in_w; |
wire [1:0] usb_func_stat_linestate_in_w; |
wire [10:0] usb_func_stat_frame_in_w; |
wire usb_ep0_sts_tx_err_in_w; |
wire usb_ep0_sts_tx_busy_in_w; |
wire usb_ep0_sts_rx_err_in_w; |
wire usb_ep0_sts_rx_setup_in_w; |
wire usb_ep0_sts_rx_ready_in_w; |
wire [10:0] usb_ep0_sts_rx_count_in_w; |
wire [7:0] usb_ep0_data_data_in_w; |
wire usb_ep1_sts_tx_err_in_w; |
wire usb_ep1_sts_tx_busy_in_w; |
wire usb_ep1_sts_rx_err_in_w; |
wire usb_ep1_sts_rx_setup_in_w; |
wire usb_ep1_sts_rx_ready_in_w; |
wire [10:0] usb_ep1_sts_rx_count_in_w; |
wire [7:0] usb_ep1_data_data_in_w; |
wire usb_ep2_sts_tx_err_in_w; |
wire usb_ep2_sts_tx_busy_in_w; |
wire usb_ep2_sts_rx_err_in_w; |
wire usb_ep2_sts_rx_setup_in_w; |
wire usb_ep2_sts_rx_ready_in_w; |
wire [10:0] usb_ep2_sts_rx_count_in_w; |
wire [7:0] usb_ep2_data_data_in_w; |
wire usb_ep3_sts_tx_err_in_w; |
wire usb_ep3_sts_tx_busy_in_w; |
wire usb_ep3_sts_rx_err_in_w; |
wire usb_ep3_sts_rx_setup_in_w; |
wire usb_ep3_sts_rx_ready_in_w; |
wire [10:0] usb_ep3_sts_rx_count_in_w; |
wire [7:0] usb_ep3_data_data_in_w; |
|
|
//----------------------------------------------------------------- |
// Read mux |
//----------------------------------------------------------------- |
reg [31:0] data_r; |
|
always @ * |
begin |
data_r = 32'b0; |
|
case (cfg_araddr_i[7:0]) |
|
`USB_FUNC_CTRL: |
begin |
data_r[`USB_FUNC_CTRL_HS_CHIRP_EN_R] = usb_func_ctrl_hs_chirp_en_q; |
data_r[`USB_FUNC_CTRL_PHY_DMPULLDOWN_R] = usb_func_ctrl_phy_dmpulldown_q; |
data_r[`USB_FUNC_CTRL_PHY_DPPULLDOWN_R] = usb_func_ctrl_phy_dppulldown_q; |
data_r[`USB_FUNC_CTRL_PHY_TERMSELECT_R] = usb_func_ctrl_phy_termselect_q; |
data_r[`USB_FUNC_CTRL_PHY_XCVRSELECT_R] = usb_func_ctrl_phy_xcvrselect_q; |
data_r[`USB_FUNC_CTRL_PHY_OPMODE_R] = usb_func_ctrl_phy_opmode_q; |
data_r[`USB_FUNC_CTRL_INT_EN_SOF_R] = usb_func_ctrl_int_en_sof_q; |
end |
`USB_FUNC_STAT: |
begin |
data_r[`USB_FUNC_STAT_RST_R] = usb_func_stat_rst_in_w; |
data_r[`USB_FUNC_STAT_LINESTATE_R] = usb_func_stat_linestate_in_w; |
data_r[`USB_FUNC_STAT_FRAME_R] = usb_func_stat_frame_in_w; |
end |
`USB_FUNC_ADDR: |
begin |
data_r[`USB_FUNC_ADDR_DEV_ADDR_R] = usb_func_addr_dev_addr_q; |
end |
`USB_EP0_CFG: |
begin |
data_r[`USB_EP0_CFG_INT_RX_R] = usb_ep0_cfg_int_rx_q; |
data_r[`USB_EP0_CFG_INT_TX_R] = usb_ep0_cfg_int_tx_q; |
data_r[`USB_EP0_CFG_ISO_R] = usb_ep0_cfg_iso_q; |
end |
`USB_EP0_TX_CTRL: |
begin |
data_r[`USB_EP0_TX_CTRL_TX_LEN_R] = usb_ep0_tx_ctrl_tx_len_q; |
end |
`USB_EP0_STS: |
begin |
data_r[`USB_EP0_STS_TX_ERR_R] = usb_ep0_sts_tx_err_in_w; |
data_r[`USB_EP0_STS_TX_BUSY_R] = usb_ep0_sts_tx_busy_in_w; |
data_r[`USB_EP0_STS_RX_ERR_R] = usb_ep0_sts_rx_err_in_w; |
data_r[`USB_EP0_STS_RX_SETUP_R] = usb_ep0_sts_rx_setup_in_w; |
data_r[`USB_EP0_STS_RX_READY_R] = usb_ep0_sts_rx_ready_in_w; |
data_r[`USB_EP0_STS_RX_COUNT_R] = usb_ep0_sts_rx_count_in_w; |
end |
`USB_EP0_DATA: |
begin |
data_r[`USB_EP0_DATA_DATA_R] = usb_ep0_data_data_in_w; |
end |
`USB_EP1_CFG: |
begin |
data_r[`USB_EP1_CFG_INT_RX_R] = usb_ep1_cfg_int_rx_q; |
data_r[`USB_EP1_CFG_INT_TX_R] = usb_ep1_cfg_int_tx_q; |
data_r[`USB_EP1_CFG_ISO_R] = usb_ep1_cfg_iso_q; |
end |
`USB_EP1_TX_CTRL: |
begin |
data_r[`USB_EP1_TX_CTRL_TX_LEN_R] = usb_ep1_tx_ctrl_tx_len_q; |
end |
`USB_EP1_STS: |
begin |
data_r[`USB_EP1_STS_TX_ERR_R] = usb_ep1_sts_tx_err_in_w; |
data_r[`USB_EP1_STS_TX_BUSY_R] = usb_ep1_sts_tx_busy_in_w; |
data_r[`USB_EP1_STS_RX_ERR_R] = usb_ep1_sts_rx_err_in_w; |
data_r[`USB_EP1_STS_RX_SETUP_R] = usb_ep1_sts_rx_setup_in_w; |
data_r[`USB_EP1_STS_RX_READY_R] = usb_ep1_sts_rx_ready_in_w; |
data_r[`USB_EP1_STS_RX_COUNT_R] = usb_ep1_sts_rx_count_in_w; |
end |
`USB_EP1_DATA: |
begin |
data_r[`USB_EP1_DATA_DATA_R] = usb_ep1_data_data_in_w; |
end |
`USB_EP2_CFG: |
begin |
data_r[`USB_EP2_CFG_INT_RX_R] = usb_ep2_cfg_int_rx_q; |
data_r[`USB_EP2_CFG_INT_TX_R] = usb_ep2_cfg_int_tx_q; |
data_r[`USB_EP2_CFG_ISO_R] = usb_ep2_cfg_iso_q; |
end |
`USB_EP2_TX_CTRL: |
begin |
data_r[`USB_EP2_TX_CTRL_TX_LEN_R] = usb_ep2_tx_ctrl_tx_len_q; |
end |
`USB_EP2_STS: |
begin |
data_r[`USB_EP2_STS_TX_ERR_R] = usb_ep2_sts_tx_err_in_w; |
data_r[`USB_EP2_STS_TX_BUSY_R] = usb_ep2_sts_tx_busy_in_w; |
data_r[`USB_EP2_STS_RX_ERR_R] = usb_ep2_sts_rx_err_in_w; |
data_r[`USB_EP2_STS_RX_SETUP_R] = usb_ep2_sts_rx_setup_in_w; |
data_r[`USB_EP2_STS_RX_READY_R] = usb_ep2_sts_rx_ready_in_w; |
data_r[`USB_EP2_STS_RX_COUNT_R] = usb_ep2_sts_rx_count_in_w; |
end |
`USB_EP2_DATA: |
begin |
data_r[`USB_EP2_DATA_DATA_R] = usb_ep2_data_data_in_w; |
end |
`USB_EP3_CFG: |
begin |
data_r[`USB_EP3_CFG_INT_RX_R] = usb_ep3_cfg_int_rx_q; |
data_r[`USB_EP3_CFG_INT_TX_R] = usb_ep3_cfg_int_tx_q; |
data_r[`USB_EP3_CFG_ISO_R] = usb_ep3_cfg_iso_q; |
end |
`USB_EP3_TX_CTRL: |
begin |
data_r[`USB_EP3_TX_CTRL_TX_LEN_R] = usb_ep3_tx_ctrl_tx_len_q; |
end |
`USB_EP3_STS: |
begin |
data_r[`USB_EP3_STS_TX_ERR_R] = usb_ep3_sts_tx_err_in_w; |
data_r[`USB_EP3_STS_TX_BUSY_R] = usb_ep3_sts_tx_busy_in_w; |
data_r[`USB_EP3_STS_RX_ERR_R] = usb_ep3_sts_rx_err_in_w; |
data_r[`USB_EP3_STS_RX_SETUP_R] = usb_ep3_sts_rx_setup_in_w; |
data_r[`USB_EP3_STS_RX_READY_R] = usb_ep3_sts_rx_ready_in_w; |
data_r[`USB_EP3_STS_RX_COUNT_R] = usb_ep3_sts_rx_count_in_w; |
end |
`USB_EP3_DATA: |
begin |
data_r[`USB_EP3_DATA_DATA_R] = usb_ep3_data_data_in_w; |
end |
default : |
data_r = 32'b0; |
endcase |
end |
|
//----------------------------------------------------------------- |
// RVALID |
//----------------------------------------------------------------- |
reg rvalid_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rvalid_q <= 1'b0; |
else if (read_en_w) |
rvalid_q <= 1'b1; |
else if (cfg_rready_i) |
rvalid_q <= 1'b0; |
|
assign cfg_rvalid_o = rvalid_q; |
|
//----------------------------------------------------------------- |
// Retime read response |
//----------------------------------------------------------------- |
reg [31:0] rd_data_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rd_data_q <= 32'b0; |
else if (!cfg_rvalid_o || cfg_rready_i) |
rd_data_q <= data_r; |
|
assign cfg_rdata_o = rd_data_q; |
assign cfg_rresp_o = 2'b0; |
|
//----------------------------------------------------------------- |
// BVALID |
//----------------------------------------------------------------- |
reg bvalid_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
bvalid_q <= 1'b0; |
else if (write_en_w) |
bvalid_q <= 1'b1; |
else if (cfg_bready_i) |
bvalid_q <= 1'b0; |
|
assign cfg_bvalid_o = bvalid_q; |
assign cfg_bresp_o = 2'b0; |
|
wire usb_ep0_data_rd_req_w = read_en_w & (cfg_araddr_i[7:0] == `USB_EP0_DATA); |
wire usb_ep1_data_rd_req_w = read_en_w & (cfg_araddr_i[7:0] == `USB_EP1_DATA); |
wire usb_ep2_data_rd_req_w = read_en_w & (cfg_araddr_i[7:0] == `USB_EP2_DATA); |
wire usb_ep3_data_rd_req_w = read_en_w & (cfg_araddr_i[7:0] == `USB_EP3_DATA); |
|
wire usb_func_stat_wr_req_w = usb_func_stat_wr_q; |
wire usb_ep0_data_wr_req_w = usb_ep0_data_wr_q; |
wire usb_ep1_data_wr_req_w = usb_ep1_data_wr_q; |
wire usb_ep2_data_wr_req_w = usb_ep2_data_wr_q; |
wire usb_ep3_data_wr_req_w = usb_ep3_data_wr_q; |
|
|
//----------------------------------------------------------------- |
// Wires |
//----------------------------------------------------------------- |
wire stat_rst_w; |
wire [10:0] stat_frame_w; |
wire stat_rst_clr_w = usb_func_stat_rst_out_w; |
wire stat_wr_req_w = usb_func_stat_wr_req_w; |
|
wire usb_ep0_tx_rd_w; |
wire [7:0] usb_ep0_tx_data_w; |
wire usb_ep0_tx_empty_w; |
|
wire usb_ep0_rx_wr_w; |
wire [7:0] usb_ep0_rx_data_w; |
wire usb_ep0_rx_full_w; |
wire usb_ep1_tx_rd_w; |
wire [7:0] usb_ep1_tx_data_w; |
wire usb_ep1_tx_empty_w; |
|
wire usb_ep1_rx_wr_w; |
wire [7:0] usb_ep1_rx_data_w; |
wire usb_ep1_rx_full_w; |
wire usb_ep2_tx_rd_w; |
wire [7:0] usb_ep2_tx_data_w; |
wire usb_ep2_tx_empty_w; |
|
wire usb_ep2_rx_wr_w; |
wire [7:0] usb_ep2_rx_data_w; |
wire usb_ep2_rx_full_w; |
wire usb_ep3_tx_rd_w; |
wire [7:0] usb_ep3_tx_data_w; |
wire usb_ep3_tx_empty_w; |
|
wire usb_ep3_rx_wr_w; |
wire [7:0] usb_ep3_rx_data_w; |
wire usb_ep3_rx_full_w; |
|
// Rx SIE Interface (shared) |
wire rx_strb_w; |
wire [7:0] rx_data_w; |
wire rx_last_w; |
wire rx_crc_err_w; |
|
// EP0 Rx SIE Interface |
wire ep0_rx_space_w; |
wire ep0_rx_valid_w; |
wire ep0_rx_setup_w; |
|
// EP0 Tx SIE Interface |
wire ep0_tx_ready_w; |
wire ep0_tx_data_valid_w; |
wire ep0_tx_data_strb_w; |
wire [7:0] ep0_tx_data_w; |
wire ep0_tx_data_last_w; |
wire ep0_tx_data_accept_w; |
// EP1 Rx SIE Interface |
wire ep1_rx_space_w; |
wire ep1_rx_valid_w; |
wire ep1_rx_setup_w; |
|
// EP1 Tx SIE Interface |
wire ep1_tx_ready_w; |
wire ep1_tx_data_valid_w; |
wire ep1_tx_data_strb_w; |
wire [7:0] ep1_tx_data_w; |
wire ep1_tx_data_last_w; |
wire ep1_tx_data_accept_w; |
// EP2 Rx SIE Interface |
wire ep2_rx_space_w; |
wire ep2_rx_valid_w; |
wire ep2_rx_setup_w; |
|
// EP2 Tx SIE Interface |
wire ep2_tx_ready_w; |
wire ep2_tx_data_valid_w; |
wire ep2_tx_data_strb_w; |
wire [7:0] ep2_tx_data_w; |
wire ep2_tx_data_last_w; |
wire ep2_tx_data_accept_w; |
// EP3 Rx SIE Interface |
wire ep3_rx_space_w; |
wire ep3_rx_valid_w; |
wire ep3_rx_setup_w; |
|
// EP3 Tx SIE Interface |
wire ep3_tx_ready_w; |
wire ep3_tx_data_valid_w; |
wire ep3_tx_data_strb_w; |
wire [7:0] ep3_tx_data_w; |
wire ep3_tx_data_last_w; |
wire ep3_tx_data_accept_w; |
|
// Transceiver Control |
assign utmi_dmpulldown_o = usb_func_ctrl_phy_dmpulldown_out_w; |
assign utmi_dppulldown_o = usb_func_ctrl_phy_dppulldown_out_w; |
assign utmi_termselect_o = usb_func_ctrl_phy_termselect_out_w; |
assign utmi_xcvrselect_o = usb_func_ctrl_phy_xcvrselect_out_w; |
assign utmi_op_mode_o = usb_func_ctrl_phy_opmode_out_w; |
|
// Status |
assign usb_func_stat_rst_in_w = stat_rst_w; |
assign usb_func_stat_linestate_in_w = utmi_linestate_i; |
assign usb_func_stat_frame_in_w = stat_frame_w; |
|
//----------------------------------------------------------------- |
// Core |
//----------------------------------------------------------------- |
usbf_device_core |
u_core |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.intr_o(intr_o), |
|
// UTMI interface |
.utmi_data_o(utmi_data_out_o), |
.utmi_data_i(utmi_data_in_i), |
.utmi_txvalid_o(utmi_txvalid_o), |
.utmi_txready_i(utmi_txready_i), |
.utmi_rxvalid_i(utmi_rxvalid_i), |
.utmi_rxactive_i(utmi_rxactive_i), |
.utmi_rxerror_i(utmi_rxerror_i), |
.utmi_linestate_i(utmi_linestate_i), |
|
.reg_chirp_en_i(usb_func_ctrl_hs_chirp_en_out_w), |
.reg_int_en_sof_i(usb_func_ctrl_int_en_sof_out_w), |
|
.reg_dev_addr_i(usb_func_addr_dev_addr_out_w), |
|
// Rx SIE Interface (shared) |
.rx_strb_o(rx_strb_w), |
.rx_data_o(rx_data_w), |
.rx_last_o(rx_last_w), |
.rx_crc_err_o(rx_crc_err_w), |
|
// EP0 Config |
.ep0_iso_i(usb_ep0_cfg_iso_out_w), |
.ep0_stall_i(usb_ep0_cfg_stall_ep_out_w), |
.ep0_cfg_int_rx_i(usb_ep0_cfg_int_rx_out_w), |
.ep0_cfg_int_tx_i(usb_ep0_cfg_int_tx_out_w), |
|
// EP0 Rx SIE Interface |
.ep0_rx_setup_o(ep0_rx_setup_w), |
.ep0_rx_valid_o(ep0_rx_valid_w), |
.ep0_rx_space_i(ep0_rx_space_w), |
|
// EP0 Tx SIE Interface |
.ep0_tx_ready_i(ep0_tx_ready_w), |
.ep0_tx_data_valid_i(ep0_tx_data_valid_w), |
.ep0_tx_data_strb_i(ep0_tx_data_strb_w), |
.ep0_tx_data_i(ep0_tx_data_w), |
.ep0_tx_data_last_i(ep0_tx_data_last_w), |
.ep0_tx_data_accept_o(ep0_tx_data_accept_w), |
|
// EP1 Config |
.ep1_iso_i(usb_ep1_cfg_iso_out_w), |
.ep1_stall_i(usb_ep1_cfg_stall_ep_out_w), |
.ep1_cfg_int_rx_i(usb_ep1_cfg_int_rx_out_w), |
.ep1_cfg_int_tx_i(usb_ep1_cfg_int_tx_out_w), |
|
// EP1 Rx SIE Interface |
.ep1_rx_setup_o(ep1_rx_setup_w), |
.ep1_rx_valid_o(ep1_rx_valid_w), |
.ep1_rx_space_i(ep1_rx_space_w), |
|
// EP1 Tx SIE Interface |
.ep1_tx_ready_i(ep1_tx_ready_w), |
.ep1_tx_data_valid_i(ep1_tx_data_valid_w), |
.ep1_tx_data_strb_i(ep1_tx_data_strb_w), |
.ep1_tx_data_i(ep1_tx_data_w), |
.ep1_tx_data_last_i(ep1_tx_data_last_w), |
.ep1_tx_data_accept_o(ep1_tx_data_accept_w), |
|
// EP2 Config |
.ep2_iso_i(usb_ep2_cfg_iso_out_w), |
.ep2_stall_i(usb_ep2_cfg_stall_ep_out_w), |
.ep2_cfg_int_rx_i(usb_ep2_cfg_int_rx_out_w), |
.ep2_cfg_int_tx_i(usb_ep2_cfg_int_tx_out_w), |
|
// EP2 Rx SIE Interface |
.ep2_rx_setup_o(ep2_rx_setup_w), |
.ep2_rx_valid_o(ep2_rx_valid_w), |
.ep2_rx_space_i(ep2_rx_space_w), |
|
// EP2 Tx SIE Interface |
.ep2_tx_ready_i(ep2_tx_ready_w), |
.ep2_tx_data_valid_i(ep2_tx_data_valid_w), |
.ep2_tx_data_strb_i(ep2_tx_data_strb_w), |
.ep2_tx_data_i(ep2_tx_data_w), |
.ep2_tx_data_last_i(ep2_tx_data_last_w), |
.ep2_tx_data_accept_o(ep2_tx_data_accept_w), |
|
// EP3 Config |
.ep3_iso_i(usb_ep3_cfg_iso_out_w), |
.ep3_stall_i(usb_ep3_cfg_stall_ep_out_w), |
.ep3_cfg_int_rx_i(usb_ep3_cfg_int_rx_out_w), |
.ep3_cfg_int_tx_i(usb_ep3_cfg_int_tx_out_w), |
|
// EP3 Rx SIE Interface |
.ep3_rx_setup_o(ep3_rx_setup_w), |
.ep3_rx_valid_o(ep3_rx_valid_w), |
.ep3_rx_space_i(ep3_rx_space_w), |
|
// EP3 Tx SIE Interface |
.ep3_tx_ready_i(ep3_tx_ready_w), |
.ep3_tx_data_valid_i(ep3_tx_data_valid_w), |
.ep3_tx_data_strb_i(ep3_tx_data_strb_w), |
.ep3_tx_data_i(ep3_tx_data_w), |
.ep3_tx_data_last_i(ep3_tx_data_last_w), |
.ep3_tx_data_accept_o(ep3_tx_data_accept_w), |
|
// Status |
.reg_sts_rst_clr_i(stat_rst_clr_w & stat_wr_req_w), |
.reg_sts_rst_o(stat_rst_w), |
.reg_sts_frame_num_o(stat_frame_w) |
); |
|
assign usb_ep0_cfg_stall_ep_ack_in_w = ep0_rx_setup_w; |
assign usb_ep1_cfg_stall_ep_ack_in_w = ep1_rx_setup_w; |
assign usb_ep2_cfg_stall_ep_ack_in_w = ep2_rx_setup_w; |
assign usb_ep3_cfg_stall_ep_ack_in_w = ep3_rx_setup_w; |
|
//----------------------------------------------------------------- |
// FIFOs |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Endpoint 0: Host -> Device |
//----------------------------------------------------------------- |
usbf_fifo |
#( |
.WIDTH(8), |
.DEPTH(8), |
.ADDR_W(3) |
) |
u_fifo_rx_ep0 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.data_i(usb_ep0_rx_data_w), |
.push_i(usb_ep0_rx_wr_w), |
|
.flush_i(usb_ep0_rx_ctrl_rx_flush_out_w), |
|
.full_o(usb_ep0_rx_full_w), |
.empty_o(), |
|
// Output to register block |
.data_o(usb_ep0_data_data_in_w), |
.pop_i(usb_ep0_data_rd_req_w) |
); |
|
//----------------------------------------------------------------- |
// Endpoint 0: Device -> Host |
//----------------------------------------------------------------- |
usbf_fifo |
#( |
.WIDTH(8), |
.DEPTH(8), |
.ADDR_W(3) |
) |
u_fifo_tx_ep0 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
// Input from register block |
.data_i(usb_ep0_data_data_out_w), |
.push_i(usb_ep0_data_wr_req_w), |
|
.flush_i(usb_ep0_tx_ctrl_tx_flush_out_w), |
|
.full_o(), |
.empty_o(usb_ep0_tx_empty_w), |
|
.data_o(usb_ep0_tx_data_w), |
.pop_i(usb_ep0_tx_rd_w) |
); |
|
//----------------------------------------------------------------- |
// Endpoint 1: Host -> Device |
//----------------------------------------------------------------- |
usbf_fifo |
#( |
.WIDTH(8), |
.DEPTH(64), |
.ADDR_W(6) |
) |
u_fifo_rx_ep1 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.data_i(usb_ep1_rx_data_w), |
.push_i(usb_ep1_rx_wr_w), |
|
.flush_i(usb_ep1_rx_ctrl_rx_flush_out_w), |
|
.full_o(usb_ep1_rx_full_w), |
.empty_o(), |
|
// Output to register block |
.data_o(usb_ep1_data_data_in_w), |
.pop_i(usb_ep1_data_rd_req_w) |
); |
|
//----------------------------------------------------------------- |
// Endpoint 1: Device -> Host |
//----------------------------------------------------------------- |
usbf_fifo |
#( |
.WIDTH(8), |
.DEPTH(64), |
.ADDR_W(6) |
) |
u_fifo_tx_ep1 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
// Input from register block |
.data_i(usb_ep1_data_data_out_w), |
.push_i(usb_ep1_data_wr_req_w), |
|
.flush_i(usb_ep1_tx_ctrl_tx_flush_out_w), |
|
.full_o(), |
.empty_o(usb_ep1_tx_empty_w), |
|
.data_o(usb_ep1_tx_data_w), |
.pop_i(usb_ep1_tx_rd_w) |
); |
|
//----------------------------------------------------------------- |
// Endpoint 2: Host -> Device |
//----------------------------------------------------------------- |
usbf_fifo |
#( |
.WIDTH(8), |
.DEPTH(64), |
.ADDR_W(6) |
) |
u_fifo_rx_ep2 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.data_i(usb_ep2_rx_data_w), |
.push_i(usb_ep2_rx_wr_w), |
|
.flush_i(usb_ep2_rx_ctrl_rx_flush_out_w), |
|
.full_o(usb_ep2_rx_full_w), |
.empty_o(), |
|
// Output to register block |
.data_o(usb_ep2_data_data_in_w), |
.pop_i(usb_ep2_data_rd_req_w) |
); |
|
//----------------------------------------------------------------- |
// Endpoint 2: Device -> Host |
//----------------------------------------------------------------- |
usbf_fifo |
#( |
.WIDTH(8), |
.DEPTH(64), |
.ADDR_W(6) |
) |
u_fifo_tx_ep2 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
// Input from register block |
.data_i(usb_ep2_data_data_out_w), |
.push_i(usb_ep2_data_wr_req_w), |
|
.flush_i(usb_ep2_tx_ctrl_tx_flush_out_w), |
|
.full_o(), |
.empty_o(usb_ep2_tx_empty_w), |
|
.data_o(usb_ep2_tx_data_w), |
.pop_i(usb_ep2_tx_rd_w) |
); |
|
//----------------------------------------------------------------- |
// Endpoint 3: Host -> Device |
//----------------------------------------------------------------- |
usbf_fifo |
#( |
.WIDTH(8), |
.DEPTH(64), |
.ADDR_W(6) |
) |
u_fifo_rx_ep3 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.data_i(usb_ep3_rx_data_w), |
.push_i(usb_ep3_rx_wr_w), |
|
.flush_i(usb_ep3_rx_ctrl_rx_flush_out_w), |
|
.full_o(usb_ep3_rx_full_w), |
.empty_o(), |
|
// Output to register block |
.data_o(usb_ep3_data_data_in_w), |
.pop_i(usb_ep3_data_rd_req_w) |
); |
|
//----------------------------------------------------------------- |
// Endpoint 3: Device -> Host |
//----------------------------------------------------------------- |
usbf_fifo |
#( |
.WIDTH(8), |
.DEPTH(64), |
.ADDR_W(6) |
) |
u_fifo_tx_ep3 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
// Input from register block |
.data_i(usb_ep3_data_data_out_w), |
.push_i(usb_ep3_data_wr_req_w), |
|
.flush_i(usb_ep3_tx_ctrl_tx_flush_out_w), |
|
.full_o(), |
.empty_o(usb_ep3_tx_empty_w), |
|
.data_o(usb_ep3_tx_data_w), |
.pop_i(usb_ep3_tx_rd_w) |
); |
|
|
//----------------------------------------------------------------- |
// Endpoint 0: Control |
//----------------------------------------------------------------- |
usbf_sie_ep |
u_ep0 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
// Rx SIE Interface |
.rx_space_o(ep0_rx_space_w), |
.rx_valid_i(ep0_rx_valid_w), |
.rx_setup_i(ep0_rx_setup_w), |
.rx_strb_i(rx_strb_w), |
.rx_data_i(rx_data_w), |
.rx_last_i(rx_last_w), |
.rx_crc_err_i(rx_crc_err_w), |
|
// Rx FIFO Interface |
.rx_push_o(usb_ep0_rx_wr_w), |
.rx_data_o(usb_ep0_rx_data_w), |
.rx_full_i(usb_ep0_rx_full_w), |
|
// Rx Register Interface |
.rx_length_o(usb_ep0_sts_rx_count_in_w), |
.rx_ready_o(usb_ep0_sts_rx_ready_in_w), |
.rx_err_o(usb_ep0_sts_rx_err_in_w), |
.rx_setup_o(usb_ep0_sts_rx_setup_in_w), |
.rx_ack_i(usb_ep0_rx_ctrl_rx_accept_out_w), |
|
// Tx FIFO Interface |
.tx_pop_o(usb_ep0_tx_rd_w), |
.tx_data_i(usb_ep0_tx_data_w), |
.tx_empty_i(usb_ep0_tx_empty_w), |
|
// Tx Register Interface |
.tx_flush_i(usb_ep0_tx_ctrl_tx_flush_out_w), |
.tx_length_i(usb_ep0_tx_ctrl_tx_len_out_w), |
.tx_start_i(usb_ep0_tx_ctrl_tx_start_out_w), |
.tx_busy_o(usb_ep0_sts_tx_busy_in_w), |
.tx_err_o(usb_ep0_sts_tx_err_in_w), |
|
// Tx SIE Interface |
.tx_ready_o(ep0_tx_ready_w), |
.tx_data_valid_o(ep0_tx_data_valid_w), |
.tx_data_strb_o(ep0_tx_data_strb_w), |
.tx_data_o(ep0_tx_data_w), |
.tx_data_last_o(ep0_tx_data_last_w), |
.tx_data_accept_i(ep0_tx_data_accept_w) |
); |
//----------------------------------------------------------------- |
// Endpoint 1: Control |
//----------------------------------------------------------------- |
usbf_sie_ep |
u_ep1 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
// Rx SIE Interface |
.rx_space_o(ep1_rx_space_w), |
.rx_valid_i(ep1_rx_valid_w), |
.rx_setup_i(ep1_rx_setup_w), |
.rx_strb_i(rx_strb_w), |
.rx_data_i(rx_data_w), |
.rx_last_i(rx_last_w), |
.rx_crc_err_i(rx_crc_err_w), |
|
// Rx FIFO Interface |
.rx_push_o(usb_ep1_rx_wr_w), |
.rx_data_o(usb_ep1_rx_data_w), |
.rx_full_i(usb_ep1_rx_full_w), |
|
// Rx Register Interface |
.rx_length_o(usb_ep1_sts_rx_count_in_w), |
.rx_ready_o(usb_ep1_sts_rx_ready_in_w), |
.rx_err_o(usb_ep1_sts_rx_err_in_w), |
.rx_setup_o(usb_ep1_sts_rx_setup_in_w), |
.rx_ack_i(usb_ep1_rx_ctrl_rx_accept_out_w), |
|
// Tx FIFO Interface |
.tx_pop_o(usb_ep1_tx_rd_w), |
.tx_data_i(usb_ep1_tx_data_w), |
.tx_empty_i(usb_ep1_tx_empty_w), |
|
// Tx Register Interface |
.tx_flush_i(usb_ep1_tx_ctrl_tx_flush_out_w), |
.tx_length_i(usb_ep1_tx_ctrl_tx_len_out_w), |
.tx_start_i(usb_ep1_tx_ctrl_tx_start_out_w), |
.tx_busy_o(usb_ep1_sts_tx_busy_in_w), |
.tx_err_o(usb_ep1_sts_tx_err_in_w), |
|
// Tx SIE Interface |
.tx_ready_o(ep1_tx_ready_w), |
.tx_data_valid_o(ep1_tx_data_valid_w), |
.tx_data_strb_o(ep1_tx_data_strb_w), |
.tx_data_o(ep1_tx_data_w), |
.tx_data_last_o(ep1_tx_data_last_w), |
.tx_data_accept_i(ep1_tx_data_accept_w) |
); |
//----------------------------------------------------------------- |
// Endpoint 2: Control |
//----------------------------------------------------------------- |
usbf_sie_ep |
u_ep2 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
// Rx SIE Interface |
.rx_space_o(ep2_rx_space_w), |
.rx_valid_i(ep2_rx_valid_w), |
.rx_setup_i(ep2_rx_setup_w), |
.rx_strb_i(rx_strb_w), |
.rx_data_i(rx_data_w), |
.rx_last_i(rx_last_w), |
.rx_crc_err_i(rx_crc_err_w), |
|
// Rx FIFO Interface |
.rx_push_o(usb_ep2_rx_wr_w), |
.rx_data_o(usb_ep2_rx_data_w), |
.rx_full_i(usb_ep2_rx_full_w), |
|
// Rx Register Interface |
.rx_length_o(usb_ep2_sts_rx_count_in_w), |
.rx_ready_o(usb_ep2_sts_rx_ready_in_w), |
.rx_err_o(usb_ep2_sts_rx_err_in_w), |
.rx_setup_o(usb_ep2_sts_rx_setup_in_w), |
.rx_ack_i(usb_ep2_rx_ctrl_rx_accept_out_w), |
|
// Tx FIFO Interface |
.tx_pop_o(usb_ep2_tx_rd_w), |
.tx_data_i(usb_ep2_tx_data_w), |
.tx_empty_i(usb_ep2_tx_empty_w), |
|
// Tx Register Interface |
.tx_flush_i(usb_ep2_tx_ctrl_tx_flush_out_w), |
.tx_length_i(usb_ep2_tx_ctrl_tx_len_out_w), |
.tx_start_i(usb_ep2_tx_ctrl_tx_start_out_w), |
.tx_busy_o(usb_ep2_sts_tx_busy_in_w), |
.tx_err_o(usb_ep2_sts_tx_err_in_w), |
|
// Tx SIE Interface |
.tx_ready_o(ep2_tx_ready_w), |
.tx_data_valid_o(ep2_tx_data_valid_w), |
.tx_data_strb_o(ep2_tx_data_strb_w), |
.tx_data_o(ep2_tx_data_w), |
.tx_data_last_o(ep2_tx_data_last_w), |
.tx_data_accept_i(ep2_tx_data_accept_w) |
); |
//----------------------------------------------------------------- |
// Endpoint 3: Control |
//----------------------------------------------------------------- |
usbf_sie_ep |
u_ep3 |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
// Rx SIE Interface |
.rx_space_o(ep3_rx_space_w), |
.rx_valid_i(ep3_rx_valid_w), |
.rx_setup_i(ep3_rx_setup_w), |
.rx_strb_i(rx_strb_w), |
.rx_data_i(rx_data_w), |
.rx_last_i(rx_last_w), |
.rx_crc_err_i(rx_crc_err_w), |
|
// Rx FIFO Interface |
.rx_push_o(usb_ep3_rx_wr_w), |
.rx_data_o(usb_ep3_rx_data_w), |
.rx_full_i(usb_ep3_rx_full_w), |
|
// Rx Register Interface |
.rx_length_o(usb_ep3_sts_rx_count_in_w), |
.rx_ready_o(usb_ep3_sts_rx_ready_in_w), |
.rx_err_o(usb_ep3_sts_rx_err_in_w), |
.rx_setup_o(usb_ep3_sts_rx_setup_in_w), |
.rx_ack_i(usb_ep3_rx_ctrl_rx_accept_out_w), |
|
// Tx FIFO Interface |
.tx_pop_o(usb_ep3_tx_rd_w), |
.tx_data_i(usb_ep3_tx_data_w), |
.tx_empty_i(usb_ep3_tx_empty_w), |
|
// Tx Register Interface |
.tx_flush_i(usb_ep3_tx_ctrl_tx_flush_out_w), |
.tx_length_i(usb_ep3_tx_ctrl_tx_len_out_w), |
.tx_start_i(usb_ep3_tx_ctrl_tx_start_out_w), |
.tx_busy_o(usb_ep3_sts_tx_busy_in_w), |
.tx_err_o(usb_ep3_sts_tx_err_in_w), |
|
// Tx SIE Interface |
.tx_ready_o(ep3_tx_ready_w), |
.tx_data_valid_o(ep3_tx_data_valid_w), |
.tx_data_strb_o(ep3_tx_data_strb_w), |
.tx_data_o(ep3_tx_data_w), |
.tx_data_last_o(ep3_tx_data_last_w), |
.tx_data_accept_i(ep3_tx_data_accept_w) |
); |
|
|
endmodule |
/usb_device_core/trunk/src_v/usbf_device_core.v
0,0 → 1,1016
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
|
module usbf_device_core |
( |
// Inputs |
input clk_i |
,input rst_i |
,input [ 7:0] utmi_data_i |
,input utmi_txready_i |
,input utmi_rxvalid_i |
,input utmi_rxactive_i |
,input utmi_rxerror_i |
,input [ 1:0] utmi_linestate_i |
,input ep0_stall_i |
,input ep0_iso_i |
,input ep0_cfg_int_rx_i |
,input ep0_cfg_int_tx_i |
,input ep0_rx_space_i |
,input ep0_tx_ready_i |
,input ep0_tx_data_valid_i |
,input ep0_tx_data_strb_i |
,input [ 7:0] ep0_tx_data_i |
,input ep0_tx_data_last_i |
,input ep1_stall_i |
,input ep1_iso_i |
,input ep1_cfg_int_rx_i |
,input ep1_cfg_int_tx_i |
,input ep1_rx_space_i |
,input ep1_tx_ready_i |
,input ep1_tx_data_valid_i |
,input ep1_tx_data_strb_i |
,input [ 7:0] ep1_tx_data_i |
,input ep1_tx_data_last_i |
,input ep2_stall_i |
,input ep2_iso_i |
,input ep2_cfg_int_rx_i |
,input ep2_cfg_int_tx_i |
,input ep2_rx_space_i |
,input ep2_tx_ready_i |
,input ep2_tx_data_valid_i |
,input ep2_tx_data_strb_i |
,input [ 7:0] ep2_tx_data_i |
,input ep2_tx_data_last_i |
,input ep3_stall_i |
,input ep3_iso_i |
,input ep3_cfg_int_rx_i |
,input ep3_cfg_int_tx_i |
,input ep3_rx_space_i |
,input ep3_tx_ready_i |
,input ep3_tx_data_valid_i |
,input ep3_tx_data_strb_i |
,input [ 7:0] ep3_tx_data_i |
,input ep3_tx_data_last_i |
,input reg_chirp_en_i |
,input reg_int_en_sof_i |
,input reg_sts_rst_clr_i |
,input [ 6:0] reg_dev_addr_i |
|
// Outputs |
,output intr_o |
,output [ 7:0] utmi_data_o |
,output utmi_txvalid_o |
,output rx_strb_o |
,output [ 7:0] rx_data_o |
,output rx_last_o |
,output rx_crc_err_o |
,output ep0_rx_setup_o |
,output ep0_rx_valid_o |
,output ep0_tx_data_accept_o |
,output ep1_rx_setup_o |
,output ep1_rx_valid_o |
,output ep1_tx_data_accept_o |
,output ep2_rx_setup_o |
,output ep2_rx_valid_o |
,output ep2_tx_data_accept_o |
,output ep3_rx_setup_o |
,output ep3_rx_valid_o |
,output ep3_tx_data_accept_o |
,output reg_sts_rst_o |
,output [ 10:0] reg_sts_frame_num_o |
); |
|
|
|
//----------------------------------------------------------------- |
// Defines: |
//----------------------------------------------------------------- |
`include "usbf_defs.v" |
|
`define USB_RESET_CNT_W 15 |
|
localparam STATE_W = 3; |
localparam STATE_RX_IDLE = 3'd0; |
localparam STATE_RX_DATA = 3'd1; |
localparam STATE_RX_DATA_READY = 3'd2; |
localparam STATE_RX_DATA_IGNORE = 3'd3; |
localparam STATE_TX_DATA = 3'd4; |
localparam STATE_TX_DATA_COMPLETE = 3'd5; |
localparam STATE_TX_HANDSHAKE = 3'd6; |
localparam STATE_TX_CHIRP = 3'd7; |
reg [STATE_W-1:0] state_q; |
|
//----------------------------------------------------------------- |
// Reset detection |
//----------------------------------------------------------------- |
reg [`USB_RESET_CNT_W-1:0] se0_cnt_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
se0_cnt_q <= `USB_RESET_CNT_W'b0; |
else if (utmi_linestate_i == 2'b0) |
begin |
if (!se0_cnt_q[`USB_RESET_CNT_W-1]) |
se0_cnt_q <= se0_cnt_q + `USB_RESET_CNT_W'd1; |
end |
else |
se0_cnt_q <= `USB_RESET_CNT_W'b0; |
|
wire usb_rst_w = se0_cnt_q[`USB_RESET_CNT_W-1]; |
|
//----------------------------------------------------------------- |
// Wire / Regs |
//----------------------------------------------------------------- |
`define USB_FRAME_W 11 |
wire [`USB_FRAME_W-1:0] frame_num_w; |
|
wire frame_valid_w; |
|
`define USB_DEV_W 7 |
wire [`USB_DEV_W-1:0] token_dev_w; |
|
`define USB_EP_W 4 |
wire [`USB_EP_W-1:0] token_ep_w; |
|
`define USB_PID_W 8 |
wire [`USB_PID_W-1:0] token_pid_w; |
|
wire token_valid_w; |
|
wire rx_data_valid_w; |
wire rx_data_complete_w; |
|
wire rx_handshake_w; |
|
reg tx_data_valid_r; |
reg tx_data_strb_r; |
reg [7:0] tx_data_r; |
reg tx_data_last_r; |
wire tx_data_accept_w; |
|
reg tx_valid_q; |
reg [7:0] tx_pid_q; |
wire tx_accept_w; |
|
reg rx_space_q; |
reg rx_space_r; |
reg tx_ready_r; |
reg ep_data_bit_r; |
|
reg ep_stall_r; |
reg ep_iso_r; |
|
reg rx_enable_q; |
reg rx_setup_q; |
|
reg ep0_data_bit_q; |
reg ep1_data_bit_q; |
reg ep2_data_bit_q; |
reg ep3_data_bit_q; |
|
wire status_stage_w; |
|
reg [`USB_DEV_W-1:0] current_addr_q; |
|
//----------------------------------------------------------------- |
// SIE - TX |
//----------------------------------------------------------------- |
usbf_sie_tx |
u_sie_tx |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.enable_i(~usb_rst_w), |
.chirp_i(reg_chirp_en_i), |
|
// UTMI Interface |
.utmi_data_o(utmi_data_o), |
.utmi_txvalid_o(utmi_txvalid_o), |
.utmi_txready_i(utmi_txready_i), |
|
// Request |
.tx_valid_i(tx_valid_q), |
.tx_pid_i(tx_pid_q), |
.tx_accept_o(tx_accept_w), |
|
// Data |
.data_valid_i(tx_data_valid_r), |
.data_strb_i(tx_data_strb_r), |
.data_i(tx_data_r), |
.data_last_i(tx_data_last_r), |
.data_accept_o(tx_data_accept_w) |
); |
|
always @ * |
begin |
tx_data_valid_r = 1'b0; |
tx_data_strb_r = 1'b0; |
tx_data_r = 8'b0; |
tx_data_last_r = 1'b0; |
|
case (token_ep_w) |
4'd0: |
begin |
tx_data_valid_r = ep0_tx_data_valid_i; |
tx_data_strb_r = ep0_tx_data_strb_i; |
tx_data_r = ep0_tx_data_i; |
tx_data_last_r = ep0_tx_data_last_i; |
end |
4'd1: |
begin |
tx_data_valid_r = ep1_tx_data_valid_i; |
tx_data_strb_r = ep1_tx_data_strb_i; |
tx_data_r = ep1_tx_data_i; |
tx_data_last_r = ep1_tx_data_last_i; |
end |
4'd2: |
begin |
tx_data_valid_r = ep2_tx_data_valid_i; |
tx_data_strb_r = ep2_tx_data_strb_i; |
tx_data_r = ep2_tx_data_i; |
tx_data_last_r = ep2_tx_data_last_i; |
end |
4'd3: |
begin |
tx_data_valid_r = ep3_tx_data_valid_i; |
tx_data_strb_r = ep3_tx_data_strb_i; |
tx_data_r = ep3_tx_data_i; |
tx_data_last_r = ep3_tx_data_last_i; |
end |
default: |
; |
endcase |
end |
|
assign ep0_tx_data_accept_o = tx_data_accept_w & (token_ep_w == 4'd0); |
assign ep1_tx_data_accept_o = tx_data_accept_w & (token_ep_w == 4'd1); |
assign ep2_tx_data_accept_o = tx_data_accept_w & (token_ep_w == 4'd2); |
assign ep3_tx_data_accept_o = tx_data_accept_w & (token_ep_w == 4'd3); |
|
always @ * |
begin |
rx_space_r = 1'b0; |
tx_ready_r = 1'b0; |
ep_data_bit_r = 1'b0; |
|
ep_stall_r = 1'b0; |
ep_iso_r = 1'b0; |
|
case (token_ep_w) |
4'd0: |
begin |
rx_space_r = ep0_rx_space_i; |
tx_ready_r = ep0_tx_ready_i; |
ep_data_bit_r = ep0_data_bit_q | status_stage_w; |
ep_stall_r = ep0_stall_i; |
ep_iso_r = ep0_iso_i; |
end |
4'd1: |
begin |
rx_space_r = ep1_rx_space_i; |
tx_ready_r = ep1_tx_ready_i; |
ep_data_bit_r = ep1_data_bit_q | status_stage_w; |
ep_stall_r = ep1_stall_i; |
ep_iso_r = ep1_iso_i; |
end |
4'd2: |
begin |
rx_space_r = ep2_rx_space_i; |
tx_ready_r = ep2_tx_ready_i; |
ep_data_bit_r = ep2_data_bit_q | status_stage_w; |
ep_stall_r = ep2_stall_i; |
ep_iso_r = ep2_iso_i; |
end |
4'd3: |
begin |
rx_space_r = ep3_rx_space_i; |
tx_ready_r = ep3_tx_ready_i; |
ep_data_bit_r = ep3_data_bit_q | status_stage_w; |
ep_stall_r = ep3_stall_i; |
ep_iso_r = ep3_iso_i; |
end |
default: |
; |
endcase |
end |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rx_space_q <= 1'b0; |
else if (state_q == STATE_RX_IDLE) |
rx_space_q <= rx_space_r; |
|
//----------------------------------------------------------------- |
// SIE - RX |
//----------------------------------------------------------------- |
usbf_sie_rx |
u_sie_rx |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.enable_i(~usb_rst_w && ~reg_chirp_en_i), |
|
// UTMI Interface |
.utmi_data_i(utmi_data_i), |
.utmi_rxvalid_i(utmi_rxvalid_i), |
.utmi_rxactive_i(utmi_rxactive_i), |
|
.current_addr_i(current_addr_q), |
|
.pid_o(token_pid_w), |
|
.frame_valid_o(frame_valid_w), |
.frame_number_o(reg_sts_frame_num_o), |
|
.token_valid_o(token_valid_w), |
.token_addr_o(token_dev_w), |
.token_ep_o(token_ep_w), |
.token_crc_err_o(), |
|
.handshake_valid_o(rx_handshake_w), |
|
.data_valid_o(rx_data_valid_w), |
.data_strb_o(rx_strb_o), |
.data_o(rx_data_o), |
.data_last_o(rx_last_o), |
|
.data_complete_o(rx_data_complete_w), |
.data_crc_err_o(rx_crc_err_o) |
); |
|
assign ep0_rx_valid_o = rx_enable_q & rx_data_valid_w & (token_ep_w == 4'd0); |
assign ep0_rx_setup_o = rx_setup_q & (token_ep_w == 4'd0); |
assign ep1_rx_valid_o = rx_enable_q & rx_data_valid_w & (token_ep_w == 4'd1); |
assign ep1_rx_setup_o = rx_setup_q & (token_ep_w == 4'd0); |
assign ep2_rx_valid_o = rx_enable_q & rx_data_valid_w & (token_ep_w == 4'd2); |
assign ep2_rx_setup_o = rx_setup_q & (token_ep_w == 4'd0); |
assign ep3_rx_valid_o = rx_enable_q & rx_data_valid_w & (token_ep_w == 4'd3); |
assign ep3_rx_setup_o = rx_setup_q & (token_ep_w == 4'd0); |
|
//----------------------------------------------------------------- |
// Next state |
//----------------------------------------------------------------- |
reg [STATE_W-1:0] next_state_r; |
|
always @ * |
begin |
next_state_r = state_q; |
|
//----------------------------------------- |
// State Machine |
//----------------------------------------- |
case (state_q) |
|
//----------------------------------------- |
// IDLE |
//----------------------------------------- |
STATE_RX_IDLE : |
begin |
// Token received (OUT, IN, SETUP, PING) |
if (token_valid_w) |
begin |
//------------------------------- |
// IN transfer (device -> host) |
//------------------------------- |
if (token_pid_w == `PID_IN) |
begin |
// Stalled endpoint? |
if (ep_stall_r) |
next_state_r = STATE_TX_HANDSHAKE; |
// Some data to TX? |
else if (tx_ready_r) |
next_state_r = STATE_TX_DATA; |
// No data to TX |
else |
next_state_r = STATE_TX_HANDSHAKE; |
end |
//------------------------------- |
// PING transfer (device -> host) |
//------------------------------- |
else if (token_pid_w == `PID_PING) |
begin |
next_state_r = STATE_TX_HANDSHAKE; |
end |
//------------------------------- |
// OUT transfer (host -> device) |
//------------------------------- |
else if (token_pid_w == `PID_OUT) |
begin |
// Stalled endpoint? |
if (ep_stall_r) |
next_state_r = STATE_RX_DATA_IGNORE; |
// Some space to rx |
else if (rx_space_r) |
next_state_r = STATE_RX_DATA; |
// No rx space, ignore receive |
else |
next_state_r = STATE_RX_DATA_IGNORE; |
end |
//------------------------------- |
// SETUP transfer (host -> device) |
//------------------------------- |
else if (token_pid_w == `PID_SETUP) |
begin |
// Some space to rx |
if (rx_space_r) |
next_state_r = STATE_RX_DATA; |
// No rx space, ignore receive |
else |
next_state_r = STATE_RX_DATA_IGNORE; |
end |
end |
else if (reg_chirp_en_i) |
next_state_r = STATE_TX_CHIRP; |
end |
|
//----------------------------------------- |
// RX_DATA |
//----------------------------------------- |
STATE_RX_DATA : |
begin |
// TODO: Exit data state handling? |
|
// TODO: Sort out ISO data bit handling |
// Check for expected DATAx PID |
if ((token_pid_w == `PID_DATA0 && ep_data_bit_r && !ep_iso_r) || |
(token_pid_w == `PID_DATA1 && !ep_data_bit_r && !ep_iso_r)) |
next_state_r = STATE_RX_DATA_IGNORE; |
// Receive complete |
else if (rx_data_valid_w && rx_last_o) |
next_state_r = STATE_RX_DATA_READY; |
end |
//----------------------------------------- |
// RX_DATA_IGNORE |
//----------------------------------------- |
STATE_RX_DATA_IGNORE : |
begin |
// Receive complete |
if (rx_data_valid_w && rx_last_o) |
next_state_r = STATE_RX_DATA_READY; |
end |
//----------------------------------------- |
// RX_DATA_READY |
//----------------------------------------- |
STATE_RX_DATA_READY : |
begin |
if (rx_data_complete_w) |
begin |
// No response on CRC16 error |
if (rx_crc_err_o) |
next_state_r = STATE_RX_IDLE; |
// ISO endpoint, no response? |
else if (ep_iso_r) |
next_state_r = STATE_RX_IDLE; |
else |
next_state_r = STATE_TX_HANDSHAKE; |
end |
end |
//----------------------------------------- |
// TX_DATA |
//----------------------------------------- |
STATE_TX_DATA : |
begin |
if (!tx_valid_q || tx_accept_w) |
if (tx_data_valid_r && tx_data_last_r && tx_data_accept_w) |
next_state_r = STATE_TX_DATA_COMPLETE; |
end |
//----------------------------------------- |
// TX_HANDSHAKE |
//----------------------------------------- |
STATE_TX_DATA_COMPLETE : |
begin |
next_state_r = STATE_RX_IDLE; |
end |
//----------------------------------------- |
// TX_HANDSHAKE |
//----------------------------------------- |
STATE_TX_HANDSHAKE : |
begin |
if (tx_accept_w) |
next_state_r = STATE_RX_IDLE; |
end |
//----------------------------------------- |
// TX_CHIRP |
//----------------------------------------- |
STATE_TX_CHIRP : |
begin |
if (!reg_chirp_en_i) |
next_state_r = STATE_RX_IDLE; |
end |
|
default : |
; |
|
endcase |
|
//----------------------------------------- |
// USB Bus Reset (HOST->DEVICE) |
//----------------------------------------- |
if (usb_rst_w && !reg_chirp_en_i) |
next_state_r = STATE_RX_IDLE; |
end |
|
// Update state |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
state_q <= STATE_RX_IDLE; |
else |
state_q <= next_state_r; |
|
//----------------------------------------------------------------- |
// Response |
//----------------------------------------------------------------- |
reg tx_valid_r; |
reg [7:0] tx_pid_r; |
|
always @ * |
begin |
tx_valid_r = 1'b0; |
tx_pid_r = 8'b0; |
|
case (state_q) |
//----------------------------------------- |
// IDLE |
//----------------------------------------- |
STATE_RX_IDLE : |
begin |
// Token received (OUT, IN, SETUP, PING) |
if (token_valid_w) |
begin |
//------------------------------- |
// IN transfer (device -> host) |
//------------------------------- |
if (token_pid_w == `PID_IN) |
begin |
// Stalled endpoint? |
if (ep_stall_r) |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_STALL; |
end |
// Some data to TX? |
else if (tx_ready_r) |
begin |
tx_valid_r = 1'b1; |
// TODO: Handle MDATA for ISOs |
tx_pid_r = ep_data_bit_r ? `PID_DATA1 : `PID_DATA0; |
end |
// No data to TX |
else |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_NAK; |
end |
end |
//------------------------------- |
// PING transfer (device -> host) |
//------------------------------- |
else if (token_pid_w == `PID_PING) |
begin |
// Stalled endpoint? |
if (ep_stall_r) |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_STALL; |
end |
// Data ready to RX |
else if (rx_space_r) |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_ACK; |
end |
// No data to TX |
else |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_NAK; |
end |
end |
end |
end |
|
//----------------------------------------- |
// RX_DATA_READY |
//----------------------------------------- |
STATE_RX_DATA_READY : |
begin |
// Receive complete |
if (rx_data_complete_w) |
begin |
// No response on CRC16 error |
if (rx_crc_err_o) |
; |
// ISO endpoint, no response? |
else if (ep_iso_r) |
; |
// Send STALL? |
else if (ep_stall_r) |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_STALL; |
end |
// DATAx bit mismatch |
else if ( (token_pid_w == `PID_DATA0 && ep_data_bit_r) || |
(token_pid_w == `PID_DATA1 && !ep_data_bit_r) ) |
begin |
// Ack transfer to resync |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_ACK; |
end |
// Send NAK |
else if (!rx_space_q) |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_NAK; |
end |
// TODO: USB 2.0, no more buffer space, return NYET |
else |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = `PID_ACK; |
end |
end |
end |
|
//----------------------------------------- |
// TX_CHIRP |
//----------------------------------------- |
STATE_TX_CHIRP : |
begin |
tx_valid_r = 1'b1; |
tx_pid_r = 8'b0; |
end |
|
default : |
; |
|
endcase |
end |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
tx_valid_q <= 1'b0; |
else if (!tx_valid_q || tx_accept_w) |
tx_valid_q <= tx_valid_r; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
tx_pid_q <= 8'b0; |
else if (!tx_valid_q || tx_accept_w) |
tx_pid_q <= tx_pid_r; |
|
//----------------------------------------------------------------- |
// Receive enable |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rx_enable_q <= 1'b0; |
else if (usb_rst_w ||reg_chirp_en_i) |
rx_enable_q <= 1'b0; |
else |
rx_enable_q <= (state_q == STATE_RX_DATA); |
|
//----------------------------------------------------------------- |
// Receive SETUP: Pulse on SETUP packet receive |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rx_setup_q <= 1'b0; |
else if (usb_rst_w ||reg_chirp_en_i) |
rx_setup_q <= 1'b0; |
else if ((state_q == STATE_RX_IDLE) && token_valid_w && (token_pid_w == `PID_SETUP) && (token_ep_w == 4'd0)) |
rx_setup_q <= 1'b1; |
else |
rx_setup_q <= 1'b0; |
|
//----------------------------------------------------------------- |
// Set Address |
//----------------------------------------------------------------- |
reg addr_update_pending_q; |
|
wire ep0_tx_zlp_w = ep0_tx_data_valid_i && (ep0_tx_data_strb_i == 1'b0) && |
ep0_tx_data_last_i && ep0_tx_data_accept_o; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
addr_update_pending_q <= 1'b0; |
else if (ep0_tx_zlp_w || usb_rst_w) |
addr_update_pending_q <= 1'b0; |
// TODO: Use write strobe |
else if (reg_dev_addr_i != current_addr_q) |
addr_update_pending_q <= 1'b1; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
current_addr_q <= `USB_DEV_W'b0; |
else if (usb_rst_w) |
current_addr_q <= `USB_DEV_W'b0; |
else if (ep0_tx_zlp_w && addr_update_pending_q) |
current_addr_q <= reg_dev_addr_i; |
|
//----------------------------------------------------------------- |
// SETUP request tracking |
//----------------------------------------------------------------- |
reg ep0_dir_in_q; |
reg ep0_dir_out_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
ep0_dir_in_q <= 1'b0; |
else if (usb_rst_w ||reg_chirp_en_i) |
ep0_dir_in_q <= 1'b0; |
else if ((state_q == STATE_RX_IDLE) && token_valid_w && (token_pid_w == `PID_SETUP) && (token_ep_w == 4'd0)) |
ep0_dir_in_q <= 1'b0; |
else if ((state_q == STATE_RX_IDLE) && token_valid_w && (token_pid_w == `PID_IN) && (token_ep_w == 4'd0)) |
ep0_dir_in_q <= 1'b1; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
ep0_dir_out_q <= 1'b0; |
else if (usb_rst_w ||reg_chirp_en_i) |
ep0_dir_out_q <= 1'b0; |
else if ((state_q == STATE_RX_IDLE) && token_valid_w && (token_pid_w == `PID_SETUP) && (token_ep_w == 4'd0)) |
ep0_dir_out_q <= 1'b0; |
else if ((state_q == STATE_RX_IDLE) && token_valid_w && (token_pid_w == `PID_OUT) && (token_ep_w == 4'd0)) |
ep0_dir_out_q <= 1'b1; |
|
assign status_stage_w = ep0_dir_in_q && ep0_dir_out_q && (token_ep_w == 4'd0); |
|
//----------------------------------------------------------------- |
// Endpoint data bit toggle |
//----------------------------------------------------------------- |
reg new_data_bit_r; |
always @ * |
begin |
new_data_bit_r = ep_data_bit_r; |
|
case (state_q) |
//----------------------------------------- |
// RX_DATA_READY |
//----------------------------------------- |
STATE_RX_DATA_READY : |
begin |
// Receive complete |
if (rx_data_complete_w) |
begin |
// No toggle on CRC16 error |
if (rx_crc_err_o) |
; |
// ISO endpoint, no response? |
else if (ep_iso_r) |
; // TODO: HS handling |
// STALL? |
else if (ep_stall_r) |
; |
// DATAx bit mismatch |
else if ( (token_pid_w == `PID_DATA0 && ep_data_bit_r) || |
(token_pid_w == `PID_DATA1 && !ep_data_bit_r) ) |
; |
// NAKd |
else if (!rx_space_q) |
; |
// Data accepted - toggle data bit |
else |
new_data_bit_r = !ep_data_bit_r; |
end |
end |
//----------------------------------------- |
// RX_IDLE |
//----------------------------------------- |
STATE_RX_IDLE : |
begin |
// Token received (OUT, IN, SETUP, PING) |
if (token_valid_w) |
begin |
// SETUP packets always start with DATA0 |
if (token_pid_w == `PID_SETUP) |
new_data_bit_r = 1'b0; |
end |
// ACK received |
else if (rx_handshake_w && token_pid_w == `PID_ACK) |
begin |
new_data_bit_r = !ep_data_bit_r; |
end |
end |
default: |
; |
endcase |
end |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
ep0_data_bit_q <= 1'b0; |
else if (usb_rst_w) |
ep0_data_bit_q <= 1'b0; |
else if (token_ep_w == 4'd0) |
ep0_data_bit_q <= new_data_bit_r; |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
ep1_data_bit_q <= 1'b0; |
else if (usb_rst_w) |
ep1_data_bit_q <= 1'b0; |
else if (token_ep_w == 4'd1) |
ep1_data_bit_q <= new_data_bit_r; |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
ep2_data_bit_q <= 1'b0; |
else if (usb_rst_w) |
ep2_data_bit_q <= 1'b0; |
else if (token_ep_w == 4'd2) |
ep2_data_bit_q <= new_data_bit_r; |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
ep3_data_bit_q <= 1'b0; |
else if (usb_rst_w) |
ep3_data_bit_q <= 1'b0; |
else if (token_ep_w == 4'd3) |
ep3_data_bit_q <= new_data_bit_r; |
|
//----------------------------------------------------------------- |
// Reset event |
//----------------------------------------------------------------- |
reg rst_event_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rst_event_q <= 1'b0; |
else if (usb_rst_w) |
rst_event_q <= 1'b1; |
else if (reg_sts_rst_clr_i) |
rst_event_q <= 1'b0; |
|
assign reg_sts_rst_o = rst_event_q; |
|
//----------------------------------------------------------------- |
// Interrupts |
//----------------------------------------------------------------- |
reg intr_q; |
|
reg cfg_int_rx_r; |
reg cfg_int_tx_r; |
|
always @ * |
begin |
cfg_int_rx_r = 1'b0; |
cfg_int_tx_r = 1'b0; |
|
case (token_ep_w) |
4'd0: |
begin |
cfg_int_rx_r = ep0_cfg_int_rx_i; |
cfg_int_tx_r = ep0_cfg_int_tx_i; |
end |
4'd1: |
begin |
cfg_int_rx_r = ep1_cfg_int_rx_i; |
cfg_int_tx_r = ep1_cfg_int_tx_i; |
end |
4'd2: |
begin |
cfg_int_rx_r = ep2_cfg_int_rx_i; |
cfg_int_tx_r = ep2_cfg_int_tx_i; |
end |
4'd3: |
begin |
cfg_int_rx_r = ep3_cfg_int_rx_i; |
cfg_int_tx_r = ep3_cfg_int_tx_i; |
end |
default: |
; |
endcase |
end |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
intr_q <= 1'b0; |
// SOF |
else if (frame_valid_w && reg_int_en_sof_i) |
intr_q <= 1'b1; |
// Reset event |
else if (!rst_event_q && usb_rst_w) |
intr_q <= 1'b1; |
// Rx ready |
else if (state_q == STATE_RX_DATA_READY && rx_space_q && cfg_int_rx_r) |
intr_q <= 1'b1; |
// Tx complete |
else if (state_q == STATE_TX_DATA_COMPLETE && cfg_int_tx_r) |
intr_q <= 1'b1; |
else |
intr_q <= 1'b0; |
|
assign intr_o = intr_q; |
|
//------------------------------------------------------------------- |
// Debug |
//------------------------------------------------------------------- |
`ifdef verilator |
/* verilator lint_off WIDTH */ |
reg [79:0] dbg_state; |
|
always @ * |
begin |
dbg_state = "-"; |
|
case (state_q) |
STATE_RX_IDLE: dbg_state = "IDLE"; |
STATE_RX_DATA: dbg_state = "RX_DATA"; |
STATE_RX_DATA_READY: dbg_state = "RX_DATA_READY"; |
STATE_RX_DATA_IGNORE: dbg_state = "RX_IGNORE"; |
STATE_TX_DATA: dbg_state = "TX_DATA"; |
STATE_TX_DATA_COMPLETE: dbg_state = "TX_DATA_COMPLETE"; |
STATE_TX_HANDSHAKE: dbg_state = "TX_HANDSHAKE"; |
STATE_TX_CHIRP: dbg_state = "CHIRP"; |
endcase |
end |
|
reg [79:0] dbg_pid; |
reg [7:0] dbg_pid_r; |
always @ * |
begin |
dbg_pid = "-"; |
|
if (tx_valid_q && tx_accept_w) |
dbg_pid_r = tx_pid_q; |
else if (token_valid_w || rx_handshake_w || rx_data_valid_w) |
dbg_pid_r = token_pid_w; |
else |
dbg_pid_r = 8'b0; |
|
case (dbg_pid_r) |
// Token |
`PID_OUT: |
dbg_pid = "OUT"; |
`PID_IN: |
dbg_pid = "IN"; |
`PID_SOF: |
dbg_pid = "SOF"; |
`PID_SETUP: |
dbg_pid = "SETUP"; |
`PID_PING: |
dbg_pid = "PING"; |
// Data |
`PID_DATA0: |
dbg_pid = "DATA0"; |
`PID_DATA1: |
dbg_pid = "DATA1"; |
`PID_DATA2: |
dbg_pid = "DATA2"; |
`PID_MDATA: |
dbg_pid = "MDATA"; |
// Handshake |
`PID_ACK: |
dbg_pid = "ACK"; |
`PID_NAK: |
dbg_pid = "NAK"; |
`PID_STALL: |
dbg_pid = "STALL"; |
`PID_NYET: |
dbg_pid = "NYET"; |
// Special |
`PID_PRE: |
dbg_pid = "PRE/ERR"; |
`PID_SPLIT: |
dbg_pid = "SPLIT"; |
default: |
; |
endcase |
end |
/* verilator lint_on WIDTH */ |
`endif |
|
|
endmodule |
/usb_device_core/trunk/src_v/usbf_device_defs.v
0,0 → 1,588
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
|
`define USB_FUNC_CTRL 8'h0 |
|
`define USB_FUNC_CTRL_HS_CHIRP_EN 8 |
`define USB_FUNC_CTRL_HS_CHIRP_EN_DEFAULT 0 |
`define USB_FUNC_CTRL_HS_CHIRP_EN_B 8 |
`define USB_FUNC_CTRL_HS_CHIRP_EN_T 8 |
`define USB_FUNC_CTRL_HS_CHIRP_EN_W 1 |
`define USB_FUNC_CTRL_HS_CHIRP_EN_R 8:8 |
|
`define USB_FUNC_CTRL_PHY_DMPULLDOWN 7 |
`define USB_FUNC_CTRL_PHY_DMPULLDOWN_DEFAULT 0 |
`define USB_FUNC_CTRL_PHY_DMPULLDOWN_B 7 |
`define USB_FUNC_CTRL_PHY_DMPULLDOWN_T 7 |
`define USB_FUNC_CTRL_PHY_DMPULLDOWN_W 1 |
`define USB_FUNC_CTRL_PHY_DMPULLDOWN_R 7:7 |
|
`define USB_FUNC_CTRL_PHY_DPPULLDOWN 6 |
`define USB_FUNC_CTRL_PHY_DPPULLDOWN_DEFAULT 0 |
`define USB_FUNC_CTRL_PHY_DPPULLDOWN_B 6 |
`define USB_FUNC_CTRL_PHY_DPPULLDOWN_T 6 |
`define USB_FUNC_CTRL_PHY_DPPULLDOWN_W 1 |
`define USB_FUNC_CTRL_PHY_DPPULLDOWN_R 6:6 |
|
`define USB_FUNC_CTRL_PHY_TERMSELECT 5 |
`define USB_FUNC_CTRL_PHY_TERMSELECT_DEFAULT 0 |
`define USB_FUNC_CTRL_PHY_TERMSELECT_B 5 |
`define USB_FUNC_CTRL_PHY_TERMSELECT_T 5 |
`define USB_FUNC_CTRL_PHY_TERMSELECT_W 1 |
`define USB_FUNC_CTRL_PHY_TERMSELECT_R 5:5 |
|
`define USB_FUNC_CTRL_PHY_XCVRSELECT_DEFAULT 0 |
`define USB_FUNC_CTRL_PHY_XCVRSELECT_B 3 |
`define USB_FUNC_CTRL_PHY_XCVRSELECT_T 4 |
`define USB_FUNC_CTRL_PHY_XCVRSELECT_W 2 |
`define USB_FUNC_CTRL_PHY_XCVRSELECT_R 4:3 |
|
`define USB_FUNC_CTRL_PHY_OPMODE_DEFAULT 0 |
`define USB_FUNC_CTRL_PHY_OPMODE_B 1 |
`define USB_FUNC_CTRL_PHY_OPMODE_T 2 |
`define USB_FUNC_CTRL_PHY_OPMODE_W 2 |
`define USB_FUNC_CTRL_PHY_OPMODE_R 2:1 |
|
`define USB_FUNC_CTRL_INT_EN_SOF 0 |
`define USB_FUNC_CTRL_INT_EN_SOF_DEFAULT 0 |
`define USB_FUNC_CTRL_INT_EN_SOF_B 0 |
`define USB_FUNC_CTRL_INT_EN_SOF_T 0 |
`define USB_FUNC_CTRL_INT_EN_SOF_W 1 |
`define USB_FUNC_CTRL_INT_EN_SOF_R 0:0 |
|
`define USB_FUNC_STAT 8'h4 |
|
`define USB_FUNC_STAT_RST 13 |
`define USB_FUNC_STAT_RST_DEFAULT 0 |
`define USB_FUNC_STAT_RST_B 13 |
`define USB_FUNC_STAT_RST_T 13 |
`define USB_FUNC_STAT_RST_W 1 |
`define USB_FUNC_STAT_RST_R 13:13 |
|
`define USB_FUNC_STAT_LINESTATE_DEFAULT 0 |
`define USB_FUNC_STAT_LINESTATE_B 11 |
`define USB_FUNC_STAT_LINESTATE_T 12 |
`define USB_FUNC_STAT_LINESTATE_W 2 |
`define USB_FUNC_STAT_LINESTATE_R 12:11 |
|
`define USB_FUNC_STAT_FRAME_DEFAULT 0 |
`define USB_FUNC_STAT_FRAME_B 0 |
`define USB_FUNC_STAT_FRAME_T 10 |
`define USB_FUNC_STAT_FRAME_W 11 |
`define USB_FUNC_STAT_FRAME_R 10:0 |
|
`define USB_FUNC_ADDR 8'h8 |
|
`define USB_FUNC_ADDR_DEV_ADDR_DEFAULT 0 |
`define USB_FUNC_ADDR_DEV_ADDR_B 0 |
`define USB_FUNC_ADDR_DEV_ADDR_T 6 |
`define USB_FUNC_ADDR_DEV_ADDR_W 7 |
`define USB_FUNC_ADDR_DEV_ADDR_R 6:0 |
|
`define USB_EP0_CFG 8'hc |
|
`define USB_EP0_CFG_INT_RX 3 |
`define USB_EP0_CFG_INT_RX_DEFAULT 0 |
`define USB_EP0_CFG_INT_RX_B 3 |
`define USB_EP0_CFG_INT_RX_T 3 |
`define USB_EP0_CFG_INT_RX_W 1 |
`define USB_EP0_CFG_INT_RX_R 3:3 |
|
`define USB_EP0_CFG_INT_TX 2 |
`define USB_EP0_CFG_INT_TX_DEFAULT 0 |
`define USB_EP0_CFG_INT_TX_B 2 |
`define USB_EP0_CFG_INT_TX_T 2 |
`define USB_EP0_CFG_INT_TX_W 1 |
`define USB_EP0_CFG_INT_TX_R 2:2 |
|
`define USB_EP0_CFG_STALL_EP 1 |
`define USB_EP0_CFG_STALL_EP_DEFAULT 0 |
`define USB_EP0_CFG_STALL_EP_B 1 |
`define USB_EP0_CFG_STALL_EP_T 1 |
`define USB_EP0_CFG_STALL_EP_W 1 |
`define USB_EP0_CFG_STALL_EP_R 1:1 |
|
`define USB_EP0_CFG_ISO 0 |
`define USB_EP0_CFG_ISO_DEFAULT 0 |
`define USB_EP0_CFG_ISO_B 0 |
`define USB_EP0_CFG_ISO_T 0 |
`define USB_EP0_CFG_ISO_W 1 |
`define USB_EP0_CFG_ISO_R 0:0 |
|
`define USB_EP0_TX_CTRL 8'h10 |
|
`define USB_EP0_TX_CTRL_TX_FLUSH 17 |
`define USB_EP0_TX_CTRL_TX_FLUSH_DEFAULT 0 |
`define USB_EP0_TX_CTRL_TX_FLUSH_B 17 |
`define USB_EP0_TX_CTRL_TX_FLUSH_T 17 |
`define USB_EP0_TX_CTRL_TX_FLUSH_W 1 |
`define USB_EP0_TX_CTRL_TX_FLUSH_R 17:17 |
|
`define USB_EP0_TX_CTRL_TX_START 16 |
`define USB_EP0_TX_CTRL_TX_START_DEFAULT 0 |
`define USB_EP0_TX_CTRL_TX_START_B 16 |
`define USB_EP0_TX_CTRL_TX_START_T 16 |
`define USB_EP0_TX_CTRL_TX_START_W 1 |
`define USB_EP0_TX_CTRL_TX_START_R 16:16 |
|
`define USB_EP0_TX_CTRL_TX_LEN_DEFAULT 0 |
`define USB_EP0_TX_CTRL_TX_LEN_B 0 |
`define USB_EP0_TX_CTRL_TX_LEN_T 10 |
`define USB_EP0_TX_CTRL_TX_LEN_W 11 |
`define USB_EP0_TX_CTRL_TX_LEN_R 10:0 |
|
`define USB_EP0_RX_CTRL 8'h14 |
|
`define USB_EP0_RX_CTRL_RX_FLUSH 1 |
`define USB_EP0_RX_CTRL_RX_FLUSH_DEFAULT 0 |
`define USB_EP0_RX_CTRL_RX_FLUSH_B 1 |
`define USB_EP0_RX_CTRL_RX_FLUSH_T 1 |
`define USB_EP0_RX_CTRL_RX_FLUSH_W 1 |
`define USB_EP0_RX_CTRL_RX_FLUSH_R 1:1 |
|
`define USB_EP0_RX_CTRL_RX_ACCEPT 0 |
`define USB_EP0_RX_CTRL_RX_ACCEPT_DEFAULT 0 |
`define USB_EP0_RX_CTRL_RX_ACCEPT_B 0 |
`define USB_EP0_RX_CTRL_RX_ACCEPT_T 0 |
`define USB_EP0_RX_CTRL_RX_ACCEPT_W 1 |
`define USB_EP0_RX_CTRL_RX_ACCEPT_R 0:0 |
|
`define USB_EP0_STS 8'h18 |
|
`define USB_EP0_STS_TX_ERR 20 |
`define USB_EP0_STS_TX_ERR_DEFAULT 0 |
`define USB_EP0_STS_TX_ERR_B 20 |
`define USB_EP0_STS_TX_ERR_T 20 |
`define USB_EP0_STS_TX_ERR_W 1 |
`define USB_EP0_STS_TX_ERR_R 20:20 |
|
`define USB_EP0_STS_TX_BUSY 19 |
`define USB_EP0_STS_TX_BUSY_DEFAULT 0 |
`define USB_EP0_STS_TX_BUSY_B 19 |
`define USB_EP0_STS_TX_BUSY_T 19 |
`define USB_EP0_STS_TX_BUSY_W 1 |
`define USB_EP0_STS_TX_BUSY_R 19:19 |
|
`define USB_EP0_STS_RX_ERR 18 |
`define USB_EP0_STS_RX_ERR_DEFAULT 0 |
`define USB_EP0_STS_RX_ERR_B 18 |
`define USB_EP0_STS_RX_ERR_T 18 |
`define USB_EP0_STS_RX_ERR_W 1 |
`define USB_EP0_STS_RX_ERR_R 18:18 |
|
`define USB_EP0_STS_RX_SETUP 17 |
`define USB_EP0_STS_RX_SETUP_DEFAULT 0 |
`define USB_EP0_STS_RX_SETUP_B 17 |
`define USB_EP0_STS_RX_SETUP_T 17 |
`define USB_EP0_STS_RX_SETUP_W 1 |
`define USB_EP0_STS_RX_SETUP_R 17:17 |
|
`define USB_EP0_STS_RX_READY 16 |
`define USB_EP0_STS_RX_READY_DEFAULT 0 |
`define USB_EP0_STS_RX_READY_B 16 |
`define USB_EP0_STS_RX_READY_T 16 |
`define USB_EP0_STS_RX_READY_W 1 |
`define USB_EP0_STS_RX_READY_R 16:16 |
|
`define USB_EP0_STS_RX_COUNT_DEFAULT 0 |
`define USB_EP0_STS_RX_COUNT_B 0 |
`define USB_EP0_STS_RX_COUNT_T 10 |
`define USB_EP0_STS_RX_COUNT_W 11 |
`define USB_EP0_STS_RX_COUNT_R 10:0 |
|
`define USB_EP0_DATA 8'h1c |
|
`define USB_EP0_DATA_DATA_DEFAULT 0 |
`define USB_EP0_DATA_DATA_B 0 |
`define USB_EP0_DATA_DATA_T 7 |
`define USB_EP0_DATA_DATA_W 8 |
`define USB_EP0_DATA_DATA_R 7:0 |
|
`define USB_EP1_CFG 8'h20 |
|
`define USB_EP1_CFG_INT_RX 3 |
`define USB_EP1_CFG_INT_RX_DEFAULT 0 |
`define USB_EP1_CFG_INT_RX_B 3 |
`define USB_EP1_CFG_INT_RX_T 3 |
`define USB_EP1_CFG_INT_RX_W 1 |
`define USB_EP1_CFG_INT_RX_R 3:3 |
|
`define USB_EP1_CFG_INT_TX 2 |
`define USB_EP1_CFG_INT_TX_DEFAULT 0 |
`define USB_EP1_CFG_INT_TX_B 2 |
`define USB_EP1_CFG_INT_TX_T 2 |
`define USB_EP1_CFG_INT_TX_W 1 |
`define USB_EP1_CFG_INT_TX_R 2:2 |
|
`define USB_EP1_CFG_STALL_EP 1 |
`define USB_EP1_CFG_STALL_EP_DEFAULT 0 |
`define USB_EP1_CFG_STALL_EP_B 1 |
`define USB_EP1_CFG_STALL_EP_T 1 |
`define USB_EP1_CFG_STALL_EP_W 1 |
`define USB_EP1_CFG_STALL_EP_R 1:1 |
|
`define USB_EP1_CFG_ISO 0 |
`define USB_EP1_CFG_ISO_DEFAULT 0 |
`define USB_EP1_CFG_ISO_B 0 |
`define USB_EP1_CFG_ISO_T 0 |
`define USB_EP1_CFG_ISO_W 1 |
`define USB_EP1_CFG_ISO_R 0:0 |
|
`define USB_EP1_TX_CTRL 8'h24 |
|
`define USB_EP1_TX_CTRL_TX_FLUSH 17 |
`define USB_EP1_TX_CTRL_TX_FLUSH_DEFAULT 0 |
`define USB_EP1_TX_CTRL_TX_FLUSH_B 17 |
`define USB_EP1_TX_CTRL_TX_FLUSH_T 17 |
`define USB_EP1_TX_CTRL_TX_FLUSH_W 1 |
`define USB_EP1_TX_CTRL_TX_FLUSH_R 17:17 |
|
`define USB_EP1_TX_CTRL_TX_START 16 |
`define USB_EP1_TX_CTRL_TX_START_DEFAULT 0 |
`define USB_EP1_TX_CTRL_TX_START_B 16 |
`define USB_EP1_TX_CTRL_TX_START_T 16 |
`define USB_EP1_TX_CTRL_TX_START_W 1 |
`define USB_EP1_TX_CTRL_TX_START_R 16:16 |
|
`define USB_EP1_TX_CTRL_TX_LEN_DEFAULT 0 |
`define USB_EP1_TX_CTRL_TX_LEN_B 0 |
`define USB_EP1_TX_CTRL_TX_LEN_T 10 |
`define USB_EP1_TX_CTRL_TX_LEN_W 11 |
`define USB_EP1_TX_CTRL_TX_LEN_R 10:0 |
|
`define USB_EP1_RX_CTRL 8'h28 |
|
`define USB_EP1_RX_CTRL_RX_FLUSH 1 |
`define USB_EP1_RX_CTRL_RX_FLUSH_DEFAULT 0 |
`define USB_EP1_RX_CTRL_RX_FLUSH_B 1 |
`define USB_EP1_RX_CTRL_RX_FLUSH_T 1 |
`define USB_EP1_RX_CTRL_RX_FLUSH_W 1 |
`define USB_EP1_RX_CTRL_RX_FLUSH_R 1:1 |
|
`define USB_EP1_RX_CTRL_RX_ACCEPT 0 |
`define USB_EP1_RX_CTRL_RX_ACCEPT_DEFAULT 0 |
`define USB_EP1_RX_CTRL_RX_ACCEPT_B 0 |
`define USB_EP1_RX_CTRL_RX_ACCEPT_T 0 |
`define USB_EP1_RX_CTRL_RX_ACCEPT_W 1 |
`define USB_EP1_RX_CTRL_RX_ACCEPT_R 0:0 |
|
`define USB_EP1_STS 8'h2c |
|
`define USB_EP1_STS_TX_ERR 20 |
`define USB_EP1_STS_TX_ERR_DEFAULT 0 |
`define USB_EP1_STS_TX_ERR_B 20 |
`define USB_EP1_STS_TX_ERR_T 20 |
`define USB_EP1_STS_TX_ERR_W 1 |
`define USB_EP1_STS_TX_ERR_R 20:20 |
|
`define USB_EP1_STS_TX_BUSY 19 |
`define USB_EP1_STS_TX_BUSY_DEFAULT 0 |
`define USB_EP1_STS_TX_BUSY_B 19 |
`define USB_EP1_STS_TX_BUSY_T 19 |
`define USB_EP1_STS_TX_BUSY_W 1 |
`define USB_EP1_STS_TX_BUSY_R 19:19 |
|
`define USB_EP1_STS_RX_ERR 18 |
`define USB_EP1_STS_RX_ERR_DEFAULT 0 |
`define USB_EP1_STS_RX_ERR_B 18 |
`define USB_EP1_STS_RX_ERR_T 18 |
`define USB_EP1_STS_RX_ERR_W 1 |
`define USB_EP1_STS_RX_ERR_R 18:18 |
|
`define USB_EP1_STS_RX_SETUP 17 |
`define USB_EP1_STS_RX_SETUP_DEFAULT 0 |
`define USB_EP1_STS_RX_SETUP_B 17 |
`define USB_EP1_STS_RX_SETUP_T 17 |
`define USB_EP1_STS_RX_SETUP_W 1 |
`define USB_EP1_STS_RX_SETUP_R 17:17 |
|
`define USB_EP1_STS_RX_READY 16 |
`define USB_EP1_STS_RX_READY_DEFAULT 0 |
`define USB_EP1_STS_RX_READY_B 16 |
`define USB_EP1_STS_RX_READY_T 16 |
`define USB_EP1_STS_RX_READY_W 1 |
`define USB_EP1_STS_RX_READY_R 16:16 |
|
`define USB_EP1_STS_RX_COUNT_DEFAULT 0 |
`define USB_EP1_STS_RX_COUNT_B 0 |
`define USB_EP1_STS_RX_COUNT_T 10 |
`define USB_EP1_STS_RX_COUNT_W 11 |
`define USB_EP1_STS_RX_COUNT_R 10:0 |
|
`define USB_EP1_DATA 8'h30 |
|
`define USB_EP1_DATA_DATA_DEFAULT 0 |
`define USB_EP1_DATA_DATA_B 0 |
`define USB_EP1_DATA_DATA_T 7 |
`define USB_EP1_DATA_DATA_W 8 |
`define USB_EP1_DATA_DATA_R 7:0 |
|
`define USB_EP2_CFG 8'h34 |
|
`define USB_EP2_CFG_INT_RX 3 |
`define USB_EP2_CFG_INT_RX_DEFAULT 0 |
`define USB_EP2_CFG_INT_RX_B 3 |
`define USB_EP2_CFG_INT_RX_T 3 |
`define USB_EP2_CFG_INT_RX_W 1 |
`define USB_EP2_CFG_INT_RX_R 3:3 |
|
`define USB_EP2_CFG_INT_TX 2 |
`define USB_EP2_CFG_INT_TX_DEFAULT 0 |
`define USB_EP2_CFG_INT_TX_B 2 |
`define USB_EP2_CFG_INT_TX_T 2 |
`define USB_EP2_CFG_INT_TX_W 1 |
`define USB_EP2_CFG_INT_TX_R 2:2 |
|
`define USB_EP2_CFG_STALL_EP 1 |
`define USB_EP2_CFG_STALL_EP_DEFAULT 0 |
`define USB_EP2_CFG_STALL_EP_B 1 |
`define USB_EP2_CFG_STALL_EP_T 1 |
`define USB_EP2_CFG_STALL_EP_W 1 |
`define USB_EP2_CFG_STALL_EP_R 1:1 |
|
`define USB_EP2_CFG_ISO 0 |
`define USB_EP2_CFG_ISO_DEFAULT 0 |
`define USB_EP2_CFG_ISO_B 0 |
`define USB_EP2_CFG_ISO_T 0 |
`define USB_EP2_CFG_ISO_W 1 |
`define USB_EP2_CFG_ISO_R 0:0 |
|
`define USB_EP2_TX_CTRL 8'h38 |
|
`define USB_EP2_TX_CTRL_TX_FLUSH 17 |
`define USB_EP2_TX_CTRL_TX_FLUSH_DEFAULT 0 |
`define USB_EP2_TX_CTRL_TX_FLUSH_B 17 |
`define USB_EP2_TX_CTRL_TX_FLUSH_T 17 |
`define USB_EP2_TX_CTRL_TX_FLUSH_W 1 |
`define USB_EP2_TX_CTRL_TX_FLUSH_R 17:17 |
|
`define USB_EP2_TX_CTRL_TX_START 16 |
`define USB_EP2_TX_CTRL_TX_START_DEFAULT 0 |
`define USB_EP2_TX_CTRL_TX_START_B 16 |
`define USB_EP2_TX_CTRL_TX_START_T 16 |
`define USB_EP2_TX_CTRL_TX_START_W 1 |
`define USB_EP2_TX_CTRL_TX_START_R 16:16 |
|
`define USB_EP2_TX_CTRL_TX_LEN_DEFAULT 0 |
`define USB_EP2_TX_CTRL_TX_LEN_B 0 |
`define USB_EP2_TX_CTRL_TX_LEN_T 10 |
`define USB_EP2_TX_CTRL_TX_LEN_W 11 |
`define USB_EP2_TX_CTRL_TX_LEN_R 10:0 |
|
`define USB_EP2_RX_CTRL 8'h3c |
|
`define USB_EP2_RX_CTRL_RX_FLUSH 1 |
`define USB_EP2_RX_CTRL_RX_FLUSH_DEFAULT 0 |
`define USB_EP2_RX_CTRL_RX_FLUSH_B 1 |
`define USB_EP2_RX_CTRL_RX_FLUSH_T 1 |
`define USB_EP2_RX_CTRL_RX_FLUSH_W 1 |
`define USB_EP2_RX_CTRL_RX_FLUSH_R 1:1 |
|
`define USB_EP2_RX_CTRL_RX_ACCEPT 0 |
`define USB_EP2_RX_CTRL_RX_ACCEPT_DEFAULT 0 |
`define USB_EP2_RX_CTRL_RX_ACCEPT_B 0 |
`define USB_EP2_RX_CTRL_RX_ACCEPT_T 0 |
`define USB_EP2_RX_CTRL_RX_ACCEPT_W 1 |
`define USB_EP2_RX_CTRL_RX_ACCEPT_R 0:0 |
|
`define USB_EP2_STS 8'h40 |
|
`define USB_EP2_STS_TX_ERR 20 |
`define USB_EP2_STS_TX_ERR_DEFAULT 0 |
`define USB_EP2_STS_TX_ERR_B 20 |
`define USB_EP2_STS_TX_ERR_T 20 |
`define USB_EP2_STS_TX_ERR_W 1 |
`define USB_EP2_STS_TX_ERR_R 20:20 |
|
`define USB_EP2_STS_TX_BUSY 19 |
`define USB_EP2_STS_TX_BUSY_DEFAULT 0 |
`define USB_EP2_STS_TX_BUSY_B 19 |
`define USB_EP2_STS_TX_BUSY_T 19 |
`define USB_EP2_STS_TX_BUSY_W 1 |
`define USB_EP2_STS_TX_BUSY_R 19:19 |
|
`define USB_EP2_STS_RX_ERR 18 |
`define USB_EP2_STS_RX_ERR_DEFAULT 0 |
`define USB_EP2_STS_RX_ERR_B 18 |
`define USB_EP2_STS_RX_ERR_T 18 |
`define USB_EP2_STS_RX_ERR_W 1 |
`define USB_EP2_STS_RX_ERR_R 18:18 |
|
`define USB_EP2_STS_RX_SETUP 17 |
`define USB_EP2_STS_RX_SETUP_DEFAULT 0 |
`define USB_EP2_STS_RX_SETUP_B 17 |
`define USB_EP2_STS_RX_SETUP_T 17 |
`define USB_EP2_STS_RX_SETUP_W 1 |
`define USB_EP2_STS_RX_SETUP_R 17:17 |
|
`define USB_EP2_STS_RX_READY 16 |
`define USB_EP2_STS_RX_READY_DEFAULT 0 |
`define USB_EP2_STS_RX_READY_B 16 |
`define USB_EP2_STS_RX_READY_T 16 |
`define USB_EP2_STS_RX_READY_W 1 |
`define USB_EP2_STS_RX_READY_R 16:16 |
|
`define USB_EP2_STS_RX_COUNT_DEFAULT 0 |
`define USB_EP2_STS_RX_COUNT_B 0 |
`define USB_EP2_STS_RX_COUNT_T 10 |
`define USB_EP2_STS_RX_COUNT_W 11 |
`define USB_EP2_STS_RX_COUNT_R 10:0 |
|
`define USB_EP2_DATA 8'h44 |
|
`define USB_EP2_DATA_DATA_DEFAULT 0 |
`define USB_EP2_DATA_DATA_B 0 |
`define USB_EP2_DATA_DATA_T 7 |
`define USB_EP2_DATA_DATA_W 8 |
`define USB_EP2_DATA_DATA_R 7:0 |
|
`define USB_EP3_CFG 8'h48 |
|
`define USB_EP3_CFG_INT_RX 3 |
`define USB_EP3_CFG_INT_RX_DEFAULT 0 |
`define USB_EP3_CFG_INT_RX_B 3 |
`define USB_EP3_CFG_INT_RX_T 3 |
`define USB_EP3_CFG_INT_RX_W 1 |
`define USB_EP3_CFG_INT_RX_R 3:3 |
|
`define USB_EP3_CFG_INT_TX 2 |
`define USB_EP3_CFG_INT_TX_DEFAULT 0 |
`define USB_EP3_CFG_INT_TX_B 2 |
`define USB_EP3_CFG_INT_TX_T 2 |
`define USB_EP3_CFG_INT_TX_W 1 |
`define USB_EP3_CFG_INT_TX_R 2:2 |
|
`define USB_EP3_CFG_STALL_EP 1 |
`define USB_EP3_CFG_STALL_EP_DEFAULT 0 |
`define USB_EP3_CFG_STALL_EP_B 1 |
`define USB_EP3_CFG_STALL_EP_T 1 |
`define USB_EP3_CFG_STALL_EP_W 1 |
`define USB_EP3_CFG_STALL_EP_R 1:1 |
|
`define USB_EP3_CFG_ISO 0 |
`define USB_EP3_CFG_ISO_DEFAULT 0 |
`define USB_EP3_CFG_ISO_B 0 |
`define USB_EP3_CFG_ISO_T 0 |
`define USB_EP3_CFG_ISO_W 1 |
`define USB_EP3_CFG_ISO_R 0:0 |
|
`define USB_EP3_TX_CTRL 8'h4c |
|
`define USB_EP3_TX_CTRL_TX_FLUSH 17 |
`define USB_EP3_TX_CTRL_TX_FLUSH_DEFAULT 0 |
`define USB_EP3_TX_CTRL_TX_FLUSH_B 17 |
`define USB_EP3_TX_CTRL_TX_FLUSH_T 17 |
`define USB_EP3_TX_CTRL_TX_FLUSH_W 1 |
`define USB_EP3_TX_CTRL_TX_FLUSH_R 17:17 |
|
`define USB_EP3_TX_CTRL_TX_START 16 |
`define USB_EP3_TX_CTRL_TX_START_DEFAULT 0 |
`define USB_EP3_TX_CTRL_TX_START_B 16 |
`define USB_EP3_TX_CTRL_TX_START_T 16 |
`define USB_EP3_TX_CTRL_TX_START_W 1 |
`define USB_EP3_TX_CTRL_TX_START_R 16:16 |
|
`define USB_EP3_TX_CTRL_TX_LEN_DEFAULT 0 |
`define USB_EP3_TX_CTRL_TX_LEN_B 0 |
`define USB_EP3_TX_CTRL_TX_LEN_T 10 |
`define USB_EP3_TX_CTRL_TX_LEN_W 11 |
`define USB_EP3_TX_CTRL_TX_LEN_R 10:0 |
|
`define USB_EP3_RX_CTRL 8'h50 |
|
`define USB_EP3_RX_CTRL_RX_FLUSH 1 |
`define USB_EP3_RX_CTRL_RX_FLUSH_DEFAULT 0 |
`define USB_EP3_RX_CTRL_RX_FLUSH_B 1 |
`define USB_EP3_RX_CTRL_RX_FLUSH_T 1 |
`define USB_EP3_RX_CTRL_RX_FLUSH_W 1 |
`define USB_EP3_RX_CTRL_RX_FLUSH_R 1:1 |
|
`define USB_EP3_RX_CTRL_RX_ACCEPT 0 |
`define USB_EP3_RX_CTRL_RX_ACCEPT_DEFAULT 0 |
`define USB_EP3_RX_CTRL_RX_ACCEPT_B 0 |
`define USB_EP3_RX_CTRL_RX_ACCEPT_T 0 |
`define USB_EP3_RX_CTRL_RX_ACCEPT_W 1 |
`define USB_EP3_RX_CTRL_RX_ACCEPT_R 0:0 |
|
`define USB_EP3_STS 8'h54 |
|
`define USB_EP3_STS_TX_ERR 20 |
`define USB_EP3_STS_TX_ERR_DEFAULT 0 |
`define USB_EP3_STS_TX_ERR_B 20 |
`define USB_EP3_STS_TX_ERR_T 20 |
`define USB_EP3_STS_TX_ERR_W 1 |
`define USB_EP3_STS_TX_ERR_R 20:20 |
|
`define USB_EP3_STS_TX_BUSY 19 |
`define USB_EP3_STS_TX_BUSY_DEFAULT 0 |
`define USB_EP3_STS_TX_BUSY_B 19 |
`define USB_EP3_STS_TX_BUSY_T 19 |
`define USB_EP3_STS_TX_BUSY_W 1 |
`define USB_EP3_STS_TX_BUSY_R 19:19 |
|
`define USB_EP3_STS_RX_ERR 18 |
`define USB_EP3_STS_RX_ERR_DEFAULT 0 |
`define USB_EP3_STS_RX_ERR_B 18 |
`define USB_EP3_STS_RX_ERR_T 18 |
`define USB_EP3_STS_RX_ERR_W 1 |
`define USB_EP3_STS_RX_ERR_R 18:18 |
|
`define USB_EP3_STS_RX_SETUP 17 |
`define USB_EP3_STS_RX_SETUP_DEFAULT 0 |
`define USB_EP3_STS_RX_SETUP_B 17 |
`define USB_EP3_STS_RX_SETUP_T 17 |
`define USB_EP3_STS_RX_SETUP_W 1 |
`define USB_EP3_STS_RX_SETUP_R 17:17 |
|
`define USB_EP3_STS_RX_READY 16 |
`define USB_EP3_STS_RX_READY_DEFAULT 0 |
`define USB_EP3_STS_RX_READY_B 16 |
`define USB_EP3_STS_RX_READY_T 16 |
`define USB_EP3_STS_RX_READY_W 1 |
`define USB_EP3_STS_RX_READY_R 16:16 |
|
`define USB_EP3_STS_RX_COUNT_DEFAULT 0 |
`define USB_EP3_STS_RX_COUNT_B 0 |
`define USB_EP3_STS_RX_COUNT_T 10 |
`define USB_EP3_STS_RX_COUNT_W 11 |
`define USB_EP3_STS_RX_COUNT_R 10:0 |
|
`define USB_EP3_DATA 8'h58 |
|
`define USB_EP3_DATA_DATA_DEFAULT 0 |
`define USB_EP3_DATA_DATA_B 0 |
`define USB_EP3_DATA_DATA_T 7 |
`define USB_EP3_DATA_DATA_W 8 |
`define USB_EP3_DATA_DATA_R 7:0 |
|
/usb_device_core/trunk/src_v/usbf_fifo.v
0,0 → 1,126
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
|
module usbf_fifo |
( |
// Inputs |
input clk_i |
,input rst_i |
,input [ 7:0] data_i |
,input push_i |
,input pop_i |
,input flush_i |
|
// Outputs |
,output full_o |
,output empty_o |
,output [ 7:0] data_o |
); |
|
|
|
parameter WIDTH = 8; |
parameter DEPTH = 4; |
parameter ADDR_W = 2; |
|
//----------------------------------------------------------------- |
// Local Params |
//----------------------------------------------------------------- |
localparam COUNT_W = ADDR_W + 1; |
|
//----------------------------------------------------------------- |
// Registers |
//----------------------------------------------------------------- |
reg [WIDTH-1:0] ram [DEPTH-1:0]; |
reg [ADDR_W-1:0] rd_ptr; |
reg [ADDR_W-1:0] wr_ptr; |
reg [COUNT_W-1:0] count; |
|
//----------------------------------------------------------------- |
// Sequential |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
begin |
count <= {(COUNT_W) {1'b0}}; |
rd_ptr <= {(ADDR_W) {1'b0}}; |
wr_ptr <= {(ADDR_W) {1'b0}}; |
end |
else |
begin |
|
if (flush_i) |
begin |
count <= {(COUNT_W) {1'b0}}; |
rd_ptr <= {(ADDR_W) {1'b0}}; |
wr_ptr <= {(ADDR_W) {1'b0}}; |
end |
|
// Push |
if (push_i & ~full_o) |
begin |
ram[wr_ptr] <= data_i; |
wr_ptr <= wr_ptr + 1; |
end |
|
// Pop |
if (pop_i & ~empty_o) |
begin |
rd_ptr <= rd_ptr + 1; |
end |
|
// Count up |
if ((push_i & ~full_o) & ~(pop_i & ~empty_o)) |
begin |
count <= count + 1; |
end |
// Count down |
else if (~(push_i & ~full_o) & (pop_i & ~empty_o)) |
begin |
count <= count - 1; |
end |
end |
|
//------------------------------------------------------------------- |
// Combinatorial |
//------------------------------------------------------------------- |
/* verilator lint_off WIDTH */ |
assign full_o = (count == DEPTH); |
assign empty_o = (count == 0); |
/* verilator lint_on WIDTH */ |
|
assign data_o = ram[rd_ptr]; |
|
|
endmodule |
/usb_device_core/trunk/src_v/usbf_sie_ep.v
0,0 → 1,193
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
|
module usbf_sie_ep |
( |
// Inputs |
input clk_i |
,input rst_i |
,input rx_setup_i |
,input rx_valid_i |
,input rx_strb_i |
,input [ 7:0] rx_data_i |
,input rx_last_i |
,input rx_crc_err_i |
,input rx_full_i |
,input rx_ack_i |
,input [ 7:0] tx_data_i |
,input tx_empty_i |
,input tx_flush_i |
,input [ 10:0] tx_length_i |
,input tx_start_i |
,input tx_data_accept_i |
|
// Outputs |
,output rx_space_o |
,output rx_push_o |
,output [ 7:0] rx_data_o |
,output [ 10:0] rx_length_o |
,output rx_ready_o |
,output rx_err_o |
,output rx_setup_o |
,output tx_pop_o |
,output tx_busy_o |
,output tx_err_o |
,output tx_ready_o |
,output tx_data_valid_o |
,output tx_data_strb_o |
,output [ 7:0] tx_data_o |
,output tx_data_last_o |
); |
|
|
|
//----------------------------------------------------------------- |
// Rx |
//----------------------------------------------------------------- |
reg rx_ready_q; |
reg rx_err_q; |
reg [10:0] rx_len_q; |
reg rx_setup_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rx_ready_q <= 1'b0; |
else if (rx_ack_i) |
rx_ready_q <= 1'b0; |
else if (rx_valid_i && rx_last_i) |
rx_ready_q <= 1'b1; |
|
assign rx_space_o = !rx_ready_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rx_len_q <= 11'b0; |
else if (rx_ack_i) |
rx_len_q <= 11'b0; |
else if (rx_valid_i && rx_strb_i) |
rx_len_q <= rx_len_q + 11'd1; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rx_err_q <= 1'b0; |
else if (rx_ack_i) |
rx_err_q <= 1'b0; |
else if (rx_valid_i && rx_last_i && rx_crc_err_i) |
rx_err_q <= 1'b1; |
else if (rx_full_i && rx_push_o) |
rx_err_q <= 1'b1; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rx_setup_q <= 1'b0; |
else if (rx_ack_i) |
rx_setup_q <= 1'b0; |
else if (rx_setup_i) |
rx_setup_q <= 1'b1; |
|
assign rx_length_o = rx_len_q; |
assign rx_ready_o = rx_ready_q; |
assign rx_err_o = rx_err_q; |
assign rx_setup_o = rx_setup_q; |
|
assign rx_push_o = rx_valid_i & rx_strb_i; |
assign rx_data_o = rx_data_i; |
|
//----------------------------------------------------------------- |
// Tx |
//----------------------------------------------------------------- |
reg tx_active_q; |
reg tx_err_q; |
reg tx_zlp_q; |
reg [10:0] tx_len_q; |
|
// Tx active |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
tx_active_q <= 1'b0; |
else if (tx_flush_i) |
tx_active_q <= 1'b0; |
else if (tx_start_i) |
tx_active_q <= 1'b1; |
else if (tx_data_valid_o && tx_data_last_o && tx_data_accept_i) |
tx_active_q <= 1'b0; |
|
assign tx_ready_o = tx_active_q; |
|
// Tx zero length packet |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
tx_zlp_q <= 1'b0; |
else if (tx_flush_i) |
tx_zlp_q <= 1'b0; |
else if (tx_start_i) |
tx_zlp_q <= (tx_length_i == 11'b0); |
|
// Tx length |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
tx_len_q <= 11'b0; |
else if (tx_flush_i) |
tx_len_q <= 11'b0; |
else if (tx_start_i) |
tx_len_q <= tx_length_i; |
else if (tx_data_valid_o && tx_data_accept_i && !tx_zlp_q) |
tx_len_q <= tx_len_q - 11'd1; |
|
// Tx SIE Interface |
assign tx_data_valid_o = tx_active_q; |
assign tx_data_strb_o = !tx_zlp_q; |
assign tx_data_last_o = tx_zlp_q || (tx_len_q == 11'd1); |
assign tx_data_o = tx_data_i; |
|
// Error: Buffer underrun |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
tx_err_q <= 1'b0; |
else if (tx_flush_i) |
tx_err_q <= 1'b0; |
else if (tx_start_i) |
tx_err_q <= 1'b0; |
else if (!tx_zlp_q && tx_empty_i && tx_data_valid_o) |
tx_err_q <= 1'b1; |
|
// Tx Register Interface |
assign tx_err_o = tx_err_q; |
assign tx_busy_o = tx_active_q; |
|
// Tx FIFO Interface |
assign tx_pop_o = tx_data_accept_i & tx_active_q; |
|
|
endmodule |
/usb_device_core/trunk/src_v/usbf_sie_rx.v
0,0 → 1,463
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
|
module usbf_sie_rx |
( |
// Inputs |
input clk_i |
,input rst_i |
,input enable_i |
,input [ 7:0] utmi_data_i |
,input utmi_rxvalid_i |
,input utmi_rxactive_i |
,input [ 6:0] current_addr_i |
|
// Outputs |
,output [ 7:0] pid_o |
,output frame_valid_o |
,output [ 10:0] frame_number_o |
,output token_valid_o |
,output [ 6:0] token_addr_o |
,output [ 3:0] token_ep_o |
,output token_crc_err_o |
,output handshake_valid_o |
,output data_valid_o |
,output data_strb_o |
,output [ 7:0] data_o |
,output data_last_o |
,output data_crc_err_o |
,output data_complete_o |
); |
|
|
|
//----------------------------------------------------------------- |
// Defines: |
//----------------------------------------------------------------- |
`include "usbf_defs.v" |
|
localparam STATE_W = 4; |
localparam STATE_RX_IDLE = 4'd0; |
localparam STATE_RX_TOKEN2 = 4'd1; |
localparam STATE_RX_TOKEN3 = 4'd2; |
localparam STATE_RX_TOKEN_COMPLETE = 4'd3; |
localparam STATE_RX_SOF2 = 4'd4; |
localparam STATE_RX_SOF3 = 4'd5; |
localparam STATE_RX_DATA = 4'd6; |
localparam STATE_RX_DATA_COMPLETE = 4'd7; |
localparam STATE_RX_IGNORED = 4'd8; |
reg [STATE_W-1:0] state_q; |
|
//----------------------------------------------------------------- |
// Wire / Regs |
//----------------------------------------------------------------- |
`define USB_FRAME_W 11 |
reg [`USB_FRAME_W-1:0] frame_num_q; |
|
`define USB_DEV_W 7 |
reg [`USB_DEV_W-1:0] token_dev_q; |
|
`define USB_EP_W 4 |
reg [`USB_EP_W-1:0] token_ep_q; |
|
`define USB_PID_W 8 |
reg [`USB_PID_W-1:0] token_pid_q; |
|
//----------------------------------------------------------------- |
// Data delay (to strip the CRC16 trailing bytes) |
//----------------------------------------------------------------- |
reg [31:0] data_buffer_q; |
reg [3:0] data_valid_q; |
reg [3:0] rx_active_q; |
|
wire shift_en_w = (utmi_rxvalid_i & utmi_rxactive_i) || !utmi_rxactive_i; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
data_buffer_q <= 32'b0; |
else if (shift_en_w) |
data_buffer_q <= {utmi_data_i, data_buffer_q[31:8]}; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
data_valid_q <= 4'b0; |
else if (shift_en_w) |
data_valid_q <= {(utmi_rxvalid_i & utmi_rxactive_i), data_valid_q[3:1]}; |
else |
data_valid_q <= {data_valid_q[3:1], 1'b0}; |
|
reg [1:0] data_crc_q; |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
data_crc_q <= 2'b0; |
else if (shift_en_w) |
data_crc_q <= {!utmi_rxactive_i, data_crc_q[1]}; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
rx_active_q <= 4'b0; |
else |
rx_active_q <= {utmi_rxactive_i, rx_active_q[3:1]}; |
|
wire [7:0] data_w = data_buffer_q[7:0]; |
wire data_ready_w = data_valid_q[0]; |
wire crc_byte_w = data_crc_q[0]; |
wire rx_active_w = rx_active_q[0]; |
|
wire address_match_w = (token_dev_q == current_addr_i); |
|
//----------------------------------------------------------------- |
// Next state |
//----------------------------------------------------------------- |
reg [STATE_W-1:0] next_state_r; |
|
always @ * |
begin |
next_state_r = state_q; |
|
case (state_q) |
|
//----------------------------------------- |
// IDLE |
//----------------------------------------- |
STATE_RX_IDLE : |
begin |
if (data_ready_w) |
begin |
// Decode PID |
case (data_w) |
|
`PID_OUT, `PID_IN, `PID_SETUP, `PID_PING: |
next_state_r = STATE_RX_TOKEN2; |
|
`PID_SOF: |
next_state_r = STATE_RX_SOF2; |
|
`PID_DATA0, `PID_DATA1, `PID_DATA2, `PID_MDATA: |
begin |
next_state_r = STATE_RX_DATA; |
end |
|
`PID_ACK, `PID_NAK, `PID_STALL, `PID_NYET: |
next_state_r = STATE_RX_IDLE; |
|
default : // SPLIT / ERR |
next_state_r = STATE_RX_IGNORED; |
endcase |
end |
end |
|
//----------------------------------------- |
// RX_IGNORED: Unknown / unsupported |
//----------------------------------------- |
STATE_RX_IGNORED : |
begin |
// Wait until the end of the packet |
if (!rx_active_w) |
next_state_r = STATE_RX_IDLE; |
end |
|
//----------------------------------------- |
// SOF (BYTE 2) |
//----------------------------------------- |
STATE_RX_SOF2 : |
begin |
if (data_ready_w) |
next_state_r = STATE_RX_SOF3; |
else if (!rx_active_w) |
next_state_r = STATE_RX_IDLE; |
end |
|
//----------------------------------------- |
// SOF (BYTE 3) |
//----------------------------------------- |
STATE_RX_SOF3 : |
begin |
if (data_ready_w || !rx_active_w) |
next_state_r = STATE_RX_IDLE; |
end |
|
//----------------------------------------- |
// TOKEN (IN/OUT/SETUP) (Address/Endpoint) |
//----------------------------------------- |
STATE_RX_TOKEN2 : |
begin |
if (data_ready_w) |
next_state_r = STATE_RX_TOKEN3; |
else if (!rx_active_w) |
next_state_r = STATE_RX_IDLE; |
end |
|
//----------------------------------------- |
// TOKEN (IN/OUT/SETUP) (Endpoint/CRC) |
//----------------------------------------- |
STATE_RX_TOKEN3 : |
begin |
if (data_ready_w) |
next_state_r = STATE_RX_TOKEN_COMPLETE; |
else if (!rx_active_w) |
next_state_r = STATE_RX_IDLE; |
end |
|
//----------------------------------------- |
// RX_TOKEN_COMPLETE |
//----------------------------------------- |
STATE_RX_TOKEN_COMPLETE : |
begin |
next_state_r = STATE_RX_IDLE; |
end |
|
//----------------------------------------- |
// RX_DATA |
//----------------------------------------- |
STATE_RX_DATA : |
begin |
// Receive complete |
if (crc_byte_w) |
next_state_r = STATE_RX_DATA_COMPLETE; |
end |
|
//----------------------------------------- |
// RX_DATA_COMPLETE |
//----------------------------------------- |
STATE_RX_DATA_COMPLETE : |
begin |
if (!rx_active_w) |
next_state_r = STATE_RX_IDLE; |
end |
|
default : |
; |
|
endcase |
end |
|
// Update state |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
state_q <= STATE_RX_IDLE; |
else if (!enable_i) |
state_q <= STATE_RX_IDLE; |
else |
state_q <= next_state_r; |
|
//----------------------------------------------------------------- |
// Handshake: |
//----------------------------------------------------------------- |
reg handshake_valid_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
handshake_valid_q <= 1'b0; |
else if (state_q == STATE_RX_IDLE && data_ready_w) |
begin |
case (data_w) |
`PID_ACK, `PID_NAK, `PID_STALL, `PID_NYET: |
handshake_valid_q <= address_match_w; |
default : |
handshake_valid_q <= 1'b0; |
endcase |
end |
else |
handshake_valid_q <= 1'b0; |
|
assign handshake_valid_o = handshake_valid_q; |
|
//----------------------------------------------------------------- |
// SOF: Frame number |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
frame_num_q <= `USB_FRAME_W'b0; |
else if (state_q == STATE_RX_SOF2 && data_ready_w) |
frame_num_q <= {3'b0, data_w}; |
else if (state_q == STATE_RX_SOF3 && data_ready_w) |
frame_num_q <= {data_w[2:0], frame_num_q[7:0]}; |
else if (!enable_i) |
frame_num_q <= `USB_FRAME_W'b0; |
|
assign frame_number_o = frame_num_q; |
|
reg frame_valid_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
frame_valid_q <= 1'b0; |
else |
frame_valid_q <= (state_q == STATE_RX_SOF3 && data_ready_w); |
|
assign frame_valid_o = frame_valid_q; |
|
//----------------------------------------------------------------- |
// Token: PID |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
token_pid_q <= `USB_PID_W'b0; |
else if (state_q == STATE_RX_IDLE && data_ready_w) |
token_pid_q <= data_w; |
else if (!enable_i) |
token_pid_q <= `USB_PID_W'b0; |
|
assign pid_o = token_pid_q; |
|
reg token_valid_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
token_valid_q <= 1'b0; |
else |
token_valid_q <= (state_q == STATE_RX_TOKEN_COMPLETE) && address_match_w; |
|
assign token_valid_o = token_valid_q; |
|
//----------------------------------------------------------------- |
// Token: Device Address |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
token_dev_q <= `USB_DEV_W'b0; |
else if (state_q == STATE_RX_TOKEN2 && data_ready_w) |
token_dev_q <= data_w[6:0]; |
else if (!enable_i) |
token_dev_q <= `USB_DEV_W'b0; |
|
assign token_addr_o = token_dev_q; |
|
//----------------------------------------------------------------- |
// Token: Endpoint |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
token_ep_q <= `USB_EP_W'b0; |
else if (state_q == STATE_RX_TOKEN2 && data_ready_w) |
token_ep_q[0] <= data_w[7]; |
else if (state_q == STATE_RX_TOKEN3 && data_ready_w) |
token_ep_q[3:1] <= data_w[2:0]; |
else if (!enable_i) |
token_ep_q <= `USB_EP_W'b0; |
|
assign token_ep_o = token_ep_q; |
assign token_crc_err_o = 1'b0; |
|
wire [7:0] input_data_w = data_w; |
wire input_ready_w = state_q == STATE_RX_DATA && data_ready_w && !crc_byte_w; |
|
//----------------------------------------------------------------- |
// CRC16: Generate CRC16 on incoming data bytes |
//----------------------------------------------------------------- |
reg [15:0] crc_sum_q; |
wire [15:0] crc_out_w; |
reg crc_err_q; |
|
usbf_crc16 |
u_crc16 |
( |
.crc_in_i(crc_sum_q), |
.din_i(data_w), |
.crc_out_o(crc_out_w) |
); |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
crc_sum_q <= 16'hFFFF; |
else if (state_q == STATE_RX_IDLE) |
crc_sum_q <= 16'hFFFF; |
else if (data_ready_w) |
crc_sum_q <= crc_out_w; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
crc_err_q <= 1'b0; |
else if (state_q == STATE_RX_IDLE) |
crc_err_q <= 1'b0; |
else if (state_q == STATE_RX_DATA_COMPLETE && next_state_r == STATE_RX_IDLE) |
crc_err_q <= (crc_sum_q != 16'hB001); |
|
assign data_crc_err_o = crc_err_q; |
|
reg data_complete_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
data_complete_q <= 1'b0; |
else if (state_q == STATE_RX_DATA_COMPLETE && next_state_r == STATE_RX_IDLE) |
data_complete_q <= 1'b1; |
else |
data_complete_q <= 1'b0; |
|
assign data_complete_o = data_complete_q; |
|
reg data_zlp_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
data_zlp_q <= 1'b0; |
else if (state_q == STATE_RX_IDLE && next_state_r == STATE_RX_DATA) |
data_zlp_q <= 1'b1; |
else if (input_ready_w) |
data_zlp_q <= 1'b0; |
|
//----------------------------------------------------------------- |
// Data Output |
//----------------------------------------------------------------- |
reg valid_q; |
reg last_q; |
reg [7:0] data_q; |
reg mask_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
begin |
valid_q <= 1'b0; |
data_q <= 8'b0; |
mask_q <= 1'b0; |
last_q <= 1'b0; |
end |
else |
begin |
valid_q <= input_ready_w || ((state_q == STATE_RX_DATA) && crc_byte_w && data_zlp_q); |
data_q <= input_data_w; |
mask_q <= input_ready_w; |
last_q <= (state_q == STATE_RX_DATA) && crc_byte_w; |
end |
|
// Data |
assign data_valid_o = valid_q; |
assign data_strb_o = mask_q; |
assign data_o = data_q; |
assign data_last_o = last_q | crc_byte_w; |
|
|
endmodule |
/usb_device_core/trunk/src_v/usbf_sie_tx.v
0,0 → 1,350
//----------------------------------------------------------------- |
// USB Device Core |
// V1.0 |
// Ultra-Embedded.com |
// Copyright 2014-2019 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for |
// use in closed source commercial applications please contact me |
// for details. |
//----------------------------------------------------------------- |
// |
// This file is open source HDL; you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as |
// published by the Free Software Foundation; either version 2 of |
// the License, or (at your option) any later version. |
// |
// This file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this file; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Generated File |
//----------------------------------------------------------------- |
|
module usbf_sie_tx |
( |
// Inputs |
input clk_i |
,input rst_i |
,input enable_i |
,input chirp_i |
,input utmi_txready_i |
,input tx_valid_i |
,input [ 7:0] tx_pid_i |
,input data_valid_i |
,input data_strb_i |
,input [ 7:0] data_i |
,input data_last_i |
|
// Outputs |
,output [ 7:0] utmi_data_o |
,output utmi_txvalid_o |
,output tx_accept_o |
,output data_accept_o |
); |
|
|
|
//----------------------------------------------------------------- |
// Defines: |
//----------------------------------------------------------------- |
`include "usbf_defs.v" |
|
localparam STATE_W = 3; |
localparam STATE_TX_IDLE = 3'd0; |
localparam STATE_TX_PID = 3'd1; |
localparam STATE_TX_DATA = 3'd2; |
localparam STATE_TX_CRC1 = 3'd3; |
localparam STATE_TX_CRC2 = 3'd4; |
localparam STATE_TX_DONE = 3'd5; |
localparam STATE_TX_CHIRP = 3'd6; |
|
reg [STATE_W-1:0] state_q; |
reg [STATE_W-1:0] next_state_r; |
|
//----------------------------------------------------------------- |
// Wire / Regs |
//----------------------------------------------------------------- |
reg last_q; |
|
//----------------------------------------------------------------- |
// Request Type |
//----------------------------------------------------------------- |
reg data_pid_q; |
reg data_zlp_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
begin |
data_pid_q <= 1'b0; |
data_zlp_q <= 1'b0; |
end |
else if (!enable_i) |
begin |
data_pid_q <= 1'b0; |
data_zlp_q <= 1'b0; |
end |
else if (tx_valid_i && tx_accept_o) |
begin |
case (tx_pid_i) |
|
`PID_MDATA, `PID_DATA2, `PID_DATA0, `PID_DATA1: |
begin |
data_pid_q <= 1'b1; |
data_zlp_q <= data_valid_i && (data_strb_i == 1'b0) && data_last_i; |
end |
|
default : |
begin |
data_pid_q <= 1'b0; |
data_zlp_q <= 1'b0; |
end |
endcase |
end |
else if (next_state_r == STATE_TX_CRC1) |
begin |
data_pid_q <= 1'b0; |
data_zlp_q <= 1'b0; |
end |
|
assign tx_accept_o = (state_q == STATE_TX_IDLE); |
|
//----------------------------------------------------------------- |
// Next state |
//----------------------------------------------------------------- |
always @ * |
begin |
next_state_r = state_q; |
|
//----------------------------------------- |
// State Machine |
//----------------------------------------- |
case (state_q) |
|
//----------------------------------------- |
// IDLE |
//----------------------------------------- |
STATE_TX_IDLE : |
begin |
if (chirp_i) |
next_state_r = STATE_TX_CHIRP; |
else if (tx_valid_i) |
next_state_r = STATE_TX_PID; |
end |
|
//----------------------------------------- |
// TX_PID |
//----------------------------------------- |
STATE_TX_PID : |
begin |
// Data accepted |
if (utmi_txready_i) |
begin |
if (data_zlp_q) |
next_state_r = STATE_TX_CRC1; |
else if (data_pid_q) |
next_state_r = STATE_TX_DATA; |
else |
next_state_r = STATE_TX_DONE; |
end |
end |
|
//----------------------------------------- |
// TX_DATA |
//----------------------------------------- |
STATE_TX_DATA : |
begin |
// Data accepted |
if (utmi_txready_i) |
begin |
// Generate CRC16 at end of packet |
if (data_last_i) |
next_state_r = STATE_TX_CRC1; |
end |
end |
|
//----------------------------------------- |
// TX_CRC1 (first byte) |
//----------------------------------------- |
STATE_TX_CRC1 : |
begin |
// Data sent? |
if (utmi_txready_i) |
next_state_r = STATE_TX_CRC2; |
end |
|
//----------------------------------------- |
// TX_CRC (second byte) |
//----------------------------------------- |
STATE_TX_CRC2 : |
begin |
// Data sent? |
if (utmi_txready_i) |
next_state_r = STATE_TX_DONE; |
end |
|
//----------------------------------------- |
// TX_DONE |
//----------------------------------------- |
STATE_TX_DONE : |
begin |
// Data sent? |
if (!utmi_txvalid_o || utmi_txready_i) |
next_state_r = STATE_TX_IDLE; |
end |
|
//----------------------------------------- |
// TX_CHIRP |
//----------------------------------------- |
STATE_TX_CHIRP : |
begin |
if (!chirp_i) |
next_state_r = STATE_TX_IDLE; |
end |
|
default : |
; |
|
endcase |
|
// USB reset but not chirping... |
if (!enable_i && !chirp_i) |
next_state_r = STATE_TX_IDLE; |
end |
|
// Update state |
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
state_q <= STATE_TX_IDLE; |
else |
state_q <= next_state_r; |
|
//----------------------------------------------------------------- |
// Data Input |
//----------------------------------------------------------------- |
reg input_valid_r; |
reg [7:0] input_byte_r; |
reg input_last_r; |
always @ * |
begin |
input_valid_r = data_strb_i & data_pid_q; |
input_byte_r = data_i; |
input_last_r = data_last_i; |
end |
|
reg data_accept_r; |
always @ * |
begin |
if (state_q == STATE_TX_DATA) |
data_accept_r = utmi_txready_i; |
else if (state_q == STATE_TX_PID && data_zlp_q) |
data_accept_r = utmi_txready_i; |
else |
data_accept_r = 1'b0; |
end |
|
assign data_accept_o = data_accept_r; |
|
//----------------------------------------------------------------- |
// CRC16: Generate CRC16 on outgoing data |
//----------------------------------------------------------------- |
reg [15:0] crc_sum_q; |
wire [15:0] crc_out_w; |
reg crc_err_q; |
|
usbf_crc16 |
u_crc16 |
( |
.crc_in_i(crc_sum_q), |
.din_i(utmi_data_o), |
.crc_out_o(crc_out_w) |
); |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
crc_sum_q <= 16'hFFFF; |
else if (state_q == STATE_TX_IDLE) |
crc_sum_q <= 16'hFFFF; |
else if (state_q == STATE_TX_DATA && utmi_txvalid_o && utmi_txready_i) |
crc_sum_q <= crc_out_w; |
|
//----------------------------------------------------------------- |
// Output |
//----------------------------------------------------------------- |
reg valid_q; |
reg [7:0] data_q; |
|
always @ (posedge clk_i or posedge rst_i) |
if (rst_i) |
begin |
valid_q <= 1'b0; |
data_q <= 8'b0; |
last_q <= 1'b0; |
end |
else if (!enable_i) |
begin |
valid_q <= 1'b0; |
data_q <= 8'b0; |
last_q <= 1'b0; |
end |
else if (tx_valid_i && tx_accept_o) |
begin |
valid_q <= 1'b1; |
data_q <= tx_pid_i; |
last_q <= 1'b0; |
end |
else if (utmi_txready_i) |
begin |
valid_q <= 1'b0; |
data_q <= 8'b0; |
last_q <= 1'b0; |
end |
|
reg utmi_txvalid_r; |
reg [7:0] utmi_data_r; |
|
always @ * |
begin |
if (state_q == STATE_TX_CHIRP) |
begin |
utmi_txvalid_r = 1'b1; |
utmi_data_r = 8'b0; |
end |
else if (state_q == STATE_TX_CRC1) |
begin |
utmi_txvalid_r = 1'b1; |
utmi_data_r = crc_sum_q[7:0] ^ 8'hFF; |
end |
else if (state_q == STATE_TX_CRC2) |
begin |
utmi_txvalid_r = 1'b1; |
utmi_data_r = crc_sum_q[15:8] ^ 8'hFF; |
end |
else if (state_q == STATE_TX_DATA) |
begin |
utmi_txvalid_r = data_valid_i; |
utmi_data_r = data_i; |
end |
else |
begin |
utmi_txvalid_r = valid_q; |
utmi_data_r = data_q; |
end |
end |
|
assign utmi_txvalid_o = utmi_txvalid_r; |
assign utmi_data_o = utmi_data_r; |
|
|
endmodule |
/usb_device_core/trunk/sw/main.c
File deleted
/usb_device_core/trunk/sw/usb_defs.h
File deleted
/usb_device_core/trunk/sw/usb_hw.c
File deleted
/usb_device_core/trunk/sw/usb_hw.h
File deleted
/usb_device_core/trunk/sw/hardware.h
File deleted
/usb_device_core/trunk/sw/example.c
0,0 → 1,46
#include <stdint.h> |
#include <unistd.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include "timer.h" |
#include "usb_uart.h" |
#include "usb_cdc.h" |
#include "usb_device.h" |
#include "usbf_hw.h" |
|
//----------------------------------------------------------------- |
// Defines: |
//----------------------------------------------------------------- |
#define USB_DEV_BASE 0x80000000 |
|
//----------------------------------------------------------------- |
// main |
//----------------------------------------------------------------- |
int main(int argc, char *argv[]) |
{ |
printf("USB Device Test\n"); |
|
// USB init |
usbf_init(USB_DEV_BASE, 0, usb_cdc_process_request); |
usb_uart_init(); |
|
// Force detach |
usbhw_attach(0); |
timer_sleep(100); |
usbhw_attach(1); |
|
while (1) |
{ |
usbhw_service(); |
|
// Loopback |
if (usb_uart_haschar()) |
{ |
int ch = usb_uart_getchar(); |
printf("Received %c\n", ch); |
usb_uart_putchar(ch); |
} |
} |
|
return 0; |
} |
/usb_device_core/trunk/sw/timer.h
1,24 → 1,14
#ifndef __TIMER_H__ |
#define __TIMER_H__ |
|
#include "hardware.h" |
|
//----------------------------------------------------------------- |
// Defines: |
// Types |
//----------------------------------------------------------------- |
typedef unsigned long t_time; |
typedef unsigned long t_time; |
|
//----------------------------------------------------------------- |
// Prototypes: |
//----------------------------------------------------------------- |
static t_time timer_now(void) { return TIMER_HW_VAL; } |
static long timer_diff(t_time a, t_time b) { return (long)(a - b); } |
static void timer_sleep(int timeMs) |
{ |
t_time t = timer_now(); |
|
while (timer_diff(timer_now(), t) < timeMs) |
; |
} |
// TODO: Implementation specific millisecond timer... |
static t_time timer_now(void) { return 0; } |
static void timer_sleep(int timeMs) { } |
|
#endif |
/usb_device_core/trunk/sw/usb_cdc.c
1,44 → 1,39
//----------------------------------------------------------------- |
// USB Device Core |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// USB CDC Device SW |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// |
// Email: admin@ultra-embedded.com |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
// License: GPL |
// If you would like a version with a more permissive license for use in |
// closed source commercial applications please contact me for details. |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2013 - 2014 Ultra-Embedded.com |
// This file is part of USB CDC Device SW. |
// |
// 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. |
// USB CDC Device SW is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// USB CDC Device SW is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
// You should have received a copy of the GNU General Public License |
// along with USB CDC Device SW; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
#include <string.h> |
#include <stdlib.h> |
#include "usb_defs.h" |
#include "usbf_defs.h" |
#include "usb_cdc.h" |
#include "usb_log.h" |
#include "usb_device.h" |
#include "usbf_hw.h" |
|
//----------------------------------------------------------------- |
// Locals: |
60,11 → 55,11
//----------------------------------------------------------------- |
// cdc_get_line_coding: |
//----------------------------------------------------------------- |
static void cdc_get_line_coding(void) |
static void cdc_get_line_coding(unsigned short wLength) |
{ |
log_printf(USBLOG_CDC_INFO, "CDC: Get Line Coding\n"); |
|
usb_control_send( _line_coding, sizeof(_line_coding) ); |
usb_control_send( _line_coding, sizeof(_line_coding), wLength ); |
} |
//----------------------------------------------------------------- |
// cdc_set_control_line_state: |
92,7 → 87,7
//----------------------------------------------------------------- |
// cdc_get_encapsulated_response: |
//----------------------------------------------------------------- |
static void cdc_get_encapsulated_response (void) |
static void cdc_get_encapsulated_response (unsigned short wLength) |
{ |
log_printf(USBLOG_CDC_INFO, "CDC: Get encap\n"); |
|
99,9 → 94,9
usbhw_control_endpoint_stall(); |
} |
//----------------------------------------------------------------- |
// cdc_process_request: |
// usb_cdc_process_request: |
//----------------------------------------------------------------- |
void cdc_process_request(unsigned char req, unsigned short wValue, unsigned short WIndex, unsigned char *data, unsigned short wLength) |
void usb_cdc_process_request(unsigned char req, unsigned short wValue, unsigned short WIndex, unsigned char *data, unsigned short wLength) |
{ |
switch ( req ) |
{ |
111,7 → 106,7
break; |
case CDC_GET_ENCAPSULATED_RESPONSE: |
log_printf(USBLOG_CDC_INFO, "CDC: Get encap\n"); |
cdc_get_encapsulated_response(); |
cdc_get_encapsulated_response(wLength); |
break; |
case CDC_SET_LINE_CODING: |
log_printf(USBLOG_CDC_INFO, "CDC: Set line coding\n"); |
119,7 → 114,7
break; |
case CDC_GET_LINE_CODING: |
log_printf(USBLOG_CDC_INFO, "CDC: Get line coding\n"); |
cdc_get_line_coding(); |
cdc_get_line_coding(wLength); |
break; |
case CDC_SET_CONTROL_LINE_STATE: |
log_printf(USBLOG_CDC_INFO, "CDC: Set line state\n"); |
136,9 → 131,9
} |
} |
//----------------------------------------------------------------- |
// cdc_init: |
// usb_cdc_init: |
//----------------------------------------------------------------- |
void cdc_init(void) |
void usb_cdc_init(void) |
{ |
_line_coding[0] = 0x00; // UART baud rate (32-bit word, LSB first) |
_line_coding[1] = 0xC2; |
/usb_device_core/trunk/sw/usb_cdc.h
18,7 → 18,15
//----------------------------------------------------------------- |
// Prototypes: |
//----------------------------------------------------------------- |
void cdc_init( void ); |
void cdc_process_request(unsigned char req, unsigned short wValue, unsigned short WIndex, unsigned char *data, unsigned short wLength); |
#ifdef __cplusplus |
extern "C" { |
#endif |
|
void usb_cdc_init( void ); |
void usb_cdc_process_request(unsigned char req, unsigned short wValue, unsigned short WIndex, unsigned char *data, unsigned short wLength); |
|
#ifdef __cplusplus |
} |
#endif |
|
#endif |
/usb_device_core/trunk/sw/usb_desc.h
4,7 → 4,15
//----------------------------------------------------------------- |
// Prototypes |
//----------------------------------------------------------------- |
#ifdef __cplusplus |
extern "C" { |
#endif |
|
unsigned char *usb_get_descriptor( unsigned char bDescriptorType, unsigned char bDescriptorIndex, unsigned short wLength, unsigned char *pSize ); |
int usb_is_bus_powered(void); |
|
#ifdef __cplusplus |
} |
#endif |
|
#endif |
/usb_device_core/trunk/sw/usb_desc_cdc.c
1,41 → 1,35
//----------------------------------------------------------------- |
// USB Device Core |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// USB CDC Device SW |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// |
// Email: admin@ultra-embedded.com |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
// License: GPL |
// If you would like a version with a more permissive license for use in |
// closed source commercial applications please contact me for details. |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2013 - 2014 Ultra-Embedded.com |
// This file is part of USB CDC Device SW. |
// |
// 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. |
// USB CDC Device SW is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// USB CDC Device SW is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
// You should have received a copy of the GNU General Public License |
// along with USB CDC Device SW; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
#include <string.h> |
#include <stdlib.h> |
#include "usb_defs.h" |
#include "usbf_defs.h" |
#include "usb_desc.h" |
#include "usb_log.h" |
|
43,7 → 37,7
// PID/VID: |
//----------------------------------------------------------------- |
#ifndef USB_DEV_VID |
#define USB_DEV_VID 0x1234 |
#define USB_DEV_VID 0x9234 |
#endif |
#ifndef USB_DEV_PID |
#define USB_DEV_PID 0x5678 |
56,8 → 50,13
|
// Descriptor defs |
#define SIZE_OF_DEVICE_DESCR 18 |
#define EP0_MAX_PACKET_SIZE 8 |
|
#ifdef USB_SPEED_HS |
#define EP0_MAX_PACKET_SIZE 64 |
#else |
#define EP0_MAX_PACKET_SIZE 8 |
#endif |
|
// Configuration descriptor |
#define NB_INTERFACE 2 |
#define CONF_NB 1 |
77,7 → 76,11
// Endpoint 3 descriptor (INTR-IN) |
#define ENDPOINT_ID_3 0x83 |
#define EP_ATTRIBUTES_3 0x03 |
#define EP_SIZE_3 64 |
#ifdef USB_SPEED_HS |
#define EP_SIZE_3 64 // TODO: Should be 512 for HS??? |
#else |
#define EP_SIZE_3 64 |
#endif |
#define EP_INTERVAL_3 2 |
|
// Interface 1 descriptor |
92,13 → 95,21
// Endpoint 1 descriptor |
#define ENDPOINT_ID_1 0x01 |
#define EP_ATTRIBUTES_1 0x02 |
#define EP_SIZE_1 64 |
#ifdef USB_SPEED_HS |
#define EP_SIZE_1 512 |
#else |
#define EP_SIZE_1 64 |
#endif |
#define EP_INTERVAL_1 0x00 |
|
// Endpoint 2 descriptor |
#define ENDPOINT_ID_2 0x82 |
#define EP_ATTRIBUTES_2 0x02 |
#define EP_SIZE_2 64 |
#ifdef USB_SPEED_HS |
#define EP_SIZE_2 512 |
#else |
#define EP_SIZE_2 64 |
#endif |
#define EP_INTERVAL_2 0x00 |
|
// String Descriptors |
/usb_device_core/trunk/sw/usb_device.c
1,45 → 1,38
//----------------------------------------------------------------- |
// USB Device Core |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// USB CDC Device SW |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// |
// Email: admin@ultra-embedded.com |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
// License: GPL |
// If you would like a version with a more permissive license for use in |
// closed source commercial applications please contact me for details. |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2013 - 2014 Ultra-Embedded.com |
// This file is part of USB CDC Device SW. |
// |
// 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. |
// USB CDC Device SW is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// USB CDC Device SW is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
// You should have received a copy of the GNU General Public License |
// along with USB CDC Device SW; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
#include <string.h> |
#include "usb_device.h" |
#include "usb_desc.h" |
#include "usb_log.h" |
#include "usb_defs.h" |
#include "usb_hw.h" |
#include "timer.h" |
#include "usbf_defs.h" |
#include "usbf_hw.h" |
|
//----------------------------------------------------------------- |
// Defines: |
106,17 → 99,17
if (_remote_wake_enabled) |
data[0] |= (1 << 1); |
|
usb_control_send( data, 2 ); |
usb_control_send( data, 2, request->wLength ); |
} |
else if ( bRecipient == USB_RECIPIENT_INTERFACE ) |
{ |
usb_control_send( data, 2 ); |
usb_control_send( data, 2, request->wLength ); |
} |
else if ( bRecipient == USB_RECIPIENT_ENDPOINT ) |
{ |
if (usbhw_is_endpoint_stalled( request->wIndex & ENDPOINT_ADDR_MASK)) |
data[0] = 1; |
usb_control_send( data, 2 ); |
usb_control_send( data, 2, request->wLength ); |
} |
else |
usbhw_control_endpoint_stall(); |
215,7 → 208,7
desc_ptr = usb_get_descriptor(bDescriptorType, bDescriptorIndex, wLength, &bCount); |
|
if (desc_ptr) |
usb_control_send(desc_ptr, bCount); |
usb_control_send(desc_ptr, bCount, request->wLength); |
else |
usbhw_control_endpoint_stall(); |
} |
228,7 → 221,7
|
log_printf(USBLOG_INFO, "USB: Get configuration %x\n", conf); |
|
usb_control_send( &conf, 1 ); |
usb_control_send( &conf, 1, request->wLength ); |
} |
//----------------------------------------------------------------- |
// set_configuration: |
338,6 → 331,7
unsigned char setup_pkt[EP0_MAX_PACKET_SIZE]; |
|
usbhw_get_rx_data(ENDPOINT_CONTROL, setup_pkt, EP0_MAX_PACKET_SIZE); |
usbhw_clear_rx_ready(ENDPOINT_CONTROL); |
|
#if (LOG_LEVEL >= USBLOG_SETUP_DATA) |
{ |
444,6 → 438,7
else |
{ |
usbhw_get_rx_data(ENDPOINT_CONTROL, &_ctrl_xfer.data_buffer[_ctrl_xfer.data_idx], received); |
usbhw_clear_rx_ready(ENDPOINT_CONTROL); |
_ctrl_xfer.data_idx += received; |
|
log_printf(USBLOG_SETUP_OUT, "USB: OUT packet re-assembled %d\n", _ctrl_xfer.data_idx); |
472,7 → 467,7
//----------------------------------------------------------------- |
// usb_control_send: Perform a transfer via IN |
//----------------------------------------------------------------- |
int usb_control_send(unsigned char *buf, int size) |
int usb_control_send(unsigned char *buf, int size, int requested_size) |
{ |
t_time tS; |
int send; |
490,6 → 485,10
|
log_printf(USBLOG_SETUP_IN_DBG, " Remain %d, Send %d\n", remain, send); |
|
// Do not send ZLP if requested size was size transferred |
if (remain == 0 && size == requested_size) |
break; |
|
usbhw_load_tx_buffer(ENDPOINT_CONTROL, buf, (unsigned char) send); |
|
buf += send; |
497,15 → 496,22
|
log_printf(USBLOG_SETUP_IN_DBG, " Sent %d, Remain %d\n", send, (size - count)); |
|
tS = timer_now(); |
tS = usbhw_timer_now(); |
while ( !usbhw_has_tx_space( ENDPOINT_CONTROL ) ) |
{ |
if (timer_diff(timer_now(), tS) > USB_CTRL_TX_TIMEOUT) |
if (usbhw_timer_diff(usbhw_timer_now(), tS) > USB_CTRL_TX_TIMEOUT) |
{ |
log_printf(USBLOG_ERR, "USB: Timeout sending IN data\n"); |
err = 1; |
break; |
} |
} |
|
// Give up on early OUT (STATUS stage) |
if (usbhw_is_rx_ready(ENDPOINT_CONTROL)) |
{ |
log_printf(USBLOG_ERR, "USB: Early ACK received...\n"); |
break; |
} |
} |
} |
while (send >= EP0_MAX_PACKET_SIZE); |
515,10 → 521,10
log_printf(USBLOG_SETUP_IN, "USB: Sent total %d\n", count); |
|
// Wait for ACK from host |
tS = timer_now(); |
tS = usbhw_timer_now(); |
do |
{ |
if (timer_diff(timer_now(), tS) > USB_CTRL_TX_TIMEOUT) |
if (usbhw_timer_diff(usbhw_timer_now(), tS) > USB_CTRL_TX_TIMEOUT) |
{ |
log_printf(USBLOG_ERR, "USB: ACK not received\n"); |
err = 1; |
538,10 → 544,10
return !err; |
} |
//----------------------------------------------------------------- |
// usb_init: |
// usbf_init: |
//----------------------------------------------------------------- |
void usb_init(FP_BUS_RESET bus_reset, FP_CLASS_REQUEST class_request) |
void usbf_init(unsigned int base, FP_BUS_RESET bus_reset, FP_CLASS_REQUEST class_request) |
{ |
_class_request = class_request; |
usbhw_init(bus_reset, usb_process_setup, usb_process_out); |
usbhw_init(base, bus_reset, usb_process_setup, usb_process_out); |
} |
/usb_device_core/trunk/sw/usb_device.h
10,7 → 10,15
//----------------------------------------------------------------- |
// Prototypes |
//----------------------------------------------------------------- |
void usb_init(FP_BUS_RESET bus_reset, FP_CLASS_REQUEST class_request); |
int usb_control_send(unsigned char *buf, int size); |
#ifdef __cplusplus |
extern "C" { |
#endif |
|
void usbf_init(unsigned int base, FP_BUS_RESET bus_reset, FP_CLASS_REQUEST class_request); |
int usb_control_send(unsigned char *buf, int size, int requested_size); |
|
#ifdef __cplusplus |
} |
#endif |
|
#endif |
/usb_device_core/trunk/sw/usb_log.h
5,8 → 5,8
// Defines: |
//----------------------------------------------------------------- |
#define USBLOG_HW_RESET 1 |
#define USBLOG_HW_CTRL 9 |
#define USBLOG_HW_DATA 7 |
#define USBLOG_HW_CTRL 7 |
#define USBLOG_HW_DATA 9 |
#define USBLOG_CONTROL 9 |
#define USBLOG_SETUP_DATA 9 |
#define USBLOG_SETUP 8 |
23,6 → 23,10
//----------------------------------------------------------------- |
// Prototypes |
//----------------------------------------------------------------- |
#ifdef HAS_USB_DEVICE_LOG |
extern int log_printf(int level, const char* ctrl1, ... ); |
#else |
static int log_printf(int level, const char* ctrl1, ... ) { return 0; } |
#endif |
|
#endif |
/usb_device_core/trunk/sw/usb_uart.c
1,46 → 1,39
//----------------------------------------------------------------- |
// USB Device Core |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// USB CDC Device SW |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// |
// Email: admin@ultra-embedded.com |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
// License: GPL |
// If you would like a version with a more permissive license for use in |
// closed source commercial applications please contact me for details. |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2013 - 2014 Ultra-Embedded.com |
// This file is part of USB CDC Device SW. |
// |
// 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. |
// USB CDC Device SW is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// USB CDC Device SW is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
// You should have received a copy of the GNU General Public License |
// along with USB CDC Device SW; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
#include <stdio.h> |
#include <string.h> |
#include "usb_hw.h" |
#include "usbf_hw.h" |
#include "usb_cdc.h" |
#include "usb_device.h" |
#include "usb_uart.h" |
#include "usb_log.h" |
#include "timer.h" |
|
//----------------------------------------------------------------- |
// Defines: |
61,7 → 54,7
_tx_count = 0; |
_rx_count = 0; |
|
cdc_init(); |
usb_cdc_init(); |
} |
//----------------------------------------------------------------- |
// usb_uart_haschar: |
129,6 → 122,34
return count; |
} |
//----------------------------------------------------------------- |
// usb_uart_putblock: |
//----------------------------------------------------------------- |
int usb_uart_putblock(unsigned char *data, int length) |
{ |
int count = 0; |
|
do |
{ |
int chunk = length; |
|
// Wait until space available (or timeout) |
t_time tS = usbhw_timer_now(); |
while (!usbhw_has_tx_space(CDC_ENDPOINT_BULK_IN)) |
{ |
if (usbhw_timer_diff(usbhw_timer_now(), tS) > USB_UART_TX_TIMEOUT) |
return 0; |
} |
|
usbhw_load_tx_buffer(CDC_ENDPOINT_BULK_IN, data, chunk); |
|
count += chunk; |
data += chunk; |
} |
while (count < length); |
|
return length; |
} |
//----------------------------------------------------------------- |
// usb_uart_putchar: |
//----------------------------------------------------------------- |
int usb_uart_putchar(char data) |
137,10 → 158,10
usb_uart_putchar('\r'); |
|
// Wait until space available (or timeout) |
t_time tS = timer_now(); |
t_time tS = usbhw_timer_now(); |
while (!usbhw_has_tx_space(CDC_ENDPOINT_BULK_IN)) |
{ |
if (timer_diff(timer_now(), tS) > USB_UART_TX_TIMEOUT) |
if (usbhw_timer_diff(usbhw_timer_now(), tS) > USB_UART_TX_TIMEOUT) |
return 0; |
} |
|
168,12 → 189,12
// If multiple of endpoint size, send ZLP |
if ( _tx_count == EP2_MAX_PACKET_SIZE ) |
{ |
t_time tS = timer_now(); |
t_time tS = usbhw_timer_now(); |
|
// Wait for TX ready and then send ZLP |
while (!usbhw_has_tx_space(CDC_ENDPOINT_BULK_IN)) |
{ |
if (timer_diff(timer_now(), tS) > USB_UART_TX_TIMEOUT) |
if (usbhw_timer_diff(usbhw_timer_now(), tS) > USB_UART_TX_TIMEOUT) |
{ |
log_printf(USBLOG_ERR, "UART: Flush timeout\n"); |
return ; |
/usb_device_core/trunk/sw/usb_uart.h
4,11 → 4,20
//----------------------------------------------------------------- |
// Prototypes |
//----------------------------------------------------------------- |
#ifdef __cplusplus |
extern "C" { |
#endif |
|
void usb_uart_init(void); |
int usb_uart_haschar(void); |
int usb_uart_getchar(void); |
int usb_uart_putblock(unsigned char *data, int length); |
int usb_uart_getblock(unsigned char *data, int max_length); |
int usb_uart_putchar(char txbyte); |
void usb_uart_flush(void); |
|
#ifdef __cplusplus |
} |
#endif |
|
#endif |
/usb_device_core/trunk/sw/usbf_defs.h
0,0 → 1,87
#ifndef __USBF_DEFS_H__ |
#define __USBF_DEFS_H__ |
|
//----------------------------------------------------------------- |
// Macros: |
//----------------------------------------------------------------- |
// For Little Endian CPUs |
#define USB_BYTE_SWAP16(n) (n) |
// For Big Endian CPUs |
//#define USB_BYTE_SWAP16(n) ((((unsigned short)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8)) |
|
#define LO_BYTE(w) ((unsigned char)(w)) |
#define HI_BYTE(w) ((unsigned char)(((unsigned short)(w) >> 8) & 0xFF)) |
|
#define MIN(a,b) ((a)<=(b)?(a):(b)) |
|
//----------------------------------------------------------------- |
// Defines: |
//----------------------------------------------------------------- |
|
// Device class |
#define DEV_CLASS_RESERVED 0x00 |
#define DEV_CLASS_AUDIO 0x01 |
#define DEV_CLASS_COMMS 0x02 |
#define DEV_CLASS_HID 0x03 |
#define DEV_CLASS_MONITOR 0x04 |
#define DEV_CLASS_PHY_IF 0x05 |
#define DEV_CLASS_POWER 0x06 |
#define DEV_CLASS_PRINTER 0x07 |
#define DEV_CLASS_STORAGE 0x08 |
#define DEV_CLASS_HUB 0x09 |
#define DEV_CLASS_TMC 0xFE |
#define DEV_CLASS_VENDOR_CUSTOM 0xFF |
|
// Standard requests (via SETUP packets) |
#define REQ_GET_STATUS 0x00 |
#define REQ_CLEAR_FEATURE 0x01 |
#define REQ_SET_FEATURE 0x03 |
#define REQ_SET_ADDRESS 0x05 |
#define REQ_GET_DESCRIPTOR 0x06 |
#define REQ_SET_DESCRIPTOR 0x07 |
#define REQ_GET_CONFIGURATION 0x08 |
#define REQ_SET_CONFIGURATION 0x09 |
#define REQ_GET_INTERFACE 0x0A |
#define REQ_SET_INTERFACE 0x0B |
#define REQ_SYNC_FRAME 0x0C |
|
// Descriptor types |
#define DESC_DEVICE 0x01 |
#define DESC_CONFIGURATION 0x02 |
#define DESC_STRING 0x03 |
#define DESC_INTERFACE 0x04 |
#define DESC_ENDPOINT 0x05 |
#define DESC_DEV_QUALIFIER 0x06 |
#define DESC_OTHER_SPEED_CONF 0x07 |
#define DESC_IF_POWER 0x08 |
|
// Endpoints |
#define ENDPOINT_DIR_MASK (1 << 7) |
#define ENDPOINT_DIR_IN (1 << 7) |
#define ENDPOINT_DIR_OUT (0 << 7) |
#define ENDPOINT_ADDR_MASK (0x7F) |
#define ENDPOINT_TYPE_MASK (0x3) |
#define ENDPOINT_TYPE_CONTROL (0) |
#define ENDPOINT_TYPE_ISO (1) |
#define ENDPOINT_TYPE_BULK (2) |
#define ENDPOINT_TYPE_INTERRUPT (3) |
|
// Device Requests (bmRequestType) |
#define USB_RECIPIENT_MASK 0x1F |
#define USB_RECIPIENT_DEVICE 0x00 |
#define USB_RECIPIENT_INTERFACE 0x01 |
#define USB_RECIPIENT_ENDPOINT 0x02 |
#define USB_REQUEST_TYPE_MASK 0x60 |
#define USB_STANDARD_REQUEST 0x00 |
#define USB_CLASS_REQUEST 0x20 |
#define USB_VENDOR_REQUEST 0x40 |
|
// USB device addresses are 7-bits |
#define USB_ADDRESS_MASK 0x7F |
|
// USB Feature Selectors |
#define USB_FEATURE_ENDPOINT_STATE 0x0000 |
#define USB_FEATURE_REMOTE_WAKEUP 0x0001 |
#define USB_FEATURE_TEST_MODE 0x0002 |
|
#endif |
/usb_device_core/trunk/sw/usbf_hw.c
0,0 → 1,839
//----------------------------------------------------------------- |
// USB CDC Device SW |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2014 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: GPL |
// If you would like a version with a more permissive license for use in |
// closed source commercial applications please contact me for details. |
//----------------------------------------------------------------- |
// |
// This file is part of USB CDC Device SW. |
// |
// USB CDC Device SW is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// USB CDC Device SW is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with USB CDC Device SW; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
#include "usbf_hw.h" |
#include "usb_log.h" |
#include "timer.h" |
|
//----------------------------------------------------------------- |
// Peripheral registers: |
//----------------------------------------------------------------- |
#define USB_FUNC_CTRL 0x0 |
#define USB_FUNC_CTRL_HS_CHIRP_EN 8 |
#define USB_FUNC_CTRL_HS_CHIRP_EN_SHIFT 8 |
#define USB_FUNC_CTRL_HS_CHIRP_EN_MASK 0x1 |
|
#define USB_FUNC_CTRL_PHY_DMPULLDOWN 7 |
#define USB_FUNC_CTRL_PHY_DMPULLDOWN_SHIFT 7 |
#define USB_FUNC_CTRL_PHY_DMPULLDOWN_MASK 0x1 |
|
#define USB_FUNC_CTRL_PHY_DPPULLDOWN 6 |
#define USB_FUNC_CTRL_PHY_DPPULLDOWN_SHIFT 6 |
#define USB_FUNC_CTRL_PHY_DPPULLDOWN_MASK 0x1 |
|
#define USB_FUNC_CTRL_PHY_TERMSELECT 5 |
#define USB_FUNC_CTRL_PHY_TERMSELECT_SHIFT 5 |
#define USB_FUNC_CTRL_PHY_TERMSELECT_MASK 0x1 |
|
#define USB_FUNC_CTRL_PHY_XCVRSELECT_SHIFT 3 |
#define USB_FUNC_CTRL_PHY_XCVRSELECT_MASK 0x3 |
|
#define USB_FUNC_CTRL_PHY_OPMODE_SHIFT 1 |
#define USB_FUNC_CTRL_PHY_OPMODE_MASK 0x3 |
|
#define USB_FUNC_CTRL_INT_EN_SOF 0 |
#define USB_FUNC_CTRL_INT_EN_SOF_SHIFT 0 |
#define USB_FUNC_CTRL_INT_EN_SOF_MASK 0x1 |
|
#define USB_FUNC_STAT 0x4 |
#define USB_FUNC_STAT_RST 13 |
#define USB_FUNC_STAT_RST_SHIFT 13 |
#define USB_FUNC_STAT_RST_MASK 0x1 |
|
#define USB_FUNC_STAT_LINESTATE_SHIFT 11 |
#define USB_FUNC_STAT_LINESTATE_MASK 0x3 |
|
#define USB_FUNC_STAT_FRAME_SHIFT 0 |
#define USB_FUNC_STAT_FRAME_MASK 0x7ff |
|
#define USB_FUNC_ADDR 0x8 |
#define USB_FUNC_ADDR_DEV_ADDR_SHIFT 0 |
#define USB_FUNC_ADDR_DEV_ADDR_MASK 0x7f |
|
#define USB_EP0_CFG 0xc |
#define USB_EP0_CFG_INT_RX 3 |
#define USB_EP0_CFG_INT_RX_SHIFT 3 |
#define USB_EP0_CFG_INT_RX_MASK 0x1 |
|
#define USB_EP0_CFG_INT_TX 2 |
#define USB_EP0_CFG_INT_TX_SHIFT 2 |
#define USB_EP0_CFG_INT_TX_MASK 0x1 |
|
#define USB_EP0_CFG_STALL_EP 1 |
#define USB_EP0_CFG_STALL_EP_SHIFT 1 |
#define USB_EP0_CFG_STALL_EP_MASK 0x1 |
|
#define USB_EP0_CFG_ISO 0 |
#define USB_EP0_CFG_ISO_SHIFT 0 |
#define USB_EP0_CFG_ISO_MASK 0x1 |
|
#define USB_EP0_TX_CTRL 0x10 |
#define USB_EP0_TX_CTRL_TX_FLUSH 17 |
#define USB_EP0_TX_CTRL_TX_FLUSH_SHIFT 17 |
#define USB_EP0_TX_CTRL_TX_FLUSH_MASK 0x1 |
|
#define USB_EP0_TX_CTRL_TX_START 16 |
#define USB_EP0_TX_CTRL_TX_START_SHIFT 16 |
#define USB_EP0_TX_CTRL_TX_START_MASK 0x1 |
|
#define USB_EP0_TX_CTRL_TX_LEN_SHIFT 0 |
#define USB_EP0_TX_CTRL_TX_LEN_MASK 0x7ff |
|
#define USB_EP0_RX_CTRL 0x14 |
#define USB_EP0_RX_CTRL_RX_FLUSH 1 |
#define USB_EP0_RX_CTRL_RX_FLUSH_SHIFT 1 |
#define USB_EP0_RX_CTRL_RX_FLUSH_MASK 0x1 |
|
#define USB_EP0_RX_CTRL_RX_ACCEPT 0 |
#define USB_EP0_RX_CTRL_RX_ACCEPT_SHIFT 0 |
#define USB_EP0_RX_CTRL_RX_ACCEPT_MASK 0x1 |
|
#define USB_EP0_STS 0x18 |
#define USB_EP0_STS_TX_ERR 20 |
#define USB_EP0_STS_TX_ERR_SHIFT 20 |
#define USB_EP0_STS_TX_ERR_MASK 0x1 |
|
#define USB_EP0_STS_TX_BUSY 19 |
#define USB_EP0_STS_TX_BUSY_SHIFT 19 |
#define USB_EP0_STS_TX_BUSY_MASK 0x1 |
|
#define USB_EP0_STS_RX_ERR 18 |
#define USB_EP0_STS_RX_ERR_SHIFT 18 |
#define USB_EP0_STS_RX_ERR_MASK 0x1 |
|
#define USB_EP0_STS_RX_SETUP 17 |
#define USB_EP0_STS_RX_SETUP_SHIFT 17 |
#define USB_EP0_STS_RX_SETUP_MASK 0x1 |
|
#define USB_EP0_STS_RX_READY 16 |
#define USB_EP0_STS_RX_READY_SHIFT 16 |
#define USB_EP0_STS_RX_READY_MASK 0x1 |
|
#define USB_EP0_STS_RX_COUNT_SHIFT 0 |
#define USB_EP0_STS_RX_COUNT_MASK 0x7ff |
|
#define USB_EP0_DATA 0x1c |
#define USB_EP0_DATA_DATA_SHIFT 0 |
#define USB_EP0_DATA_DATA_MASK 0xff |
|
#define USB_EP1_CFG 0x20 |
#define USB_EP1_CFG_INT_RX 3 |
#define USB_EP1_CFG_INT_RX_SHIFT 3 |
#define USB_EP1_CFG_INT_RX_MASK 0x1 |
|
#define USB_EP1_CFG_INT_TX 2 |
#define USB_EP1_CFG_INT_TX_SHIFT 2 |
#define USB_EP1_CFG_INT_TX_MASK 0x1 |
|
#define USB_EP1_CFG_STALL_EP 1 |
#define USB_EP1_CFG_STALL_EP_SHIFT 1 |
#define USB_EP1_CFG_STALL_EP_MASK 0x1 |
|
#define USB_EP1_CFG_ISO 0 |
#define USB_EP1_CFG_ISO_SHIFT 0 |
#define USB_EP1_CFG_ISO_MASK 0x1 |
|
#define USB_EP1_TX_CTRL 0x24 |
#define USB_EP1_TX_CTRL_TX_FLUSH 17 |
#define USB_EP1_TX_CTRL_TX_FLUSH_SHIFT 17 |
#define USB_EP1_TX_CTRL_TX_FLUSH_MASK 0x1 |
|
#define USB_EP1_TX_CTRL_TX_START 16 |
#define USB_EP1_TX_CTRL_TX_START_SHIFT 16 |
#define USB_EP1_TX_CTRL_TX_START_MASK 0x1 |
|
#define USB_EP1_TX_CTRL_TX_LEN_SHIFT 0 |
#define USB_EP1_TX_CTRL_TX_LEN_MASK 0x7ff |
|
#define USB_EP1_RX_CTRL 0x28 |
#define USB_EP1_RX_CTRL_RX_FLUSH 1 |
#define USB_EP1_RX_CTRL_RX_FLUSH_SHIFT 1 |
#define USB_EP1_RX_CTRL_RX_FLUSH_MASK 0x1 |
|
#define USB_EP1_RX_CTRL_RX_ACCEPT 0 |
#define USB_EP1_RX_CTRL_RX_ACCEPT_SHIFT 0 |
#define USB_EP1_RX_CTRL_RX_ACCEPT_MASK 0x1 |
|
#define USB_EP1_STS 0x2c |
#define USB_EP1_STS_TX_ERR 20 |
#define USB_EP1_STS_TX_ERR_SHIFT 20 |
#define USB_EP1_STS_TX_ERR_MASK 0x1 |
|
#define USB_EP1_STS_TX_BUSY 19 |
#define USB_EP1_STS_TX_BUSY_SHIFT 19 |
#define USB_EP1_STS_TX_BUSY_MASK 0x1 |
|
#define USB_EP1_STS_RX_ERR 18 |
#define USB_EP1_STS_RX_ERR_SHIFT 18 |
#define USB_EP1_STS_RX_ERR_MASK 0x1 |
|
#define USB_EP1_STS_RX_SETUP 17 |
#define USB_EP1_STS_RX_SETUP_SHIFT 17 |
#define USB_EP1_STS_RX_SETUP_MASK 0x1 |
|
#define USB_EP1_STS_RX_READY 16 |
#define USB_EP1_STS_RX_READY_SHIFT 16 |
#define USB_EP1_STS_RX_READY_MASK 0x1 |
|
#define USB_EP1_STS_RX_COUNT_SHIFT 0 |
#define USB_EP1_STS_RX_COUNT_MASK 0x7ff |
|
#define USB_EP1_DATA 0x30 |
#define USB_EP1_DATA_DATA_SHIFT 0 |
#define USB_EP1_DATA_DATA_MASK 0xff |
|
#define USB_EP2_CFG 0x34 |
#define USB_EP2_CFG_INT_RX 3 |
#define USB_EP2_CFG_INT_RX_SHIFT 3 |
#define USB_EP2_CFG_INT_RX_MASK 0x1 |
|
#define USB_EP2_CFG_INT_TX 2 |
#define USB_EP2_CFG_INT_TX_SHIFT 2 |
#define USB_EP2_CFG_INT_TX_MASK 0x1 |
|
#define USB_EP2_CFG_STALL_EP 1 |
#define USB_EP2_CFG_STALL_EP_SHIFT 1 |
#define USB_EP2_CFG_STALL_EP_MASK 0x1 |
|
#define USB_EP2_CFG_ISO 0 |
#define USB_EP2_CFG_ISO_SHIFT 0 |
#define USB_EP2_CFG_ISO_MASK 0x1 |
|
#define USB_EP2_TX_CTRL 0x38 |
#define USB_EP2_TX_CTRL_TX_FLUSH 17 |
#define USB_EP2_TX_CTRL_TX_FLUSH_SHIFT 17 |
#define USB_EP2_TX_CTRL_TX_FLUSH_MASK 0x1 |
|
#define USB_EP2_TX_CTRL_TX_START 16 |
#define USB_EP2_TX_CTRL_TX_START_SHIFT 16 |
#define USB_EP2_TX_CTRL_TX_START_MASK 0x1 |
|
#define USB_EP2_TX_CTRL_TX_LEN_SHIFT 0 |
#define USB_EP2_TX_CTRL_TX_LEN_MASK 0x7ff |
|
#define USB_EP2_RX_CTRL 0x3c |
#define USB_EP2_RX_CTRL_RX_FLUSH 1 |
#define USB_EP2_RX_CTRL_RX_FLUSH_SHIFT 1 |
#define USB_EP2_RX_CTRL_RX_FLUSH_MASK 0x1 |
|
#define USB_EP2_RX_CTRL_RX_ACCEPT 0 |
#define USB_EP2_RX_CTRL_RX_ACCEPT_SHIFT 0 |
#define USB_EP2_RX_CTRL_RX_ACCEPT_MASK 0x1 |
|
#define USB_EP2_STS 0x40 |
#define USB_EP2_STS_TX_ERR 20 |
#define USB_EP2_STS_TX_ERR_SHIFT 20 |
#define USB_EP2_STS_TX_ERR_MASK 0x1 |
|
#define USB_EP2_STS_TX_BUSY 19 |
#define USB_EP2_STS_TX_BUSY_SHIFT 19 |
#define USB_EP2_STS_TX_BUSY_MASK 0x1 |
|
#define USB_EP2_STS_RX_ERR 18 |
#define USB_EP2_STS_RX_ERR_SHIFT 18 |
#define USB_EP2_STS_RX_ERR_MASK 0x1 |
|
#define USB_EP2_STS_RX_SETUP 17 |
#define USB_EP2_STS_RX_SETUP_SHIFT 17 |
#define USB_EP2_STS_RX_SETUP_MASK 0x1 |
|
#define USB_EP2_STS_RX_READY 16 |
#define USB_EP2_STS_RX_READY_SHIFT 16 |
#define USB_EP2_STS_RX_READY_MASK 0x1 |
|
#define USB_EP2_STS_RX_COUNT_SHIFT 0 |
#define USB_EP2_STS_RX_COUNT_MASK 0x7ff |
|
#define USB_EP2_DATA 0x44 |
#define USB_EP2_DATA_DATA_SHIFT 0 |
#define USB_EP2_DATA_DATA_MASK 0xff |
|
#define USB_EP3_CFG 0x48 |
#define USB_EP3_CFG_INT_RX 3 |
#define USB_EP3_CFG_INT_RX_SHIFT 3 |
#define USB_EP3_CFG_INT_RX_MASK 0x1 |
|
#define USB_EP3_CFG_INT_TX 2 |
#define USB_EP3_CFG_INT_TX_SHIFT 2 |
#define USB_EP3_CFG_INT_TX_MASK 0x1 |
|
#define USB_EP3_CFG_STALL_EP 1 |
#define USB_EP3_CFG_STALL_EP_SHIFT 1 |
#define USB_EP3_CFG_STALL_EP_MASK 0x1 |
|
#define USB_EP3_CFG_ISO 0 |
#define USB_EP3_CFG_ISO_SHIFT 0 |
#define USB_EP3_CFG_ISO_MASK 0x1 |
|
#define USB_EP3_TX_CTRL 0x4c |
#define USB_EP3_TX_CTRL_TX_FLUSH 17 |
#define USB_EP3_TX_CTRL_TX_FLUSH_SHIFT 17 |
#define USB_EP3_TX_CTRL_TX_FLUSH_MASK 0x1 |
|
#define USB_EP3_TX_CTRL_TX_START 16 |
#define USB_EP3_TX_CTRL_TX_START_SHIFT 16 |
#define USB_EP3_TX_CTRL_TX_START_MASK 0x1 |
|
#define USB_EP3_TX_CTRL_TX_LEN_SHIFT 0 |
#define USB_EP3_TX_CTRL_TX_LEN_MASK 0x7ff |
|
#define USB_EP3_RX_CTRL 0x50 |
#define USB_EP3_RX_CTRL_RX_FLUSH 1 |
#define USB_EP3_RX_CTRL_RX_FLUSH_SHIFT 1 |
#define USB_EP3_RX_CTRL_RX_FLUSH_MASK 0x1 |
|
#define USB_EP3_RX_CTRL_RX_ACCEPT 0 |
#define USB_EP3_RX_CTRL_RX_ACCEPT_SHIFT 0 |
#define USB_EP3_RX_CTRL_RX_ACCEPT_MASK 0x1 |
|
#define USB_EP3_STS 0x54 |
#define USB_EP3_STS_TX_ERR 20 |
#define USB_EP3_STS_TX_ERR_SHIFT 20 |
#define USB_EP3_STS_TX_ERR_MASK 0x1 |
|
#define USB_EP3_STS_TX_BUSY 19 |
#define USB_EP3_STS_TX_BUSY_SHIFT 19 |
#define USB_EP3_STS_TX_BUSY_MASK 0x1 |
|
#define USB_EP3_STS_RX_ERR 18 |
#define USB_EP3_STS_RX_ERR_SHIFT 18 |
#define USB_EP3_STS_RX_ERR_MASK 0x1 |
|
#define USB_EP3_STS_RX_SETUP 17 |
#define USB_EP3_STS_RX_SETUP_SHIFT 17 |
#define USB_EP3_STS_RX_SETUP_MASK 0x1 |
|
#define USB_EP3_STS_RX_READY 16 |
#define USB_EP3_STS_RX_READY_SHIFT 16 |
#define USB_EP3_STS_RX_READY_MASK 0x1 |
|
#define USB_EP3_STS_RX_COUNT_SHIFT 0 |
#define USB_EP3_STS_RX_COUNT_MASK 0x7ff |
|
#define USB_EP3_DATA 0x58 |
#define USB_EP3_DATA_DATA_SHIFT 0 |
#define USB_EP3_DATA_DATA_MASK 0xff |
|
//----------------------------------------------------------------- |
// Defines: |
//----------------------------------------------------------------- |
#define EP_STRIDE 0x14 |
|
#define USB_FUNC_CTRL_MODE_MASK (0xFF << USB_FUNC_CTRL_PHY_OPMODE_SHIFT) |
|
#define USB_FUNC_CTRL_MODE_HS ((0 << USB_FUNC_CTRL_PHY_OPMODE_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_XCVRSELECT_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_TERMSELECT_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DPPULLDOWN_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DMPULLDOWN_SHIFT) | \ |
(0 << USB_FUNC_CTRL_HS_CHIRP_EN_SHIFT)) |
#define USB_FUNC_CTRL_MODE_PERIP_CHIRP ((2 << USB_FUNC_CTRL_PHY_OPMODE_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_XCVRSELECT_SHIFT) | \ |
(1 << USB_FUNC_CTRL_PHY_TERMSELECT_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DPPULLDOWN_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DMPULLDOWN_SHIFT) | \ |
(1 << USB_FUNC_CTRL_HS_CHIRP_EN_SHIFT)) |
#define USB_FUNC_CTRL_MODE_HOST_CHIRP ((2 << USB_FUNC_CTRL_PHY_OPMODE_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_XCVRSELECT_SHIFT) | \ |
(1 << USB_FUNC_CTRL_PHY_TERMSELECT_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DPPULLDOWN_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DMPULLDOWN_SHIFT) | \ |
(0 << USB_FUNC_CTRL_HS_CHIRP_EN_SHIFT)) |
#define USB_FUNC_CTRL_PULLUP_EN ((0 << USB_FUNC_CTRL_PHY_OPMODE_SHIFT) | \ |
(1 << USB_FUNC_CTRL_PHY_XCVRSELECT_SHIFT) | \ |
(1 << USB_FUNC_CTRL_PHY_TERMSELECT_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DPPULLDOWN_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DMPULLDOWN_SHIFT)) |
#define USB_FUNC_CTRL_PULLUP_DIS ((1 << USB_FUNC_CTRL_PHY_OPMODE_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_XCVRSELECT_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_TERMSELECT_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DPPULLDOWN_SHIFT) | \ |
(0 << USB_FUNC_CTRL_PHY_DMPULLDOWN_SHIFT)) |
|
#define USB_FUNC_ENDPOINTS 4 |
|
#define MIN(a,b) ((a)<=(b)?(a):(b)) |
|
//----------------------------------------------------------------- |
// Locals: |
//----------------------------------------------------------------- |
static unsigned int _tx_count[USB_FUNC_ENDPOINTS]; |
static int _addressed; |
static int _configured; |
static int _attached; |
static int _endpoint_stalled[USB_FUNC_ENDPOINTS]; |
static FUNC_PTR _func_bus_reset; |
static FUNC_PTR _func_setup; |
static FUNC_PTR _func_ctrl_out; |
static unsigned int _ctrl_reg; |
static unsigned int _usb_base; |
|
//----------------------------------------------------------------- |
// usbhw_reg_write: |
//----------------------------------------------------------------- |
static void usbhw_reg_write(unsigned int addr, unsigned data) |
{ |
*((volatile unsigned int*)(_usb_base + addr)) = data; |
} |
//----------------------------------------------------------------- |
// usbhw_reg_read: |
//----------------------------------------------------------------- |
static unsigned int usbhw_reg_read(unsigned int addr) |
{ |
return *((volatile unsigned int*)(_usb_base + addr)); |
} |
//----------------------------------------------------------------- |
// usbhw_init: |
//----------------------------------------------------------------- |
void usbhw_init(unsigned int base, FUNC_PTR bus_reset, FUNC_PTR on_setup, FUNC_PTR on_out) |
{ |
int i; |
|
_usb_base = base; |
|
log_printf(USBLOG_HW_RESET, "Init\n"); |
|
for (i=0;i<USB_FUNC_ENDPOINTS;i++) |
{ |
_tx_count[i] = 0; |
_endpoint_stalled[i] = 0; |
} |
|
_addressed = 0; |
_configured = 0; |
_attached = 0; |
|
_ctrl_reg = USB_FUNC_CTRL_PULLUP_DIS; |
|
_func_bus_reset = bus_reset; |
_func_setup = on_setup; |
_func_ctrl_out = on_out; |
|
usbhw_reg_write(USB_EP0_TX_CTRL, (1 << USB_EP0_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP1_TX_CTRL, (1 << USB_EP1_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP2_TX_CTRL, (1 << USB_EP2_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP3_TX_CTRL, (1 << USB_EP3_TX_CTRL_TX_FLUSH_SHIFT)); |
|
usbhw_reg_write(USB_EP0_RX_CTRL, (1 << USB_EP0_RX_CTRL_RX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP1_RX_CTRL, (1 << USB_EP1_RX_CTRL_RX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP2_RX_CTRL, (1 << USB_EP2_RX_CTRL_RX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP3_RX_CTRL, (1 << USB_EP3_RX_CTRL_RX_FLUSH_SHIFT)); |
} |
//----------------------------------------------------------------- |
// usbhw_service: |
//----------------------------------------------------------------- |
void usbhw_service(void) |
{ |
unsigned int status = usbhw_reg_read(USB_FUNC_STAT); |
static int _initial = 1; |
static int _reset_count = 0; |
int i; |
|
// Acknowledge fake USB reset after attach.. |
if (_initial) |
{ |
usbhw_reg_write(USB_FUNC_CTRL, _ctrl_reg); |
|
_initial = 0; |
return ; |
} |
|
#ifdef USB_SPEED_HS |
// Bus reset event |
if (status & (1 << USB_FUNC_STAT_RST)) |
{ |
// Ack bus reset by writing to CTRL register |
usbhw_reg_write(USB_FUNC_STAT, (1 << USB_FUNC_STAT_RST)); |
|
usbhw_reg_write(USB_EP0_TX_CTRL, (1 << USB_EP0_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP0_RX_CTRL, (1 << USB_EP0_RX_CTRL_RX_FLUSH_SHIFT)); |
|
usbhw_reg_write(USB_EP1_TX_CTRL, (1 << USB_EP1_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP2_TX_CTRL, (1 << USB_EP2_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP3_TX_CTRL, (1 << USB_EP3_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP1_RX_CTRL, (1 << USB_EP1_RX_CTRL_RX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP2_RX_CTRL, (1 << USB_EP2_RX_CTRL_RX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP3_RX_CTRL, (1 << USB_EP3_RX_CTRL_RX_FLUSH_SHIFT)); |
|
// Fail ... |
if (_reset_count > 4) |
{ |
log_printf(USBLOG_HW_RESET, " DEVICE: Another Reset Detected %d\n", timer_now()); |
|
// Force detach |
usbhw_attach(0); |
timer_sleep(100); |
usbhw_attach(1); |
|
_reset_count = 0; |
return ; |
} |
|
_configured = 0; |
_addressed = 0; |
|
for (i=0;i<USB_FUNC_ENDPOINTS;i++) |
{ |
_tx_count[i] = 0; |
_endpoint_stalled[i] = 0; |
} |
|
log_printf(USBLOG_HW_RESET, " DEVICE: Reset Detected %d\n", timer_now()); |
|
// Detected SE0 for at least 2.5us, now drive HS CHIRP for at least 1ms |
usbhw_reg_write(USB_FUNC_CTRL, USB_FUNC_CTRL_MODE_PERIP_CHIRP); |
timer_sleep(3); |
|
// Stop driving the chirp pattern |
log_printf(USBLOG_HW_RESET, " DEVICE: Peripheral Chirp De-assert %d\n", timer_now()); |
usbhw_reg_write(USB_FUNC_CTRL, USB_FUNC_CTRL_MODE_HOST_CHIRP); |
|
int chirps = 0; |
while (chirps < 5) |
{ |
static unsigned old_ls = ~0; |
unsigned new_ls = (usbhw_reg_read(USB_FUNC_STAT) >> USB_FUNC_STAT_LINESTATE_SHIFT) & 0x3; |
if ((old_ls != new_ls) && (new_ls == 1 || new_ls == 2)) |
chirps++; |
old_ls = new_ls; |
} |
|
log_printf(USBLOG_HW_RESET, " DEVICE: Host Chirp Detected %d\n", timer_now()); |
usbhw_reg_write(USB_FUNC_CTRL, USB_FUNC_CTRL_MODE_HS); |
|
|
log_printf(USBLOG_HW_RESET, " DEVICE: BUS RESET %d\n", timer_now()); |
|
|
if (_func_bus_reset) |
_func_bus_reset(); |
|
// Ack bus reset by writing to CTRL register |
usbhw_reg_write(USB_FUNC_STAT, (1 << USB_FUNC_STAT_RST)); |
_reset_count += 1; |
} |
#else |
// Bus reset event |
if (status & (1 << USB_FUNC_STAT_RST)) |
{ |
// Ack bus reset by writing to CTRL register |
usbhw_reg_write(USB_FUNC_STAT, (1 << USB_FUNC_STAT_RST)); |
|
_configured = 0; |
_addressed = 0; |
|
for (i=0;i<USB_FUNC_ENDPOINTS;i++) |
{ |
_tx_count[i] = 0; |
_endpoint_stalled[i] = 0; |
} |
|
log_printf(USBLOG_HW_RESET, " DEVICE: BUS RESET %d\n", timer_now()); |
|
usbhw_reg_write(USB_EP0_TX_CTRL, (1 << USB_EP0_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP1_TX_CTRL, (1 << USB_EP1_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP2_TX_CTRL, (1 << USB_EP2_TX_CTRL_TX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP3_TX_CTRL, (1 << USB_EP3_TX_CTRL_TX_FLUSH_SHIFT)); |
|
usbhw_reg_write(USB_EP0_RX_CTRL, (1 << USB_EP0_RX_CTRL_RX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP1_RX_CTRL, (1 << USB_EP1_RX_CTRL_RX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP2_RX_CTRL, (1 << USB_EP2_RX_CTRL_RX_FLUSH_SHIFT)); |
usbhw_reg_write(USB_EP3_RX_CTRL, (1 << USB_EP3_RX_CTRL_RX_FLUSH_SHIFT)); |
|
if (_func_bus_reset) |
_func_bus_reset(); |
} |
#endif |
|
status = usbhw_reg_read(USB_EP0_STS); |
|
// Tx underflow error |
if (status & (1 << USB_EP0_STS_TX_ERR)) |
{ |
log_printf(USBLOG_ERR, "Tx underflow error!\n"); |
while (1) |
; |
} |
// CRC error |
else if (status & (1 << USB_EP0_STS_RX_ERR)) |
{ |
log_printf(USBLOG_ERR, "Rx CRC error!\n"); |
while (1) |
; |
} |
// SETUP packet received (EP0) |
else if ((status & (1 << USB_EP0_STS_RX_READY)) && (status & (1 << USB_EP0_STS_RX_SETUP))) |
{ |
log_printf(USBLOG_HW_CTRL, "SETUP packet received\n"); |
|
if (_func_setup) |
_func_setup(); |
|
log_printf(USBLOG_HW_CTRL, "SETUP packet processed\n"); |
} |
// OUT data received on EP0 |
else if (status & (1 << USB_EP0_STS_RX_READY)) |
{ |
log_printf(USBLOG_HW_CTRL, "OUT packet received on EP0\n"); |
|
if (_func_ctrl_out) |
_func_ctrl_out(); |
} |
} |
//----------------------------------------------------------------- |
// usbhw_attach: |
//----------------------------------------------------------------- |
void usbhw_attach(int state) |
{ |
// Pull up D+ to Vdd |
if ( state ) |
{ |
_attached = 1; |
_ctrl_reg &= ~USB_FUNC_CTRL_MODE_MASK; |
_ctrl_reg |= USB_FUNC_CTRL_PULLUP_EN; |
usbhw_reg_write(USB_FUNC_CTRL, _ctrl_reg); |
log_printf(USBLOG_HW_CTRL, "ATTACH\n"); |
|
// Reset any previous reset detection |
usbhw_reg_write(USB_FUNC_STAT, (1 << USB_FUNC_STAT_RST)); |
} |
// Disconnect pull-up to disconnect from bus |
else |
{ |
_attached = 0; |
_ctrl_reg &= ~USB_FUNC_CTRL_MODE_MASK; |
_ctrl_reg |= USB_FUNC_CTRL_PULLUP_DIS; |
usbhw_reg_write(USB_FUNC_CTRL, _ctrl_reg); |
log_printf(USBLOG_HW_CTRL, "DETACH\n"); |
} |
} |
//----------------------------------------------------------------- |
// usbhw_is_configured: |
//----------------------------------------------------------------- |
int usbhw_is_configured(void) |
{ |
return _configured; |
} |
//----------------------------------------------------------------- |
// usbhw_is_addressed: |
//----------------------------------------------------------------- |
int usbhw_is_addressed(void) |
{ |
return _addressed; |
} |
//----------------------------------------------------------------- |
// usbhw_is_attached: |
//----------------------------------------------------------------- |
int usbhw_is_attached(void) |
{ |
return _attached; |
} |
//----------------------------------------------------------------- |
// usbhw_set_configured: |
//----------------------------------------------------------------- |
void usbhw_set_configured(int configured) |
{ |
_configured = configured; |
} |
//----------------------------------------------------------------- |
// usbhw_set_address: |
//----------------------------------------------------------------- |
void usbhw_set_address(unsigned char addr) |
{ |
usbhw_reg_write(USB_FUNC_ADDR, addr); |
_addressed = 1; |
} |
//----------------------------------------------------------------- |
// usbhw_is_endpoint_stalled: |
//----------------------------------------------------------------- |
int usbhw_is_endpoint_stalled(unsigned char endpoint) |
{ |
return _endpoint_stalled[endpoint]; |
} |
//----------------------------------------------------------------- |
// usbhw_clear_endpoint_stall: |
//----------------------------------------------------------------- |
void usbhw_clear_endpoint_stall(unsigned char endpoint) |
{ |
unsigned int data = usbhw_reg_read(USB_EP0_CFG + (endpoint * EP_STRIDE)); |
data &= ~(1 << USB_EP0_CFG_STALL_EP); |
usbhw_reg_write(USB_EP0_CFG + (endpoint * EP_STRIDE), data); |
|
_endpoint_stalled[endpoint] = 0; |
} |
//----------------------------------------------------------------- |
// usbhw_set_endpoint_stall: |
//----------------------------------------------------------------- |
void usbhw_set_endpoint_stall(unsigned char endpoint) |
{ |
unsigned int data = usbhw_reg_read(USB_EP0_CFG + (endpoint * EP_STRIDE)); |
data |= (1 << USB_EP0_CFG_STALL_EP); |
usbhw_reg_write(USB_EP0_CFG + (endpoint * EP_STRIDE), data); |
|
_endpoint_stalled[endpoint] = 1; |
} |
//----------------------------------------------------------------- |
// usbhw_is_rx_ready: Is some receive data ready on an endpoint? |
//----------------------------------------------------------------- |
int usbhw_is_rx_ready(unsigned char endpoint) |
{ |
return (usbhw_reg_read(USB_EP0_STS + (endpoint * EP_STRIDE)) & (1 << USB_EP0_STS_RX_READY_SHIFT)) ? 1 : 0; |
} |
//----------------------------------------------------------------- |
// usbhw_get_rx_count: Get amount of data waiting in endpoint |
//----------------------------------------------------------------- |
int usbhw_get_rx_count(unsigned char endpoint) |
{ |
return (usbhw_reg_read(USB_EP0_STS + (endpoint * EP_STRIDE)) >> USB_EP0_STS_RX_COUNT_SHIFT) & USB_EP0_STS_RX_COUNT_MASK; |
} |
//----------------------------------------------------------------- |
// usbhw_get_rx_data: Read data from endpoint |
//----------------------------------------------------------------- |
int usbhw_get_rx_data(unsigned char endpoint, unsigned char *data, int max_len) |
{ |
int i; |
int bytes_ready; |
int bytes_read = 0; |
|
// Received data count includes CRC |
bytes_ready = usbhw_get_rx_count(endpoint); |
|
// Limit data read to buffer size |
bytes_read = MIN(bytes_ready, max_len); |
|
for (i=0;i<bytes_read;i++) |
*data++ = usbhw_reg_read(USB_EP0_DATA + (endpoint * EP_STRIDE)); |
|
// Return number of bytes read |
return bytes_read; |
} |
//----------------------------------------------------------------- |
// usbhw_get_rx_byte: Read byte from endpoint |
//----------------------------------------------------------------- |
unsigned char usbhw_get_rx_byte(unsigned char endpoint) |
{ |
return usbhw_reg_read(USB_EP0_DATA + (endpoint * EP_STRIDE)); |
} |
//----------------------------------------------------------------- |
// usbhw_clear_rx_ready: Clear Rx data ready flag |
//----------------------------------------------------------------- |
void usbhw_clear_rx_ready(unsigned char endpoint) |
{ |
log_printf(USBLOG_HW_DATA, "Clear endpoint buffer\n"); |
usbhw_reg_write(USB_EP0_RX_CTRL + (endpoint * EP_STRIDE), 1 << USB_EP1_RX_CTRL_RX_ACCEPT_SHIFT); |
} |
//----------------------------------------------------------------- |
// usbhw_has_tx_space: Is there space in the tx buffer |
//----------------------------------------------------------------- |
int usbhw_has_tx_space(unsigned char endpoint) |
{ |
return (usbhw_reg_read(USB_EP0_STS + (endpoint * EP_STRIDE)) & (1 << USB_EP1_STS_TX_BUSY_SHIFT)) ? 0 : 1; |
} |
//----------------------------------------------------------------- |
// usbhw_load_tx_buffer: Load tx buffer & start transfer (non-blocking) |
//----------------------------------------------------------------- |
int usbhw_load_tx_buffer(unsigned char endpoint, unsigned char *data, int count) |
{ |
int i; |
unsigned int word_data = 0; |
|
for (i=0;i<count;i++) |
usbhw_reg_write(USB_EP0_DATA + (endpoint * EP_STRIDE), *data++); |
|
// Start transmit |
word_data = (1 << USB_EP0_TX_CTRL_TX_START_SHIFT) | count; |
usbhw_reg_write(USB_EP0_TX_CTRL + (endpoint * EP_STRIDE), word_data); |
|
log_printf(USBLOG_HW_DATA, "Tx %d bytes\n", count); |
|
return count; |
} |
//----------------------------------------------------------------- |
// usbhw_write_tx_byte: Write a byte to Tx buffer (don't send yet) |
//----------------------------------------------------------------- |
void usbhw_write_tx_byte(unsigned char endpoint, unsigned char data) |
{ |
usbhw_reg_write(USB_EP0_DATA + (endpoint * EP_STRIDE), data); |
_tx_count[endpoint]++; |
} |
//----------------------------------------------------------------- |
// usbhw_start_tx: Start a tx packet with data loaded into endpoint |
//----------------------------------------------------------------- |
void usbhw_start_tx(unsigned char endpoint) |
{ |
// Start transmit |
unsigned int word_data = (1 << USB_EP0_TX_CTRL_TX_START_SHIFT) | _tx_count[endpoint]; |
usbhw_reg_write(USB_EP0_TX_CTRL + (endpoint * EP_STRIDE), word_data); |
|
log_printf(USBLOG_HW_DATA, "Tx %d bytes\n", _tx_count[endpoint]); |
|
_tx_count[endpoint] = 0; |
} |
//----------------------------------------------------------------- |
// usbhw_control_endpoint_stall: |
//----------------------------------------------------------------- |
void usbhw_control_endpoint_stall(void) |
{ |
log_printf(USBLOG_ERR, "Error, send EP stall!\n"); |
usbhw_set_endpoint_stall(0); |
|
// Control endpoint stalls are self clearing |
_endpoint_stalled[0] = 0; |
} |
//----------------------------------------------------------------- |
// usbhw_control_endpoint_ack: |
//----------------------------------------------------------------- |
void usbhw_control_endpoint_ack(void) |
{ |
// Send ZLP on EP0 |
log_printf(USBLOG_HW_DATA, "Send ZLP\n"); |
usbhw_reg_write(USB_EP0_TX_CTRL, (1 << USB_EP0_TX_CTRL_TX_START_SHIFT)); |
|
log_printf(USBLOG_HW_DATA, "Tx [ZLP/ACK]\n"); |
|
while (!usbhw_has_tx_space(0)) |
; |
|
log_printf(USBLOG_HW_DATA, "Tx complete\n"); |
} |
//----------------------------------------------------------------- |
// usbhw_get_frame_number: |
//----------------------------------------------------------------- |
unsigned short usbhw_get_frame_number(void) |
{ |
return (usbhw_reg_read(USB_FUNC_STAT) >> USB_FUNC_STAT_FRAME_SHIFT) & USB_FUNC_STAT_FRAME_MASK; |
} |
|
//----------------------------------------------------------------- |
// usbhw_timer_now: |
//----------------------------------------------------------------- |
t_time usbhw_timer_now(void) |
{ |
return timer_now(); |
} |
/usb_device_core/trunk/sw/usbf_hw.h
0,0 → 1,63
#ifndef __USBF_HW_H__ |
#define __USBF_HW_H__ |
|
//----------------------------------------------------------------- |
// Defines |
//----------------------------------------------------------------- |
#define ENDPOINT_CONTROL 0 |
|
#ifdef USB_SPEED_HS |
#define EP0_MAX_PACKET_SIZE 64 |
#else |
#define EP0_MAX_PACKET_SIZE 8 |
#endif |
|
#define EP1_MAX_PACKET_SIZE 64 |
#define EP2_MAX_PACKET_SIZE 64 |
#define EP3_MAX_PACKET_SIZE 64 |
|
//----------------------------------------------------------------- |
// Types |
//----------------------------------------------------------------- |
typedef void (*FUNC_PTR)(void); |
|
//----------------------------------------------------------------- |
// Prototypes |
//----------------------------------------------------------------- |
#ifdef __cplusplus |
extern "C" { |
#endif |
|
void usbhw_init(unsigned int base, FUNC_PTR bus_reset, FUNC_PTR on_setup, FUNC_PTR on_out); |
void usbhw_service(void); |
void usbhw_attach(int state); |
int usbhw_is_attached(void); |
int usbhw_is_addressed(void); |
int usbhw_is_configured(void); |
void usbhw_set_configured(int configured); |
void usbhw_set_address(unsigned char addr); |
int usbhw_is_endpoint_stalled(unsigned char endpoint); |
void usbhw_clear_endpoint_stall(unsigned char endpoint); |
void usbhw_set_endpoint_stall(unsigned char endpoint); |
int usbhw_is_rx_ready(unsigned char endpoint); |
int usbhw_get_rx_count(unsigned char endpoint); |
int usbhw_get_rx_data(unsigned char endpoint, unsigned char *data, int max_len); |
unsigned char usbhw_get_rx_byte(unsigned char endpoint); |
void usbhw_clear_rx_ready(unsigned char endpoint); |
int usbhw_has_tx_space(unsigned char endpoint); |
int usbhw_load_tx_buffer(unsigned char endpoint, unsigned char *data, int count); |
void usbhw_write_tx_byte(unsigned char endpoint, unsigned char data); |
void usbhw_start_tx(unsigned char endpoint); |
void usbhw_control_endpoint_stall(void); |
void usbhw_control_endpoint_ack(void); |
unsigned short usbhw_get_frame_number(void); |
|
typedef unsigned long t_time; |
t_time usbhw_timer_now(void); |
static long usbhw_timer_diff(t_time a, t_time b) { return (long)(a - b); } |
|
#ifdef __cplusplus |
} |
#endif |
|
#endif |