mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-26 15:44:14 +01:00
usb debug and si stuff
This commit is contained in:
parent
5671e20c3f
commit
17311eed90
@ -63,6 +63,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_gpio.sv
|
|||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_sdram.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_sdram.sv
|
||||||
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_si.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_soc.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_soc.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_uart.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_uart.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_usb.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_usb.sv
|
||||||
@ -72,10 +73,12 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/memory_sdram.sv
|
|||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bootloader.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bootloader.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bus.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bus.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_cfg.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_cfg.sv
|
||||||
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_dd.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_flashram.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_flashram.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi_fifo.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi_fifo.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_sdram.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_sdram.sv
|
||||||
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_si.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_soc.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_soc.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/config.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/config.sv
|
||||||
|
@ -62,6 +62,8 @@ module SummerCart64 (
|
|||||||
|
|
||||||
if_flashram flashram ();
|
if_flashram flashram ();
|
||||||
|
|
||||||
|
if_si si ();
|
||||||
|
|
||||||
system system_inst (
|
system system_inst (
|
||||||
.sys(sys)
|
.sys(sys)
|
||||||
);
|
);
|
||||||
@ -78,6 +80,7 @@ module SummerCart64 (
|
|||||||
.dma(dma),
|
.dma(dma),
|
||||||
.sdram(sdram),
|
.sdram(sdram),
|
||||||
.flashram(flashram),
|
.flashram(flashram),
|
||||||
|
.si(si),
|
||||||
|
|
||||||
.n64_pi_alel(i_n64_pi_alel),
|
.n64_pi_alel(i_n64_pi_alel),
|
||||||
.n64_pi_aleh(i_n64_pi_aleh),
|
.n64_pi_aleh(i_n64_pi_aleh),
|
||||||
@ -103,6 +106,7 @@ module SummerCart64 (
|
|||||||
.dma(dma),
|
.dma(dma),
|
||||||
.sdram(sdram),
|
.sdram(sdram),
|
||||||
.flashram(flashram),
|
.flashram(flashram),
|
||||||
|
.si(si),
|
||||||
|
|
||||||
.gpio_o(gpio_o),
|
.gpio_o(gpio_o),
|
||||||
.gpio_i(gpio_i),
|
.gpio_i(gpio_i),
|
||||||
|
59
fw/rtl/cpu/cpu_si.sv
Normal file
59
fw/rtl/cpu/cpu_si.sv
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
module cpu_si (
|
||||||
|
if_system.sys sys,
|
||||||
|
if_cpu_bus bus,
|
||||||
|
if_si.cpu si
|
||||||
|
);
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
bus.ack <= 1'b0;
|
||||||
|
if (bus.request) begin
|
||||||
|
bus.ack <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
bus.rdata = 32'd0;
|
||||||
|
if (bus.ack) begin
|
||||||
|
case (bus.address[3:2])
|
||||||
|
0: bus.rdata = {
|
||||||
|
20'd0,
|
||||||
|
si.rx_length[6:3],
|
||||||
|
4'd0,
|
||||||
|
si.tx_busy,
|
||||||
|
1'b0,
|
||||||
|
si.rx_data[0],
|
||||||
|
si.rx_ready
|
||||||
|
};
|
||||||
|
1: bus.rdata = {si.rx_data[56:49], si.rx_data[64:57], si.rx_data[72:65], si.rx_data[80:73]};
|
||||||
|
2: bus.rdata = {si.rx_data[24:17], si.rx_data[32:25], si.rx_data[40:33], si.rx_data[48:41]};
|
||||||
|
3: bus.rdata = {16'd0, si.rx_data[8:1], si.rx_data[16:9]};
|
||||||
|
default: bus.rdata = 32'd0;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
si.tx_data = {bus.wdata[7:0], bus.wdata[15:8], bus.wdata[23:16], bus.wdata[31:24]};
|
||||||
|
si.tx_length = bus.wdata[22:16];
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
si.tx_reset <= 1'b0;
|
||||||
|
si.rx_reset <= 1'b0;
|
||||||
|
si.tx_start <= 1'b0;
|
||||||
|
si.tx_wmask <= 3'b000;
|
||||||
|
|
||||||
|
if (bus.request && (&bus.wmask)) begin
|
||||||
|
case (bus.address[3:2])
|
||||||
|
0: begin
|
||||||
|
si.tx_reset <= bus.wdata[7];
|
||||||
|
si.rx_reset <= bus.wdata[6];
|
||||||
|
si.tx_start <= bus.wdata[2];
|
||||||
|
end
|
||||||
|
1: si.tx_wmask[0] <= 1'b1;
|
||||||
|
2: si.tx_wmask[1] <= 1'b1;
|
||||||
|
3: si.tx_wmask[2] <= 1'b1;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -4,6 +4,7 @@ module cpu_soc (
|
|||||||
if_dma dma,
|
if_dma dma,
|
||||||
if_sdram.cpu sdram,
|
if_sdram.cpu sdram,
|
||||||
if_flashram.cpu flashram,
|
if_flashram.cpu flashram,
|
||||||
|
if_si.cpu si,
|
||||||
|
|
||||||
input [7:0] gpio_i,
|
input [7:0] gpio_i,
|
||||||
output [7:0] gpio_o,
|
output [7:0] gpio_o,
|
||||||
@ -104,4 +105,10 @@ module cpu_soc (
|
|||||||
.flashram(flashram)
|
.flashram(flashram)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
cpu_si cpu_si_inst (
|
||||||
|
.sys(sys),
|
||||||
|
.bus(bus.at[sc64::ID_CPU_SI].device),
|
||||||
|
.si(si)
|
||||||
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
83
fw/rtl/n64/n64_dd.sv
Normal file
83
fw/rtl/n64/n64_dd.sv
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
interface if_dd();
|
||||||
|
|
||||||
|
logic hard_reset;
|
||||||
|
logic cmd_request;
|
||||||
|
logic cmd_ack;
|
||||||
|
logic [7:0] command;
|
||||||
|
logic [15:0] status;
|
||||||
|
logic [15:0] data_input;
|
||||||
|
logic [15:0] data_output;
|
||||||
|
logic bm_request;
|
||||||
|
logic [15:0] bm_control;
|
||||||
|
logic [15:0] bm_status;
|
||||||
|
|
||||||
|
modport n64 (
|
||||||
|
output hard_reset,
|
||||||
|
output cmd_request,
|
||||||
|
input cmd_ack,
|
||||||
|
output command,
|
||||||
|
input status,
|
||||||
|
output data_input,
|
||||||
|
input data_output,
|
||||||
|
output bm_request,
|
||||||
|
output bm_control,
|
||||||
|
input bm_status
|
||||||
|
);
|
||||||
|
|
||||||
|
modport cpu (
|
||||||
|
input hard_reset,
|
||||||
|
input cmd_request,
|
||||||
|
output cmd_ack,
|
||||||
|
input command,
|
||||||
|
output status,
|
||||||
|
input data_input,
|
||||||
|
output data_output,
|
||||||
|
input bm_request,
|
||||||
|
input bm_control,
|
||||||
|
output bm_status
|
||||||
|
);
|
||||||
|
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
|
||||||
|
module n64_dd (
|
||||||
|
if_system.sys sys,
|
||||||
|
if_n64_bus bus
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef enum bit [0:0] {
|
||||||
|
S_IDLE,
|
||||||
|
S_WAIT
|
||||||
|
} e_state;
|
||||||
|
|
||||||
|
e_state state;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
bus.rdata = 16'h0000;
|
||||||
|
if (bus.ack) begin
|
||||||
|
bus.rdata = !bus.address[1] ? 16'h0040 : 16'h0000;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
bus.ack <= 1'b0;
|
||||||
|
|
||||||
|
if (sys.reset) begin
|
||||||
|
state <= S_IDLE;
|
||||||
|
end else begin
|
||||||
|
case (state)
|
||||||
|
S_IDLE: begin
|
||||||
|
if (bus.request) begin
|
||||||
|
state <= S_WAIT;
|
||||||
|
bus.ack <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
S_WAIT: begin
|
||||||
|
state <= S_IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -61,7 +61,7 @@ module n64_pi (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Control signals input synchronization
|
// Control signals and input synchronization
|
||||||
|
|
||||||
logic [2:0] n64_pi_alel_ff;
|
logic [2:0] n64_pi_alel_ff;
|
||||||
logic [2:0] n64_pi_aleh_ff;
|
logic [2:0] n64_pi_aleh_ff;
|
||||||
@ -207,7 +207,7 @@ module n64_pi (
|
|||||||
if (cfg.dd_enabled) begin
|
if (cfg.dd_enabled) begin
|
||||||
if (n64_pi_ad_input == 16'h0500) begin
|
if (n64_pi_ad_input == 16'h0500) begin
|
||||||
n64_pi_address_valid <= 1'b1;
|
n64_pi_address_valid <= 1'b1;
|
||||||
next_id <= sc64::ID_N64_DDREGS;
|
next_id <= sc64::ID_N64_DD;
|
||||||
end
|
end
|
||||||
if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin
|
if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin
|
||||||
n64_pi_address_valid <= 1'b1;
|
n64_pi_address_valid <= 1'b1;
|
||||||
|
222
fw/rtl/n64/n64_si.sv
Normal file
222
fw/rtl/n64/n64_si.sv
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
interface if_si ();
|
||||||
|
|
||||||
|
logic rx_reset;
|
||||||
|
logic rx_ready;
|
||||||
|
logic [6:0] rx_length;
|
||||||
|
logic [80:0] rx_data;
|
||||||
|
|
||||||
|
logic tx_reset;
|
||||||
|
logic tx_start;
|
||||||
|
logic tx_busy;
|
||||||
|
logic [2:0] tx_wmask;
|
||||||
|
logic [6:0] tx_length;
|
||||||
|
logic [31:0] tx_data;
|
||||||
|
|
||||||
|
modport si (
|
||||||
|
input rx_reset,
|
||||||
|
output rx_ready,
|
||||||
|
output rx_length,
|
||||||
|
output rx_data,
|
||||||
|
input tx_reset,
|
||||||
|
input tx_start,
|
||||||
|
output tx_busy,
|
||||||
|
input tx_wmask,
|
||||||
|
input tx_length,
|
||||||
|
input tx_data
|
||||||
|
);
|
||||||
|
|
||||||
|
modport cpu (
|
||||||
|
output rx_reset,
|
||||||
|
input rx_ready,
|
||||||
|
input rx_length,
|
||||||
|
input rx_data,
|
||||||
|
output tx_reset,
|
||||||
|
output tx_start,
|
||||||
|
input tx_busy,
|
||||||
|
output tx_wmask,
|
||||||
|
output tx_length,
|
||||||
|
output tx_data
|
||||||
|
);
|
||||||
|
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module n64_si (
|
||||||
|
if_system.sys sys,
|
||||||
|
if_si.si si,
|
||||||
|
|
||||||
|
input n64_si_clk,
|
||||||
|
inout n64_si_dq
|
||||||
|
);
|
||||||
|
|
||||||
|
// Control signals and input synchronization
|
||||||
|
|
||||||
|
logic [1:0] n64_si_clk_ff;
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
n64_si_clk_ff <= {n64_si_clk_ff[0], n64_si_clk};
|
||||||
|
end
|
||||||
|
|
||||||
|
logic si_reset;
|
||||||
|
logic si_clk;
|
||||||
|
logic si_dq;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
si_reset = sys.n64_hard_reset;
|
||||||
|
si_clk = n64_si_clk_ff[1];
|
||||||
|
si_dq = n64_si_dq;
|
||||||
|
end
|
||||||
|
|
||||||
|
logic last_si_clk;
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
last_si_clk <= si_clk;
|
||||||
|
end
|
||||||
|
|
||||||
|
logic si_clk_rising_edge;
|
||||||
|
logic si_clk_falling_edge;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
si_clk_rising_edge = !si_reset && !last_si_clk && si_clk;
|
||||||
|
si_clk_falling_edge = !si_reset && last_si_clk && !si_clk;
|
||||||
|
end
|
||||||
|
|
||||||
|
logic si_dq_output_enable;
|
||||||
|
logic si_dq_output_enable_data;
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
si_dq_output_enable <= si_dq_output_enable_data;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
n64_si_dq = si_dq_output_enable ? 1'b0 : 1'bZ;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Data register and shifter
|
||||||
|
|
||||||
|
logic [80:0] trx_data;
|
||||||
|
logic rx_shift;
|
||||||
|
logic tx_shift;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
si.rx_data = trx_data;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
if (si.tx_wmask[0]) trx_data[80:49] <= si.tx_data;
|
||||||
|
if (si.tx_wmask[1]) trx_data[48:17] <= si.tx_data;
|
||||||
|
if (si.tx_wmask[2]) trx_data[16:0] <= si.tx_data[16:0];
|
||||||
|
|
||||||
|
if (rx_shift || tx_shift) begin
|
||||||
|
trx_data <= {trx_data[79:0], rx_sub_bit_counter < 2'd2};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// RX path
|
||||||
|
|
||||||
|
typedef enum bit [0:0] {
|
||||||
|
S_RX_IDLE,
|
||||||
|
S_RX_WAITING
|
||||||
|
} e_rx_state;
|
||||||
|
|
||||||
|
e_rx_state rx_state;
|
||||||
|
|
||||||
|
logic [1:0] rx_sub_bit_counter;
|
||||||
|
logic [3:0] rx_timeout_counter;
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
rx_shift <= 1'b0;
|
||||||
|
|
||||||
|
if (si_clk_rising_edge) begin
|
||||||
|
if (rx_timeout_counter < 4'd8) begin
|
||||||
|
rx_timeout_counter <= rx_timeout_counter + 1'd1;
|
||||||
|
end else if (si.rx_length > 7'd0) begin
|
||||||
|
si.rx_ready <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (sys.reset || si.rx_reset) begin
|
||||||
|
rx_state <= S_RX_IDLE;
|
||||||
|
si.rx_ready <= 1'b0;
|
||||||
|
si.rx_length <= 7'd0;
|
||||||
|
end else if (!si.tx_busy) begin
|
||||||
|
case (rx_state)
|
||||||
|
S_RX_IDLE: begin
|
||||||
|
if (si_clk_rising_edge && !si_dq) begin
|
||||||
|
rx_state <= S_RX_WAITING;
|
||||||
|
rx_sub_bit_counter <= 2'd0;
|
||||||
|
rx_timeout_counter <= 3'd0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
S_RX_WAITING: begin
|
||||||
|
if (si_clk_rising_edge) begin
|
||||||
|
if (si_dq) begin
|
||||||
|
rx_state <= S_RX_IDLE;
|
||||||
|
rx_shift <= 1'b1;
|
||||||
|
si.rx_length <= si.rx_length + 1'd1;
|
||||||
|
end else if (rx_sub_bit_counter < 2'd3) begin
|
||||||
|
rx_sub_bit_counter <= rx_sub_bit_counter + 1'd1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// TX path
|
||||||
|
|
||||||
|
typedef enum bit [0:0] {
|
||||||
|
S_TX_IDLE,
|
||||||
|
S_TX_SENDING
|
||||||
|
} e_tx_state;
|
||||||
|
|
||||||
|
e_tx_state tx_state;
|
||||||
|
|
||||||
|
logic [2:0] tx_sub_bit_counter;
|
||||||
|
logic [6:0] tx_bit_counter;
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
tx_shift <= 1'b0;
|
||||||
|
|
||||||
|
if (sys.reset || si.tx_reset) begin
|
||||||
|
tx_state <= S_TX_IDLE;
|
||||||
|
si_dq_output_enable_data <= 1'b0;
|
||||||
|
si.tx_busy <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
case (tx_state)
|
||||||
|
S_TX_IDLE: begin
|
||||||
|
if (si.tx_start) begin
|
||||||
|
tx_state <= S_TX_SENDING;
|
||||||
|
tx_sub_bit_counter <= 3'd0;
|
||||||
|
tx_bit_counter <= si.tx_length;
|
||||||
|
si.tx_busy <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
S_TX_SENDING: begin
|
||||||
|
if (si_clk_falling_edge) begin
|
||||||
|
tx_sub_bit_counter <= tx_sub_bit_counter + 1'd1;
|
||||||
|
if (tx_sub_bit_counter == 3'd7) begin
|
||||||
|
tx_shift <= 1'b1;
|
||||||
|
if (tx_bit_counter > 7'd1) begin
|
||||||
|
tx_bit_counter <= tx_bit_counter - 1'd1;
|
||||||
|
end else begin
|
||||||
|
tx_state <= S_TX_IDLE;
|
||||||
|
si.tx_busy <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (trx_data[80]) begin
|
||||||
|
si_dq_output_enable_data <= tx_sub_bit_counter < 3'd2;
|
||||||
|
end else begin
|
||||||
|
si_dq_output_enable_data <= tx_sub_bit_counter < 3'd6;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -4,6 +4,7 @@ module n64_soc (
|
|||||||
if_dma.memory dma,
|
if_dma.memory dma,
|
||||||
if_sdram.memory sdram,
|
if_sdram.memory sdram,
|
||||||
if_flashram.flashram flashram,
|
if_flashram.flashram flashram,
|
||||||
|
if_si.si si,
|
||||||
|
|
||||||
input n64_pi_alel,
|
input n64_pi_alel,
|
||||||
input n64_pi_aleh,
|
input n64_pi_aleh,
|
||||||
@ -37,6 +38,14 @@ module n64_soc (
|
|||||||
.n64_pi_ad(n64_pi_ad)
|
.n64_pi_ad(n64_pi_ad)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
n64_si n64_si_inst (
|
||||||
|
.sys(sys),
|
||||||
|
.si(si),
|
||||||
|
|
||||||
|
.n64_si_clk(n64_si_clk),
|
||||||
|
.n64_si_dq(n64_si_dq)
|
||||||
|
);
|
||||||
|
|
||||||
n64_sdram n64_sdram_inst (
|
n64_sdram n64_sdram_inst (
|
||||||
.sys(sys),
|
.sys(sys),
|
||||||
.bus(bus.at[sc64::ID_N64_SDRAM].device),
|
.bus(bus.at[sc64::ID_N64_SDRAM].device),
|
||||||
@ -64,9 +73,9 @@ module n64_soc (
|
|||||||
.flashram(flashram)
|
.flashram(flashram)
|
||||||
);
|
);
|
||||||
|
|
||||||
n64_dummy n64_ddregs_inst (
|
n64_dd n64_dd_inst (
|
||||||
.sys(sys),
|
.sys(sys),
|
||||||
.bus(bus.at[sc64::ID_N64_DDREGS].device)
|
.bus(bus.at[sc64::ID_N64_DD].device)
|
||||||
);
|
);
|
||||||
|
|
||||||
n64_cfg n64_cfg_inst (
|
n64_cfg n64_cfg_inst (
|
||||||
@ -76,46 +85,3 @@ module n64_soc (
|
|||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
module n64_dummy (
|
|
||||||
if_system.sys sys,
|
|
||||||
if_n64_bus bus
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef enum bit [0:0] {
|
|
||||||
S_IDLE,
|
|
||||||
S_WAIT
|
|
||||||
} e_state;
|
|
||||||
|
|
||||||
e_state state;
|
|
||||||
|
|
||||||
always_comb begin
|
|
||||||
bus.rdata = 16'h0000;
|
|
||||||
if (bus.ack) begin
|
|
||||||
bus.rdata = !bus.address[1] ? 16'h0040 : 16'h0000;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always_ff @(posedge sys.clk) begin
|
|
||||||
bus.ack <= 1'b0;
|
|
||||||
|
|
||||||
if (sys.reset) begin
|
|
||||||
state <= S_IDLE;
|
|
||||||
end else begin
|
|
||||||
case (state)
|
|
||||||
S_IDLE: begin
|
|
||||||
if (bus.request) begin
|
|
||||||
state <= S_WAIT;
|
|
||||||
bus.ack <= 1'b1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
S_WAIT: begin
|
|
||||||
state <= S_IDLE;
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
interface if_dd();
|
|
||||||
|
|
||||||
logic hard_reset;
|
|
||||||
logic cmd_request;
|
|
||||||
logic cmd_ack;
|
|
||||||
logic [7:0] command;
|
|
||||||
logic [15:0] status;
|
|
||||||
logic [15:0] data_input;
|
|
||||||
logic [15:0] data_output;
|
|
||||||
logic bm_request;
|
|
||||||
logic [15:0] bm_control;
|
|
||||||
logic [15:0] bm_status;
|
|
||||||
|
|
||||||
modport n64 (
|
|
||||||
output hard_reset,
|
|
||||||
output cmd_request,
|
|
||||||
input cmd_ack,
|
|
||||||
output command,
|
|
||||||
input status,
|
|
||||||
output data_input,
|
|
||||||
input data_output,
|
|
||||||
output bm_request,
|
|
||||||
output bm_control,
|
|
||||||
input bm_status
|
|
||||||
);
|
|
||||||
|
|
||||||
modport cpu (
|
|
||||||
input hard_reset,
|
|
||||||
input cmd_request,
|
|
||||||
output cmd_ack,
|
|
||||||
input command,
|
|
||||||
output status,
|
|
||||||
input data_input,
|
|
||||||
output data_output,
|
|
||||||
input bm_request,
|
|
||||||
input bm_control,
|
|
||||||
output bm_status
|
|
||||||
);
|
|
||||||
|
|
||||||
endinterface
|
|
@ -4,7 +4,7 @@ package sc64;
|
|||||||
ID_N64_SDRAM,
|
ID_N64_SDRAM,
|
||||||
ID_N64_BOOTLOADER,
|
ID_N64_BOOTLOADER,
|
||||||
ID_N64_FLASHRAM,
|
ID_N64_FLASHRAM,
|
||||||
ID_N64_DDREGS,
|
ID_N64_DD,
|
||||||
ID_N64_CFG,
|
ID_N64_CFG,
|
||||||
__ID_N64_END
|
__ID_N64_END
|
||||||
} e_n64_id;
|
} e_n64_id;
|
||||||
@ -20,6 +20,7 @@ package sc64;
|
|||||||
ID_CPU_CFG,
|
ID_CPU_CFG,
|
||||||
ID_CPU_SDRAM,
|
ID_CPU_SDRAM,
|
||||||
ID_CPU_FLASHRAM,
|
ID_CPU_FLASHRAM,
|
||||||
|
ID_CPU_SI,
|
||||||
__ID_CPU_END
|
__ID_CPU_END
|
||||||
} e_cpu_id;
|
} e_cpu_id;
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ MEMORY {
|
|||||||
ROM (rx) : org = 0x10000000, len = 128
|
ROM (rx) : org = 0x10000000, len = 128
|
||||||
}
|
}
|
||||||
|
|
||||||
__stack_pointer = ORIGIN(RAM) + LENGTH(RAM) - 4;
|
__stack_pointer = ORIGIN(RAM) + LENGTH(RAM) - 16;
|
||||||
|
|
||||||
ENTRY(reset_handler)
|
ENTRY(reset_handler)
|
||||||
|
|
||||||
|
@ -1,16 +1,28 @@
|
|||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
|
#include "controller.h"
|
||||||
|
|
||||||
|
|
||||||
static e_cfg_save_type_t save_type = CFG_SAVE_TYPE_NONE;
|
static e_cfg_save_type_t save_type = CFG_SAVE_TYPE_NONE;
|
||||||
static uint16_t cic_seed = 0xFFFF;
|
static uint16_t cic_seed = 0xFFFF;
|
||||||
static uint8_t tv_type = 0xFF;
|
static uint8_t tv_type = 0xFF;
|
||||||
|
static bool eeprom_enabled = false;
|
||||||
|
|
||||||
|
static bool n64_to_pc_pending = false;
|
||||||
|
static uint32_t n64_to_pc_address;
|
||||||
|
static uint32_t n64_to_pc_length;
|
||||||
|
|
||||||
|
static bool pc_to_n64_ready = false;
|
||||||
|
static uint32_t pc_to_n64_arg;
|
||||||
|
static uint32_t pc_to_n64_address;
|
||||||
|
static uint32_t pc_to_n64_length;
|
||||||
|
|
||||||
void process_usb (void);
|
void process_usb (void);
|
||||||
void process_cfg (void);
|
void process_cfg (void);
|
||||||
void process_flashram (void);
|
void process_flashram (void);
|
||||||
|
void process_si (void);
|
||||||
|
|
||||||
|
bool debug_decide (uint32_t *args);
|
||||||
void config_update (uint32_t *args);
|
void config_update (uint32_t *args);
|
||||||
void config_query (uint32_t *args);
|
void config_query (uint32_t *args);
|
||||||
|
|
||||||
@ -23,6 +35,7 @@ void main (void) {
|
|||||||
dma_abort();
|
dma_abort();
|
||||||
usb_flush_rx();
|
usb_flush_rx();
|
||||||
usb_flush_tx();
|
usb_flush_tx();
|
||||||
|
si_reset();
|
||||||
|
|
||||||
cfg_set_sdram_switch(true);
|
cfg_set_sdram_switch(true);
|
||||||
cfg_set_save_type(CFG_SAVE_TYPE_NONE);
|
cfg_set_save_type(CFG_SAVE_TYPE_NONE);
|
||||||
@ -33,21 +46,11 @@ void main (void) {
|
|||||||
process_usb();
|
process_usb();
|
||||||
process_cfg();
|
process_cfg();
|
||||||
process_flashram();
|
process_flashram();
|
||||||
|
process_si();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
USB_STATE_IDLE,
|
|
||||||
USB_STATE_ARGS,
|
|
||||||
USB_STATE_DATA,
|
|
||||||
USB_STATE_RESPONSE,
|
|
||||||
} e_usb_state_t;
|
|
||||||
|
|
||||||
#define USB_CMD_TOKEN (0x434D4400)
|
|
||||||
#define USB_CMP_TOKEN (0x434D5000)
|
|
||||||
#define USB_ERR_TOKEN (0x45525200)
|
|
||||||
|
|
||||||
void process_usb (void) {
|
void process_usb (void) {
|
||||||
static e_usb_state_t state = USB_STATE_IDLE;
|
static e_usb_state_t state = USB_STATE_IDLE;
|
||||||
static uint8_t cmd;
|
static uint8_t cmd;
|
||||||
@ -60,14 +63,20 @@ void process_usb (void) {
|
|||||||
case USB_STATE_IDLE:
|
case USB_STATE_IDLE:
|
||||||
if (usb_rx_word(&args[0])) {
|
if (usb_rx_word(&args[0])) {
|
||||||
if ((args[0] & 0xFFFFFF00) == USB_CMD_TOKEN) {
|
if ((args[0] & 0xFFFFFF00) == USB_CMD_TOKEN) {
|
||||||
state = USB_STATE_ARGS;
|
|
||||||
cmd = args[0] & 0xFF;
|
cmd = args[0] & 0xFF;
|
||||||
error = false;
|
error = false;
|
||||||
processing = false;
|
processing = false;
|
||||||
current_word = 0;
|
current_word = 0;
|
||||||
|
state = USB_STATE_ARGS;
|
||||||
} else {
|
} else {
|
||||||
state = USB_STATE_RESPONSE;
|
cmd = '!';
|
||||||
error = true;
|
error = true;
|
||||||
|
state = USB_STATE_RESPONSE;
|
||||||
|
}
|
||||||
|
} else if (n64_to_pc_pending) {
|
||||||
|
if (!dma_busy()) {
|
||||||
|
dma_start(n64_to_pc_address, n64_to_pc_length, DMA_ID_USB, DMA_DIR_FROM_SDRAM);
|
||||||
|
state = USB_STATE_N64_TO_PC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -112,11 +121,15 @@ void process_usb (void) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
|
cfg_set_usb_waiting(true);
|
||||||
|
pc_to_n64_arg = args[0];
|
||||||
|
pc_to_n64_length = args[1];
|
||||||
|
state = USB_STATE_PC_TO_N64;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
state = USB_STATE_RESPONSE;
|
|
||||||
error = true;
|
error = true;
|
||||||
|
state = USB_STATE_RESPONSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -127,6 +140,28 @@ void process_usb (void) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case USB_STATE_N64_TO_PC:
|
||||||
|
if (!dma_busy()) {
|
||||||
|
n64_to_pc_pending = false;
|
||||||
|
state = USB_STATE_IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_STATE_PC_TO_N64:
|
||||||
|
if (!dma_busy()) {
|
||||||
|
if (!processing) {
|
||||||
|
if (pc_to_n64_ready) {
|
||||||
|
dma_start(pc_to_n64_address, pc_to_n64_length, DMA_ID_USB, DMA_DIR_TO_SDRAM);
|
||||||
|
processing = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pc_to_n64_ready = false;
|
||||||
|
processing = false;
|
||||||
|
state = USB_STATE_IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
state = USB_STATE_IDLE;
|
state = USB_STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
@ -136,6 +171,7 @@ void process_usb (void) {
|
|||||||
void process_cfg (void) {
|
void process_cfg (void) {
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
uint32_t args[2];
|
uint32_t args[2];
|
||||||
|
bool error;
|
||||||
|
|
||||||
if (cfg_get_command(&cmd, args)) {
|
if (cfg_get_command(&cmd, args)) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
@ -150,6 +186,8 @@ void process_cfg (void) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
|
error = debug_decide(args);
|
||||||
|
cfg_set_response(args, error);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -181,15 +219,124 @@ void process_flashram (void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void process_si (void) {
|
||||||
|
uint8_t rx_data[10];
|
||||||
|
uint8_t tx_data[10];
|
||||||
|
uint32_t *save_data;
|
||||||
|
uint32_t *data_offset;
|
||||||
|
|
||||||
typedef enum {
|
if (si_rx_ready()) {
|
||||||
CONFIG_UPDATE_SDRAM_SWITCH,
|
if (si_rx_stop_bit()) {
|
||||||
CONFIG_UPDATE_SDRAM_WRITABLE,
|
si_rx(rx_data);
|
||||||
CONFIG_UPDATE_DD_ENABLE,
|
|
||||||
CONFIG_UPDATE_SAVE_TYPE,
|
if (eeprom_enabled) {
|
||||||
CONFIG_UPDATE_CIC_SEED,
|
save_data = (uint32_t *) (SDRAM_BASE + cfg_get_save_offset() + (rx_data[1] * 8));
|
||||||
CONFIG_UPDATE_TV_TYPE
|
|
||||||
} e_config_update_t;
|
switch (rx_data[0]) {
|
||||||
|
case SI_CMD_EEPROM_STATUS:
|
||||||
|
tx_data[0] = 0x00;
|
||||||
|
tx_data[1] = save_type == CFG_SAVE_TYPE_EEPROM_4K ? SI_EEPROM_ID_4K : SI_EEPROM_ID_16K;
|
||||||
|
tx_data[2] = 0x00;
|
||||||
|
si_tx(tx_data, 3);
|
||||||
|
break;
|
||||||
|
case SI_CMD_EEPROM_READ:
|
||||||
|
data_offset = (uint32_t *) (&tx_data[0]);
|
||||||
|
data_offset[0] = swapb(save_data[0]);
|
||||||
|
data_offset[1] = swapb(save_data[1]);
|
||||||
|
si_tx(tx_data, 8);
|
||||||
|
break;
|
||||||
|
case SI_CMD_EEPROM_WRITE:
|
||||||
|
data_offset = (uint32_t *) (&rx_data[2]);
|
||||||
|
save_data[0] = swapb(data_offset[0]);
|
||||||
|
save_data[1] = swapb(data_offset[1]);
|
||||||
|
tx_data[0] = 0x00;
|
||||||
|
si_tx(tx_data, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rx_data[0]) {
|
||||||
|
case SI_CMD_RTC_STATUS:
|
||||||
|
tx_data[0] = 0x00;
|
||||||
|
tx_data[1] = 0x10;
|
||||||
|
tx_data[2] = 0x00;
|
||||||
|
si_tx(tx_data, 3);
|
||||||
|
break;
|
||||||
|
case SI_CMD_RTC_READ:
|
||||||
|
if (rx_data[1] == 0) {
|
||||||
|
tx_data[0] = 0x03;
|
||||||
|
tx_data[1] = 0x00;
|
||||||
|
tx_data[2] = 0x00;
|
||||||
|
tx_data[3] = 0x00;
|
||||||
|
tx_data[4] = 0x00;
|
||||||
|
tx_data[5] = 0x00;
|
||||||
|
tx_data[6] = 0x00;
|
||||||
|
tx_data[7] = 0x00;
|
||||||
|
} else {
|
||||||
|
tx_data[0] = 0x00;
|
||||||
|
tx_data[1] = 0x00;
|
||||||
|
tx_data[2] = 0x92;
|
||||||
|
tx_data[3] = 0x06;
|
||||||
|
tx_data[4] = 0x01;
|
||||||
|
tx_data[5] = 0x09;
|
||||||
|
tx_data[6] = 0x21;
|
||||||
|
tx_data[7] = 0x01;
|
||||||
|
}
|
||||||
|
tx_data[8] = 0x00;
|
||||||
|
si_tx(tx_data, 9);
|
||||||
|
break;
|
||||||
|
case SI_CMD_RTC_WRITE:
|
||||||
|
tx_data[0] = 0x00;
|
||||||
|
si_tx(tx_data, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
si_rx_reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool debug_decide (uint32_t *args) {
|
||||||
|
switch (args[0]) {
|
||||||
|
case DEBUG_WRITE_ADDRESS:
|
||||||
|
if (!n64_to_pc_pending) {
|
||||||
|
n64_to_pc_address = args[1];
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEBUG_WRITE_LENGTH_START:
|
||||||
|
if (!n64_to_pc_pending) {
|
||||||
|
n64_to_pc_length = args[1];
|
||||||
|
n64_to_pc_pending = true;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEBUG_WRITE_STATUS:
|
||||||
|
args[1] = n64_to_pc_pending;
|
||||||
|
break;
|
||||||
|
case DEBUG_READ_ARG:
|
||||||
|
args[1] = pc_to_n64_arg;
|
||||||
|
break;
|
||||||
|
case DEBUG_READ_LENGTH:
|
||||||
|
args[1] = pc_to_n64_length;
|
||||||
|
break;
|
||||||
|
case DEBUG_READ_ADDRESS_START:
|
||||||
|
if (!pc_to_n64_ready) {
|
||||||
|
pc_to_n64_ready = true;
|
||||||
|
pc_to_n64_address = args[1];
|
||||||
|
cfg_set_usb_waiting(false);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void config_update (uint32_t *args) {
|
void config_update (uint32_t *args) {
|
||||||
switch (args[0]) {
|
switch (args[0]) {
|
||||||
@ -204,6 +351,10 @@ void config_update (uint32_t *args) {
|
|||||||
break;
|
break;
|
||||||
case CONFIG_UPDATE_SAVE_TYPE:
|
case CONFIG_UPDATE_SAVE_TYPE:
|
||||||
save_type = args[1] & 0x07;
|
save_type = args[1] & 0x07;
|
||||||
|
eeprom_enabled = (
|
||||||
|
save_type == CFG_SAVE_TYPE_EEPROM_4K ||
|
||||||
|
save_type == CFG_SAVE_TYPE_EEPROM_16K
|
||||||
|
);
|
||||||
cfg_set_save_type(save_type);
|
cfg_set_save_type(save_type);
|
||||||
break;
|
break;
|
||||||
case CONFIG_UPDATE_CIC_SEED:
|
case CONFIG_UPDATE_CIC_SEED:
|
||||||
@ -215,15 +366,6 @@ void config_update (uint32_t *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CONFIG_QUERY_STATUS,
|
|
||||||
CONFIG_QUERY_SAVE_TYPE,
|
|
||||||
CONFIG_QUERY_CIC_SEED,
|
|
||||||
CONFIG_QUERY_TV_TYPE,
|
|
||||||
CONFIG_QUERY_SAVE_OFFSET,
|
|
||||||
CONFIG_QUERY_DD_OFFSET,
|
|
||||||
} e_config_query_t;
|
|
||||||
|
|
||||||
void config_query (uint32_t *args) {
|
void config_query (uint32_t *args) {
|
||||||
switch (args[0]) {
|
switch (args[0]) {
|
||||||
case CONFIG_QUERY_STATUS:
|
case CONFIG_QUERY_STATUS:
|
||||||
|
47
sw/riscv/src/controller.h
Normal file
47
sw/riscv/src/controller.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef CONTROLLER_H__
|
||||||
|
#define CONTROLLER_H__
|
||||||
|
|
||||||
|
|
||||||
|
#define USB_CMD_TOKEN (0x434D4400)
|
||||||
|
#define USB_CMP_TOKEN (0x434D5000)
|
||||||
|
#define USB_ERR_TOKEN (0x45525200)
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
USB_STATE_IDLE,
|
||||||
|
USB_STATE_ARGS,
|
||||||
|
USB_STATE_DATA,
|
||||||
|
USB_STATE_RESPONSE,
|
||||||
|
USB_STATE_N64_TO_PC,
|
||||||
|
USB_STATE_PC_TO_N64,
|
||||||
|
} e_usb_state_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DEBUG_WRITE_ADDRESS,
|
||||||
|
DEBUG_WRITE_LENGTH_START,
|
||||||
|
DEBUG_WRITE_STATUS,
|
||||||
|
DEBUG_READ_ARG,
|
||||||
|
DEBUG_READ_LENGTH,
|
||||||
|
DEBUG_READ_ADDRESS_START,
|
||||||
|
} e_debug_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CONFIG_UPDATE_SDRAM_SWITCH,
|
||||||
|
CONFIG_UPDATE_SDRAM_WRITABLE,
|
||||||
|
CONFIG_UPDATE_DD_ENABLE,
|
||||||
|
CONFIG_UPDATE_SAVE_TYPE,
|
||||||
|
CONFIG_UPDATE_CIC_SEED,
|
||||||
|
CONFIG_UPDATE_TV_TYPE
|
||||||
|
} e_config_update_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CONFIG_QUERY_STATUS,
|
||||||
|
CONFIG_QUERY_SAVE_TYPE,
|
||||||
|
CONFIG_QUERY_CIC_SEED,
|
||||||
|
CONFIG_QUERY_TV_TYPE,
|
||||||
|
CONFIG_QUERY_SAVE_OFFSET,
|
||||||
|
CONFIG_QUERY_DD_OFFSET,
|
||||||
|
} e_config_query_t;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -255,3 +255,79 @@ void cfg_set_response (uint32_t *args, bool error) {
|
|||||||
}
|
}
|
||||||
CFG->SCR &= ~(CFG_SCR_CPU_BUSY);
|
CFG->SCR &= ~(CFG_SCR_CPU_BUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SI
|
||||||
|
|
||||||
|
bool si_rx_ready (void) {
|
||||||
|
return SI->SCR & SI_SCR_RX_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool si_rx_stop_bit (void) {
|
||||||
|
return SI->SCR & SI_SCR_RX_STOP_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool si_tx_busy (void) {
|
||||||
|
return SI->SCR & SI_SCR_TX_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void si_rx_reset (void) {
|
||||||
|
SI->SCR = SI_SCR_RX_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
void si_reset (void) {
|
||||||
|
SI->SCR = SI_SCR_TX_RESET | SI_SCR_RX_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
void si_rx (uint8_t *data) {
|
||||||
|
uint32_t rx_length = (SI->SCR & SI_SCR_RX_LENGTH_MASK) >> SI_SCR_RX_LENGTH_BIT;
|
||||||
|
for (size_t i = 0; i < rx_length; i++) {
|
||||||
|
data[i] = ((uint8_t *) SI->DATA)[(10 - rx_length) + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void si_tx (uint8_t *data, size_t length) {
|
||||||
|
for (size_t i = 0; i < ((length + 3) / 4); i++) {
|
||||||
|
SI->DATA[i] = ((uint32_t *) data)[i];
|
||||||
|
}
|
||||||
|
SI->DATA[length / 4] |= (0x80 << ((length % 4) * 8));
|
||||||
|
SI->SCR = (((length * 8) + 1) << SI_SCR_TX_LENGTH_BIT) | SI_SCR_TX_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// misc
|
||||||
|
|
||||||
|
const char hex_char_map[16] = {
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||||
|
};
|
||||||
|
|
||||||
|
void print (const char *text) {
|
||||||
|
while (*text != '\0') {
|
||||||
|
while (!(UART->SCR & UART_SCR_TXE));
|
||||||
|
UART->DR = *text++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_02hex (uint8_t number) {
|
||||||
|
char buffer[3];
|
||||||
|
buffer[0] = hex_char_map[(number >> 4) & 0x0F];
|
||||||
|
buffer[1] = hex_char_map[number & 0x0F];
|
||||||
|
buffer[2] = '\0';
|
||||||
|
print(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_08hex (uint32_t number) {
|
||||||
|
print_02hex((number >> 24) & 0xFF);
|
||||||
|
print_02hex((number >> 16) & 0xFF);
|
||||||
|
print_02hex((number >> 8) & 0xFF);
|
||||||
|
print_02hex((number >> 0) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t swapb (uint32_t data) {
|
||||||
|
return (
|
||||||
|
(data << 24) |
|
||||||
|
((data << 8) & 0x00FF0000) |
|
||||||
|
((data >> 8) & 0x0000FF00) |
|
||||||
|
(data >> 24)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -92,4 +92,33 @@ bool cfg_get_command (uint8_t *cmd, uint32_t *args);
|
|||||||
void cfg_set_response (uint32_t *args, bool error);
|
void cfg_set_response (uint32_t *args, bool error);
|
||||||
|
|
||||||
|
|
||||||
|
// SI
|
||||||
|
|
||||||
|
#define SI_CMD_EEPROM_STATUS (0x00)
|
||||||
|
#define SI_CMD_EEPROM_READ (0x04)
|
||||||
|
#define SI_CMD_EEPROM_WRITE (0x05)
|
||||||
|
#define SI_CMD_RTC_STATUS (0x06)
|
||||||
|
#define SI_CMD_RTC_READ (0x07)
|
||||||
|
#define SI_CMD_RTC_WRITE (0x08)
|
||||||
|
|
||||||
|
#define SI_EEPROM_ID_4K (0x80)
|
||||||
|
#define SI_EEPROM_ID_16K (0xC0)
|
||||||
|
|
||||||
|
bool si_rx_ready (void);
|
||||||
|
bool si_rx_stop_bit (void);
|
||||||
|
bool si_tx_busy (void);
|
||||||
|
void si_rx_reset (void);
|
||||||
|
void si_reset (void);
|
||||||
|
void si_rx (uint8_t *data);
|
||||||
|
void si_tx (uint8_t *data, size_t length);
|
||||||
|
|
||||||
|
|
||||||
|
// misc
|
||||||
|
|
||||||
|
void print (const char *text);
|
||||||
|
void print_02hex (uint8_t number);
|
||||||
|
void print_08hex (uint32_t number);
|
||||||
|
uint32_t swapb (uint32_t data);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -137,4 +137,23 @@ typedef volatile struct flashram_regs {
|
|||||||
#define FLASHRAM_PAGE_BIT (8)
|
#define FLASHRAM_PAGE_BIT (8)
|
||||||
|
|
||||||
|
|
||||||
|
typedef volatile struct si_regs {
|
||||||
|
io32_t SCR;
|
||||||
|
io32_t DATA[3];
|
||||||
|
} si_regs_t;
|
||||||
|
|
||||||
|
#define SI_BASE (0xA0000000UL)
|
||||||
|
#define SI ((si_regs_t *) SI_BASE)
|
||||||
|
|
||||||
|
#define SI_SCR_RX_READY (1 << 0)
|
||||||
|
#define SI_SCR_RX_STOP_BIT (1 << 1)
|
||||||
|
#define SI_SCR_TX_START (1 << 2)
|
||||||
|
#define SI_SCR_TX_BUSY (1 << 3)
|
||||||
|
#define SI_SCR_RX_RESET (1 << 6)
|
||||||
|
#define SI_SCR_TX_RESET (1 << 7)
|
||||||
|
#define SI_SCR_RX_LENGTH_BIT (8)
|
||||||
|
#define SI_SCR_RX_LENGTH_MASK (0x7F << SI_SCR_RX_LENGTH_BIT)
|
||||||
|
#define SI_SCR_TX_LENGTH_BIT (16)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user