usb fixed?

This commit is contained in:
Polprzewodnikowy 2022-02-04 19:23:32 +01:00
parent 8493c2edb1
commit 8da9359ee1
4 changed files with 207 additions and 139 deletions

View File

@ -19,7 +19,7 @@
#
# Quartus Prime
# Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
# Date created = 19:00:58 February 02, 2022
# Date created = 19:19:14 February 04, 2022
#
# -------------------------------------------------------------------------- #
#
@ -88,11 +88,9 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/vendor/vendor_reconfigure.sv
# Pin & Location Assignments
# ==========================
set_location_assignment PIN_6 -to o_usb_clk
set_location_assignment PIN_7 -to io_usb_miosi[2]
set_location_assignment PIN_8 -to io_usb_miosi[3]
set_location_assignment PIN_10 -to io_usb_miosi[0]
set_location_assignment PIN_11 -to io_usb_miosi[1]
set_location_assignment PIN_6 -to o_usb_cs
set_location_assignment PIN_7 -to i_usb_miso
set_location_assignment PIN_8 -to o_usb_clk
set_location_assignment PIN_12 -to i_uart_rxd
set_location_assignment PIN_13 -to o_uart_txd
set_location_assignment PIN_17 -to o_led
@ -165,13 +163,15 @@ set_location_assignment PIN_114 -to o_sd_clk
set_location_assignment PIN_118 -to io_sd_cmd
set_location_assignment PIN_119 -to io_sd_dat[3]
set_location_assignment PIN_120 -to io_sd_dat[2]
set_location_assignment PIN_121 -to io_usb_miosi[5]
set_location_assignment PIN_122 -to io_usb_miosi[7]
set_location_assignment PIN_123 -to o_n64_irq
set_location_assignment PIN_124 -to io_usb_miosi[6]
set_location_assignment PIN_126 -to io_usb_miosi[4]
set_location_assignment PIN_140 -to o_usb_cs
set_location_assignment PIN_141 -to i_usb_miso
set_location_assignment PIN_124 -to io_usb_miosi[7]
set_location_assignment PIN_127 -to io_usb_miosi[6]
set_location_assignment PIN_130 -to io_usb_miosi[4]
set_location_assignment PIN_131 -to io_usb_miosi[5]
set_location_assignment PIN_134 -to io_usb_miosi[3]
set_location_assignment PIN_135 -to io_usb_miosi[2]
set_location_assignment PIN_140 -to io_usb_miosi[1]
set_location_assignment PIN_141 -to io_usb_miosi[0]
# Classic Timing Assignments
# ==========================
@ -231,34 +231,39 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# Pin & Location Assignments
# ==========================
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_aleh
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_alel
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_read
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_write
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_alel
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_miso
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_txd
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_rtc_scl
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cs
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ras
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cas
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_we
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_rtc_scl
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_a[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ba[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cas
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cs
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ras
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_we
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_txd
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_clk
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_cs
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[*]
# Fitter Assignments
# ==================
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[*]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_nmi
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_uart_rxd
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_n64_si_dq

View File

@ -49,11 +49,11 @@ set_multicycle_path -hold -end 1 -from [get_clocks {sdram_clk}] -to [get_clocks
# FT1248 timings
set_output_delay -clock [get_clocks {usb_clk}] -max 5.0 [get_ports {io_usb_miosi[*] o_usb_cs}]
set_output_delay -clock [get_clocks {usb_clk}] -min -5.0 [get_ports {io_usb_miosi[*] o_usb_cs}]
set_output_delay -clock [get_clocks {usb_clk}] -max 2.0 [get_ports {io_usb_miosi[*] o_usb_cs}]
set_output_delay -clock [get_clocks {usb_clk}] -min -1.0 [get_ports {io_usb_miosi[*] o_usb_cs}]
set_input_delay -clock [get_clocks {usb_clk}] -max 5.0 [get_ports {io_usb_miosi[*] i_usb_miso}]
set_input_delay -clock [get_clocks {usb_clk}] -min 5.0 [get_ports {io_usb_miosi[*] i_usb_miso}]
set_input_delay -clock [get_clocks {usb_clk}] -min 2.5 [get_ports {io_usb_miosi[*] i_usb_miso}]
set_multicycle_path -setup -start 2 -from [get_clocks $sys_clk] -to [get_clocks {usb_clk}]
set_multicycle_path -hold -start 3 -from [get_clocks $sys_clk] -to [get_clocks {usb_clk}]

View File

@ -27,6 +27,7 @@ module usb_ft1248 (
logic rx_full;
logic rx_almost_full;
logic rx_write;
logic [7:0] rx_wdata;
logic tx_empty;
logic tx_almost_empty;
@ -45,7 +46,7 @@ module usb_ft1248 (
.full(rx_full),
.almost_full(rx_almost_full),
.wrreq(rx_write),
.data(usb_miosi)
.data(rx_wdata)
);
intel_fifo_8 fifo_8_tx_inst (
@ -63,6 +64,29 @@ module usb_ft1248 (
.data(tx_wdata)
);
logic [7:0] usb_miosi_out;
logic usb_oe;
logic ft_clk;
logic ft_cs;
logic ft_miso;
logic [7:0] ft_miosi_in;
logic [7:0] ft_miosi_out;
logic ft_oe;
always_ff @(posedge clk) begin
usb_clk <= ft_clk;
usb_cs <= ft_cs;
ft_miso <= usb_miso;
ft_miosi_in <= usb_miosi;
usb_miosi_out <= ft_miosi_out;
usb_oe <= ft_oe;
end
always_comb begin
usb_miosi = usb_oe ? usb_miosi_out : 8'hZZ;
end
typedef enum bit [2:0] {
STATE_IDLE,
STATE_SELECT,
@ -80,163 +104,202 @@ module usb_ft1248 (
CMD_WRITE_BUFFER_FLUSH = 8'h08
} e_command;
logic usb_miosi_oe;
logic write_buffer_flush_pending;
logic write_modem_status_pending;
logic [4:0] modem_status_counter;
logic modem_status_read;
logic last_reset_status;
logic reset_reply;
logic [3:0] phase;
logic [7:0] usb_cmd;
e_state state;
always_comb begin
usb_miosi = 8'hZZ;
if (usb_miosi_oe) begin
usb_miosi = 8'h00;
if ((state == STATE_COMMAND) || (state == STATE_STATUS)) begin
usb_miosi = usb_cmd;
end
if ((state == STATE_DATA) || (state == STATE_DESELECT)) begin
if (usb_cmd == CMD_WRITE) begin
usb_miosi = tx_rdata;
end
if (usb_cmd == CMD_WRITE_MODEM_STATUS) begin
usb_miosi = {2'b00, reset_reply, 5'b00000};
end
end
end
end
e_state next_state;
e_command cmd;
e_command next_cmd;
logic [3:0] phase;
logic reset_reply;
logic last_reset_status;
logic [4:0] modem_status_counter;
logic write_modem_status_pending;
logic write_buffer_flush_pending;
always_ff @(posedge clk) begin
rx_write <= 1'b0;
tx_read <= 1'b0;
modem_status_read <= 1'b0;
phase <= {phase[2:0], phase[3]};
state <= next_state;
cmd <= next_cmd;
if (reset) begin
usb_clk <= 1'b0;
usb_cs <= 1'b1;
usb_miosi_oe <= 1'b0;
reset_pending <= 1'b0;
write_buffer_flush_pending <= 1'b0;
write_modem_status_pending <= 1'b0;
modem_status_counter <= 5'd0;
last_reset_status <= 1'b0;
reset_reply <= 1'b0;
phase <= 4'b0001;
state <= STATE_IDLE;
end else begin
if (write_buffer_flush) begin
write_buffer_flush_pending <= 1'b1;
phase <= {phase[2:0], phase[3]};
if (state == STATE_IDLE) begin
phase <= 4'b0100;
end
if (reset) begin
reset_pending <= 1'b0;
last_reset_status <= 1'b0;
modem_status_counter <= 5'd0;
write_modem_status_pending <= 1'b0;
write_buffer_flush_pending <= 1'b0;
end else begin
if (reset_ack) begin
reset_pending <= 1'b0;
write_modem_status_pending <= 1'b1;
reset_reply <= 1'b1;
end
if (modem_status_read) begin
last_reset_status <= usb_miosi[0];
if (!last_reset_status && usb_miosi[0]) begin
if (write_buffer_flush) begin
write_buffer_flush_pending <= 1'b1;
end
if (state == STATE_IDLE) begin
modem_status_counter <= modem_status_counter + 1'd1;
end
if (!ft_miso && (state == STATE_DATA) && phase[3]) begin
if (cmd == CMD_READ_MODEM_STATUS) begin
last_reset_status <= ft_miosi_in[0];
if (!last_reset_status && ft_miosi_in[0]) begin
reset_pending <= 1'b1;
end
if (last_reset_status && !usb_miosi[0]) begin
if (last_reset_status && !ft_miosi_in[0]) begin
write_modem_status_pending <= 1'b1;
reset_reply <= 1'b0;
end
end
if (cmd == CMD_WRITE_MODEM_STATUS) begin
write_modem_status_pending <= 1'b0;
end
if (cmd == CMD_WRITE_BUFFER_FLUSH) begin
write_buffer_flush_pending <= 1'b0;
end
end
end
end
always_comb begin
ft_clk = 1'b0;
ft_cs = 1'b1;
ft_miosi_out = 8'hFF;
ft_oe = 1'b0;
if (state == STATE_SELECT) begin
ft_cs = 1'b0;
end
if (state == STATE_COMMAND) begin
if (phase[0] || phase[1]) begin
ft_clk = 1'b1;
end
ft_cs = 1'b0;
ft_miosi_out = cmd;
ft_oe = 1'b1;
end
if (state == STATE_STATUS) begin
if (phase[0] || phase[1]) begin
ft_clk = 1'b1;
end
ft_cs = 1'b0;
end
if (state == STATE_DATA) begin
ft_cs = 1'b0;
if (phase[0] || phase[1]) begin
ft_clk = 1'b1;
end
if (cmd == CMD_WRITE) begin
ft_miosi_out = tx_rdata;
ft_oe = 1'b1;
end
if (cmd == CMD_WRITE_MODEM_STATUS) begin
ft_miosi_out = {2'b00, reset_reply, 5'b00000};
ft_oe = 1'b1;
end
end
end
always_comb begin
rx_write = 1'b0;
tx_read = 1'b0;
rx_wdata = ft_miosi_in;
if (!ft_miso && (state == STATE_DATA) && phase[3]) begin
if (cmd == CMD_WRITE) begin
tx_read = 1'b1;
end
if (cmd == CMD_READ) begin
rx_write = 1'b1;
end
end
end
always_comb begin
next_state = state;
next_cmd = cmd;
if (reset) begin
next_state = STATE_IDLE;
end else begin
case (state)
STATE_IDLE: begin
usb_cs <= 1'b0;
state <= STATE_SELECT;
if (write_modem_status_pending) begin
usb_cmd <= CMD_WRITE_MODEM_STATUS;
next_state = STATE_SELECT;
next_cmd = CMD_WRITE_MODEM_STATUS;
end else if (&modem_status_counter) begin
usb_cmd <= CMD_READ_MODEM_STATUS;
next_state = STATE_SELECT;
next_cmd = CMD_READ_MODEM_STATUS;
end else if (!tx_empty) begin
usb_cmd <= CMD_WRITE;
next_state = STATE_SELECT;
next_cmd = CMD_WRITE;
end else if (write_buffer_flush_pending) begin
usb_cmd <= CMD_WRITE_BUFFER_FLUSH;
next_state = STATE_SELECT;
next_cmd = CMD_WRITE_BUFFER_FLUSH;
end else if (!rx_full) begin
usb_cmd <= CMD_READ;
end else begin
usb_cs <= 1'b1;
modem_status_counter <= modem_status_counter + 1'd1;
state <= STATE_IDLE;
next_state = STATE_SELECT;
next_cmd = CMD_READ;
end
end
STATE_SELECT: begin
phase <= 4'b0001;
state <= STATE_COMMAND;
if (phase[3]) begin
next_state = STATE_COMMAND;
end
end
STATE_COMMAND: begin
if (phase[0]) begin
usb_clk <= 1'b1;
usb_miosi_oe <= 1'b1;
end else if (phase[2]) begin
usb_clk <= 1'b0;
end else if (phase[3]) begin
state <= STATE_STATUS;
if (phase[3]) begin
next_state = STATE_STATUS;
end
end
STATE_STATUS: begin
if (phase[0]) begin
usb_clk <= 1'b1;
usb_miosi_oe <= 1'b0;
end else if (phase[2]) begin
usb_clk <= 1'b0;
end else if (phase[3]) begin
state <= STATE_DATA;
if (phase[3]) begin
if (ft_miso) begin
next_state = STATE_DESELECT;
end else begin
next_state = STATE_DATA;
end
end
end
STATE_DATA: begin
if (phase[0]) begin
usb_clk <= 1'b1;
usb_miosi_oe <= (usb_cmd == CMD_WRITE) || (usb_cmd == CMD_WRITE_MODEM_STATUS);
end else if (phase[2]) begin
usb_clk <= 1'b0;
end else if (phase[3]) begin
if (usb_miso) begin
state <= STATE_DESELECT;
end else if (usb_cmd == CMD_WRITE) begin
tx_read <= 1'b1;
if (phase[3]) begin
if (ft_miso) begin
next_state = STATE_DESELECT;
end else if (cmd == CMD_WRITE) begin
if (tx_almost_empty) begin
state <= STATE_DESELECT;
next_state = STATE_DESELECT;
end
end else if (usb_cmd == CMD_READ) begin
rx_write <= 1'b1;
end else if (cmd == CMD_READ) begin
if (rx_almost_full) begin
state <= STATE_DESELECT;
next_state = STATE_DESELECT;
end
end else if (usb_cmd == CMD_READ_MODEM_STATUS) begin
modem_status_read <= 1'b1;
state <= STATE_DESELECT;
end else if (usb_cmd == CMD_WRITE_MODEM_STATUS) begin
write_modem_status_pending <= 1'b0;
state <= STATE_DESELECT;
end else if (usb_cmd == CMD_WRITE_BUFFER_FLUSH) begin
write_buffer_flush_pending <= 1'b0;
state <= STATE_DESELECT;
end else begin
next_state = STATE_DESELECT;
end
end
end
STATE_DESELECT: begin
usb_cs <= 1'b1;
usb_miosi_oe <= 1'b0;
if (phase[1]) begin
modem_status_counter <= modem_status_counter + 1'd1;
state <= STATE_IDLE;
next_state = STATE_IDLE;
end
end
default: begin
next_state = STATE_IDLE;
end
endcase
end
end

View File

@ -157,9 +157,9 @@ class SC64:
self.__usb.close()
for p in ports:
if (p.vid == 0x0403 and p.pid == 0x6014 and p.serial_number.startswith("SC")):
if (p.vid == 0x0403 and p.pid == 0x6014 and p.serial_number.startswith("SC64")):
try:
self.__usb = Serial(p.device, timeout=0.5, write_timeout=0.5)
self.__usb = Serial(p.device, timeout=1.0, write_timeout=1.0)
self.reset_link()
self.__probe_device()
except (SerialException, SC64Exception):