mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-02-05 23:54:41 +00:00
C64: update mist_io
for synchronizing SPI_SCK->clk_sys
This commit is contained in:
@@ -155,6 +155,7 @@ end function;
|
||||
component mist_io generic(STRLEN : integer := 0 ); port
|
||||
(
|
||||
clk_sys : in std_logic;
|
||||
clk_sd : in std_logic;
|
||||
|
||||
SPI_SCK : in std_logic;
|
||||
CONF_DATA0 : in std_logic;
|
||||
@@ -509,6 +510,7 @@ begin
|
||||
generic map (STRLEN => CONF_STR'length)
|
||||
port map (
|
||||
clk_sys => clk32,
|
||||
clk_sd => clk32,
|
||||
|
||||
SPI_SCK => SPI_SCK,
|
||||
CONF_DATA0 => CONF_DATA0,
|
||||
|
||||
@@ -38,6 +38,7 @@ module mist_io #(parameter STRLEN=0, parameter PS2DIV=100)
|
||||
|
||||
// Global clock. It should be around 100MHz (higher is better).
|
||||
input clk_sys,
|
||||
input clk_sd,
|
||||
|
||||
// Global SPI clock from ARM. 24MHz
|
||||
input SPI_SCK,
|
||||
@@ -61,7 +62,7 @@ module mist_io #(parameter STRLEN=0, parameter PS2DIV=100)
|
||||
// SD config
|
||||
input sd_conf,
|
||||
input sd_sdhc,
|
||||
output img_mounted, // signaling that new image has been mounted
|
||||
output reg img_mounted, // signaling that new image has been mounted
|
||||
output reg [31:0] img_size, // size of image in bytes
|
||||
|
||||
// SD block level access
|
||||
@@ -75,7 +76,7 @@ module mist_io #(parameter STRLEN=0, parameter PS2DIV=100)
|
||||
output reg [8:0] sd_buff_addr,
|
||||
output reg [7:0] sd_buff_dout,
|
||||
input [7:0] sd_buff_din,
|
||||
output reg sd_buff_wr,
|
||||
output sd_buff_wr,
|
||||
|
||||
// ps2 keyboard emulation
|
||||
output ps2_kbd_clk,
|
||||
@@ -94,201 +95,48 @@ module mist_io #(parameter STRLEN=0, parameter PS2DIV=100)
|
||||
output reg [7:0] ioctl_dout
|
||||
);
|
||||
|
||||
reg [7:0] b_data;
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
|
||||
reg [9:0] byte_cnt; // counts bytes
|
||||
reg [7:0] but_sw;
|
||||
reg [2:0] stick_idx;
|
||||
|
||||
reg mount_strobe = 0;
|
||||
assign img_mounted = mount_strobe;
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
|
||||
reg [7:0] byte_cnt; // counts bytes
|
||||
reg [5:0] joystick0;
|
||||
reg [5:0] joystick1;
|
||||
reg [7:0] but_sw;
|
||||
reg [2:0] stick_idx;
|
||||
|
||||
assign buttons = but_sw[1:0];
|
||||
assign switches = but_sw[3:2];
|
||||
assign scandoubler_disable = but_sw[4];
|
||||
assign ypbpr = but_sw[5];
|
||||
|
||||
wire [7:0] spi_dout = { sbuf, SPI_DI};
|
||||
|
||||
// this variant of user_io is for 8 bit cores (type == a4) only
|
||||
wire [7:0] core_type = 8'ha4;
|
||||
|
||||
// command byte read by the io controller
|
||||
wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd };
|
||||
|
||||
wire spi_sck = SPI_SCK;
|
||||
|
||||
reg spi_do;
|
||||
assign SPI_DO = CONF_DATA0 ? 1'bZ : spi_do;
|
||||
|
||||
wire [7:0] kbd_led = { 2'b01, 4'b0000, ps2_caps_led, 1'b1};
|
||||
// ---------------- PS2 ---------------------
|
||||
|
||||
// drive MISO only when transmitting core id
|
||||
always@(negedge SPI_SCK) begin
|
||||
if(!CONF_DATA0) begin
|
||||
// first byte returned is always core type, further bytes are
|
||||
// command dependent
|
||||
if(byte_cnt == 0) begin
|
||||
spi_do <= core_type[~bit_cnt];
|
||||
|
||||
end else begin
|
||||
case(cmd)
|
||||
// reading config string
|
||||
8'h14: begin
|
||||
// returning a byte from string
|
||||
if(byte_cnt < STRLEN + 1) spi_do <= conf_str[{STRLEN - byte_cnt,~bit_cnt}];
|
||||
else spi_do <= 0;
|
||||
end
|
||||
|
||||
// reading sd card status
|
||||
8'h16: begin
|
||||
if(byte_cnt == 1) spi_do <= sd_cmd[~bit_cnt];
|
||||
else if((byte_cnt >= 2) && (byte_cnt < 6)) spi_do <= sd_lba[{5-byte_cnt, ~bit_cnt}];
|
||||
else spi_do <= 0;
|
||||
end
|
||||
|
||||
// reading sd card write data
|
||||
8'h18:
|
||||
spi_do <= b_data[~bit_cnt];
|
||||
|
||||
// reading keyboard LED status
|
||||
8'h1f:
|
||||
spi_do <= kbd_led[~bit_cnt];
|
||||
|
||||
default:
|
||||
spi_do <= 0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg b_wr2,b_wr3;
|
||||
always @(negedge clk_sys) begin
|
||||
b_wr3 <= b_wr2;
|
||||
sd_buff_wr <= b_wr3;
|
||||
end
|
||||
|
||||
// SPI receiver
|
||||
always@(posedge SPI_SCK or posedge CONF_DATA0) begin
|
||||
|
||||
if(CONF_DATA0) begin
|
||||
b_wr2 <= 0;
|
||||
bit_cnt <= 0;
|
||||
byte_cnt <= 0;
|
||||
sd_ack <= 0;
|
||||
sd_ack_conf <= 0;
|
||||
end else begin
|
||||
b_wr2 <= 0;
|
||||
|
||||
sbuf <= spi_dout[6:0];
|
||||
bit_cnt <= bit_cnt + 1'd1;
|
||||
if(bit_cnt == 5) begin
|
||||
if (byte_cnt == 0) sd_buff_addr <= 0;
|
||||
if((byte_cnt != 0) & (sd_buff_addr != 511)) sd_buff_addr <= sd_buff_addr + 1'b1;
|
||||
if((byte_cnt == 1) & ((cmd == 8'h17) | (cmd == 8'h19))) sd_buff_addr <= 0;
|
||||
end
|
||||
|
||||
// finished reading command byte
|
||||
if(bit_cnt == 7) begin
|
||||
if(~&byte_cnt) byte_cnt <= byte_cnt + 8'd1;
|
||||
if(byte_cnt == 0) begin
|
||||
cmd <= spi_dout;
|
||||
|
||||
if(spi_dout == 8'h19) begin
|
||||
sd_ack_conf <= 1;
|
||||
sd_buff_addr <= 0;
|
||||
end
|
||||
if((spi_dout == 8'h17) || (spi_dout == 8'h18)) begin
|
||||
sd_ack <= 1;
|
||||
sd_buff_addr <= 0;
|
||||
end
|
||||
if(spi_dout == 8'h18) b_data <= sd_buff_din;
|
||||
|
||||
mount_strobe <= 0;
|
||||
|
||||
end else begin
|
||||
|
||||
case(cmd)
|
||||
// buttons and switches
|
||||
8'h01: but_sw <= spi_dout;
|
||||
8'h02: joystick_0 <= spi_dout;
|
||||
8'h03: joystick_1 <= spi_dout;
|
||||
|
||||
// store incoming ps2 mouse bytes
|
||||
8'h04: begin
|
||||
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_dout;
|
||||
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
|
||||
end
|
||||
|
||||
// store incoming ps2 keyboard bytes
|
||||
8'h05: begin
|
||||
ps2_kbd_fifo[ps2_kbd_wptr] <= spi_dout;
|
||||
ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1;
|
||||
end
|
||||
|
||||
8'h15: status[7:0] <= spi_dout;
|
||||
|
||||
// send SD config IO -> FPGA
|
||||
// flag that download begins
|
||||
// sd card knows data is config if sd_dout_strobe is asserted
|
||||
// with sd_ack still being inactive (low)
|
||||
8'h19,
|
||||
// send sector IO -> FPGA
|
||||
// flag that download begins
|
||||
8'h17: begin
|
||||
sd_buff_dout <= spi_dout;
|
||||
b_wr2 <= 1;
|
||||
end
|
||||
|
||||
8'h18: b_data <= sd_buff_din;
|
||||
|
||||
// joystick analog
|
||||
8'h1a: begin
|
||||
// first byte is joystick index
|
||||
if(byte_cnt == 1) stick_idx <= spi_dout[2:0];
|
||||
else if(byte_cnt == 2) begin
|
||||
// second byte is x axis
|
||||
if(stick_idx == 0) joystick_analog_0[15:8] <= spi_dout;
|
||||
else if(stick_idx == 1) joystick_analog_1[15:8] <= spi_dout;
|
||||
end else if(byte_cnt == 3) begin
|
||||
// third byte is y axis
|
||||
if(stick_idx == 0) joystick_analog_0[7:0] <= spi_dout;
|
||||
else if(stick_idx == 1) joystick_analog_1[7:0] <= spi_dout;
|
||||
end
|
||||
end
|
||||
|
||||
// notify image selection
|
||||
8'h1c: mount_strobe <= 1;
|
||||
|
||||
// send image info
|
||||
8'h1d: if(byte_cnt<5) img_size[(byte_cnt-1)<<3 +:8] <= spi_dout;
|
||||
|
||||
// status, 32bit version
|
||||
8'h1e: if(byte_cnt<5) status[(byte_cnt-1)<<3 +:8] <= spi_dout;
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/////////////////////////////// PS2 ///////////////////////////////
|
||||
// 8 byte fifos to store ps2 bytes
|
||||
localparam PS2_FIFO_BITS = 3;
|
||||
|
||||
reg clk_ps2;
|
||||
reg ps2_clk;
|
||||
always @(negedge clk_sys) begin
|
||||
integer cnt;
|
||||
cnt <= cnt + 1'd1;
|
||||
if(cnt == PS2DIV) begin
|
||||
clk_ps2 <= ~clk_ps2;
|
||||
cnt <= 0;
|
||||
end
|
||||
integer cnt;
|
||||
cnt <= cnt + 1'd1;
|
||||
if(cnt == PS2DIV) begin
|
||||
ps2_clk <= ~ps2_clk;
|
||||
cnt <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// keyboard
|
||||
reg [7:0] ps2_kbd_fifo[1<<PS2_FIFO_BITS];
|
||||
reg [7:0] ps2_kbd_fifo [(2**PS2_FIFO_BITS)-1:0];
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr;
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr;
|
||||
|
||||
@@ -297,18 +145,20 @@ reg [3:0] ps2_kbd_tx_state;
|
||||
reg [7:0] ps2_kbd_tx_byte;
|
||||
reg ps2_kbd_parity;
|
||||
|
||||
assign ps2_kbd_clk = clk_ps2 || (ps2_kbd_tx_state == 0);
|
||||
assign ps2_kbd_clk = ps2_clk || (ps2_kbd_tx_state == 0);
|
||||
|
||||
// ps2 transmitter
|
||||
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
|
||||
reg ps2_kbd_r_inc;
|
||||
always@(posedge clk_sys) begin
|
||||
reg old_clk;
|
||||
old_clk <= clk_ps2;
|
||||
if(~old_clk & clk_ps2) begin
|
||||
ps2_kbd_r_inc <= 0;
|
||||
reg ps2_clkD;
|
||||
|
||||
if(ps2_kbd_r_inc) ps2_kbd_rptr <= ps2_kbd_rptr + 1'd1;
|
||||
ps2_clkD <= ps2_clk;
|
||||
if (~ps2_clkD & ps2_clk) begin
|
||||
ps2_kbd_r_inc <= 1'b0;
|
||||
|
||||
if(ps2_kbd_r_inc)
|
||||
ps2_kbd_rptr <= ps2_kbd_rptr + 1'd1;
|
||||
|
||||
// transmitter is idle?
|
||||
if(ps2_kbd_tx_state == 0) begin
|
||||
@@ -316,42 +166,46 @@ always@(posedge clk_sys) begin
|
||||
if(ps2_kbd_wptr != ps2_kbd_rptr) begin
|
||||
// load tx register from fifo
|
||||
ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr];
|
||||
ps2_kbd_r_inc <= 1;
|
||||
ps2_kbd_r_inc <= 1'b1;
|
||||
|
||||
// reset parity
|
||||
ps2_kbd_parity <= 1;
|
||||
ps2_kbd_parity <= 1'b1;
|
||||
|
||||
// start transmitter
|
||||
ps2_kbd_tx_state <= 1;
|
||||
ps2_kbd_tx_state <= 4'd1;
|
||||
|
||||
// put start bit on data line
|
||||
ps2_kbd_data <= 0; // start bit is 0
|
||||
ps2_kbd_data <= 1'b0; // start bit is 0
|
||||
end
|
||||
end else begin
|
||||
|
||||
// transmission of 8 data bits
|
||||
if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin
|
||||
ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits
|
||||
ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits
|
||||
ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down
|
||||
if(ps2_kbd_tx_byte[0])
|
||||
ps2_kbd_parity <= !ps2_kbd_parity;
|
||||
end
|
||||
|
||||
// transmission of parity
|
||||
if(ps2_kbd_tx_state == 9) ps2_kbd_data <= ps2_kbd_parity;
|
||||
|
||||
if(ps2_kbd_tx_state == 9)
|
||||
ps2_kbd_data <= ps2_kbd_parity;
|
||||
|
||||
// transmission of stop bit
|
||||
if(ps2_kbd_tx_state == 10) ps2_kbd_data <= 1; // stop bit is 1
|
||||
if(ps2_kbd_tx_state == 10)
|
||||
ps2_kbd_data <= 1'b1; // stop bit is 1
|
||||
|
||||
// advance state machine
|
||||
if(ps2_kbd_tx_state < 11) ps2_kbd_tx_state <= ps2_kbd_tx_state + 1'd1;
|
||||
else ps2_kbd_tx_state <= 0;
|
||||
if(ps2_kbd_tx_state < 11)
|
||||
ps2_kbd_tx_state <= ps2_kbd_tx_state + 4'd1;
|
||||
else
|
||||
ps2_kbd_tx_state <= 4'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// mouse
|
||||
reg [7:0] ps2_mouse_fifo[1<<PS2_FIFO_BITS];
|
||||
reg [7:0] ps2_mouse_fifo [(2**PS2_FIFO_BITS)-1:0];
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr;
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr;
|
||||
|
||||
@@ -360,18 +214,20 @@ reg [3:0] ps2_mouse_tx_state;
|
||||
reg [7:0] ps2_mouse_tx_byte;
|
||||
reg ps2_mouse_parity;
|
||||
|
||||
assign ps2_mouse_clk = clk_ps2 || (ps2_mouse_tx_state == 0);
|
||||
assign ps2_mouse_clk = ps2_clk || (ps2_mouse_tx_state == 0);
|
||||
|
||||
// ps2 transmitter
|
||||
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
|
||||
reg ps2_mouse_r_inc;
|
||||
always@(posedge clk_sys) begin
|
||||
reg old_clk;
|
||||
old_clk <= clk_ps2;
|
||||
if(~old_clk & clk_ps2) begin
|
||||
ps2_mouse_r_inc <= 0;
|
||||
reg ps2_clkD;
|
||||
|
||||
if(ps2_mouse_r_inc) ps2_mouse_rptr <= ps2_mouse_rptr + 1'd1;
|
||||
ps2_clkD <= ps2_clk;
|
||||
if (~ps2_clkD & ps2_clk) begin
|
||||
ps2_mouse_r_inc <= 1'b0;
|
||||
|
||||
if(ps2_mouse_r_inc)
|
||||
ps2_mouse_rptr <= ps2_mouse_rptr + 1'd1;
|
||||
|
||||
// transmitter is idle?
|
||||
if(ps2_mouse_tx_state == 0) begin
|
||||
@@ -379,16 +235,16 @@ always@(posedge clk_sys) begin
|
||||
if(ps2_mouse_wptr != ps2_mouse_rptr) begin
|
||||
// load tx register from fifo
|
||||
ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr];
|
||||
ps2_mouse_r_inc <= 1;
|
||||
ps2_mouse_r_inc <= 1'b1;
|
||||
|
||||
// reset parity
|
||||
ps2_mouse_parity <= 1;
|
||||
ps2_mouse_parity <= 1'b1;
|
||||
|
||||
// start transmitter
|
||||
ps2_mouse_tx_state <= 1;
|
||||
ps2_mouse_tx_state <= 4'd1;
|
||||
|
||||
// put start bit on data line
|
||||
ps2_mouse_data <= 0; // start bit is 0
|
||||
ps2_mouse_data <= 1'b0; // start bit is 0
|
||||
end
|
||||
end else begin
|
||||
|
||||
@@ -401,14 +257,298 @@ always@(posedge clk_sys) begin
|
||||
end
|
||||
|
||||
// transmission of parity
|
||||
if(ps2_mouse_tx_state == 9) ps2_mouse_data <= ps2_mouse_parity;
|
||||
if(ps2_mouse_tx_state == 9)
|
||||
ps2_mouse_data <= ps2_mouse_parity;
|
||||
|
||||
// transmission of stop bit
|
||||
if(ps2_mouse_tx_state == 10) ps2_mouse_data <= 1; // stop bit is 1
|
||||
if(ps2_mouse_tx_state == 10)
|
||||
ps2_mouse_data <= 1'b1; // stop bit is 1
|
||||
|
||||
// advance state machine
|
||||
if(ps2_mouse_tx_state < 11) ps2_mouse_tx_state <= ps2_mouse_tx_state + 1'd1;
|
||||
else ps2_mouse_tx_state <= 0;
|
||||
if(ps2_mouse_tx_state < 11)
|
||||
ps2_mouse_tx_state <= ps2_mouse_tx_state + 4'd1;
|
||||
else
|
||||
ps2_mouse_tx_state <= 4'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// fifo to receive serial data from core to be forwarded to io controller
|
||||
|
||||
// 16 byte fifo to store serial bytes
|
||||
localparam SERIAL_OUT_FIFO_BITS = 6;
|
||||
reg [7:0] serial_out_fifo [(2**SERIAL_OUT_FIFO_BITS)-1:0];
|
||||
reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_wptr;
|
||||
reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_rptr;
|
||||
|
||||
wire serial_out_data_available = serial_out_wptr != serial_out_rptr;
|
||||
wire [7:0] serial_out_byte = serial_out_fifo[serial_out_rptr] /* synthesis keep */;
|
||||
wire [7:0] serial_out_status = { 7'b1000000, serial_out_data_available};
|
||||
/*
|
||||
// status[0] is reset signal from io controller and is thus used to flush
|
||||
// the fifo
|
||||
always @(posedge serial_strobe or posedge status[0]) begin
|
||||
if(status[0] == 1) begin
|
||||
serial_out_wptr <= 0;
|
||||
end else begin
|
||||
serial_out_fifo[serial_out_wptr] <= serial_data;
|
||||
serial_out_wptr <= serial_out_wptr + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always@(negedge spi_sck or posedge status[0]) begin
|
||||
if(status[0] == 1) begin
|
||||
serial_out_rptr <= 0;
|
||||
end else begin
|
||||
if((byte_cnt != 0) && (cmd == 8'h1b)) begin
|
||||
// read last bit -> advance read pointer
|
||||
if((bit_cnt == 7) && !byte_cnt[0] && serial_out_data_available)
|
||||
serial_out_rptr <= serial_out_rptr + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
// SPI bit and byte counters
|
||||
always@(posedge spi_sck or posedge CONF_DATA0) begin
|
||||
if(CONF_DATA0 == 1) begin
|
||||
bit_cnt <= 0;
|
||||
byte_cnt <= 0;
|
||||
end else begin
|
||||
if((bit_cnt == 7)&&(byte_cnt != 8'd255))
|
||||
byte_cnt <= byte_cnt + 8'd1;
|
||||
|
||||
bit_cnt <= bit_cnt + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
// SPI transmitter FPGA -> IO
|
||||
reg [7:0] spi_byte_out;
|
||||
|
||||
always@(negedge spi_sck or posedge CONF_DATA0) begin
|
||||
spi_do <= spi_byte_out[~bit_cnt];
|
||||
end
|
||||
|
||||
always@(posedge spi_sck or posedge CONF_DATA0) begin
|
||||
reg [31:0] sd_lba_r;
|
||||
|
||||
if(CONF_DATA0 == 1) begin
|
||||
spi_byte_out <= core_type;
|
||||
end else begin
|
||||
// read the command byte to choose the response
|
||||
if(bit_cnt == 7) begin
|
||||
if(!byte_cnt) cmd <= {sbuf, SPI_DI};
|
||||
|
||||
spi_byte_out <= 0;
|
||||
case({(!byte_cnt) ? {sbuf, SPI_DI} : cmd})
|
||||
// reading config string
|
||||
8'h14: if(byte_cnt < STRLEN) spi_byte_out <= conf_str[(STRLEN - byte_cnt - 1)<<3 +:8];
|
||||
|
||||
// reading sd card status
|
||||
8'h16: if(byte_cnt == 0) begin
|
||||
spi_byte_out <= sd_cmd;
|
||||
sd_lba_r <= sd_lba;
|
||||
end
|
||||
else if(byte_cnt < 5) spi_byte_out <= sd_lba_r[(4-byte_cnt)<<3 +:8];
|
||||
|
||||
// reading sd card write data
|
||||
8'h18: spi_byte_out <= sd_buff_din;
|
||||
8'h1b:
|
||||
// send alternating flag byte and data
|
||||
if(byte_cnt[0]) spi_byte_out <= serial_out_status;
|
||||
else spi_byte_out <= serial_out_byte;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// SPI receiver IO -> FPGA
|
||||
|
||||
reg spi_receiver_strobe_r;
|
||||
reg spi_transfer_end_r;
|
||||
reg [7:0] spi_byte_in_r;
|
||||
|
||||
// Read at spi_sck clock domain, assemble bytes for transferring to clk_sys
|
||||
always@(posedge spi_sck or posedge CONF_DATA0) begin
|
||||
|
||||
if(CONF_DATA0 == 1) begin
|
||||
spi_receiver_strobe_r <= 0;
|
||||
spi_transfer_end_r <= 1;
|
||||
end else begin
|
||||
spi_receiver_strobe_r <= 0;
|
||||
spi_transfer_end_r <= 0;
|
||||
|
||||
if(bit_cnt != 7)
|
||||
sbuf[6:0] <= { sbuf[5:0], SPI_DI };
|
||||
|
||||
// finished reading a byte, prepare to transfer to clk_sys
|
||||
if(bit_cnt == 7) begin
|
||||
spi_byte_in_r <= { sbuf, SPI_DI};
|
||||
spi_receiver_strobe_r <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Process bytes from SPI at the clk_sys domain
|
||||
always @(posedge clk_sys) begin
|
||||
|
||||
reg spi_receiver_strobe;
|
||||
reg spi_transfer_end;
|
||||
reg [7:0] spi_byte_in;
|
||||
reg spi_receiver_strobeD;
|
||||
reg spi_transfer_endD;
|
||||
reg [7:0] spi_byte_inD;
|
||||
reg [7:0] acmd;
|
||||
reg [7:0] abyte_cnt; // counts bytes
|
||||
|
||||
//synchronize between SPI and sys clock domains
|
||||
spi_receiver_strobeD <= spi_receiver_strobe_r;
|
||||
spi_receiver_strobe <= spi_receiver_strobeD;
|
||||
spi_transfer_endD <= spi_transfer_end_r;
|
||||
spi_transfer_end <= spi_transfer_endD;
|
||||
spi_byte_inD <= spi_byte_in_r;
|
||||
spi_byte_in <= spi_byte_inD;
|
||||
|
||||
if (~spi_transfer_endD & spi_transfer_end) begin
|
||||
abyte_cnt <= 8'd0;
|
||||
end else if (~spi_receiver_strobeD & spi_receiver_strobe) begin
|
||||
|
||||
if(abyte_cnt != 8'd255)
|
||||
abyte_cnt <= byte_cnt + 8'd1;
|
||||
|
||||
if(abyte_cnt == 0) begin
|
||||
acmd <= spi_byte_in;
|
||||
end else begin
|
||||
case(acmd)
|
||||
// buttons and switches
|
||||
8'h01: but_sw <= spi_byte_in;
|
||||
8'h02: joystick_0 <= spi_byte_in;
|
||||
8'h03: joystick_1 <= spi_byte_in;
|
||||
8'h04: begin
|
||||
// store incoming ps2 mouse bytes
|
||||
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_byte_in;
|
||||
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
|
||||
end
|
||||
8'h05: begin
|
||||
// store incoming ps2 keyboard bytes
|
||||
ps2_kbd_fifo[ps2_kbd_wptr] <= spi_byte_in;
|
||||
ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1;
|
||||
end
|
||||
|
||||
// joystick analog
|
||||
8'h1a: begin
|
||||
// first byte is joystick indes
|
||||
if(abyte_cnt == 1)
|
||||
stick_idx <= spi_byte_in[2:0];
|
||||
else if(abyte_cnt == 2) begin
|
||||
// second byte is x axis
|
||||
if(stick_idx == 0)
|
||||
joystick_analog_0[15:8] <= spi_byte_in;
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[15:8] <= spi_byte_in;
|
||||
end else if(abyte_cnt == 3) begin
|
||||
// third byte is y axis
|
||||
if(stick_idx == 0)
|
||||
joystick_analog_0[7:0] <= spi_byte_in;
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[7:0] <= spi_byte_in;
|
||||
end
|
||||
end
|
||||
|
||||
8'h15: status <= spi_byte_in;
|
||||
|
||||
// status, 32bit version
|
||||
8'h1e: if(abyte_cnt<6) status[(abyte_cnt-2)<<3 +:8] <= spi_byte_in;
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg sd_din_strobe;
|
||||
reg sd_dout_strobe;
|
||||
assign sd_buff_wr = sd_dout_strobe;
|
||||
|
||||
// Process SD-card related bytes from SPI at the clk_sd domain
|
||||
always @(posedge clk_sd) begin
|
||||
|
||||
reg spi_receiver_strobe;
|
||||
reg spi_transfer_end;
|
||||
reg [7:0] spi_byte_in;
|
||||
reg spi_receiver_strobeD;
|
||||
reg spi_transfer_endD;
|
||||
reg [7:0] spi_byte_inD;
|
||||
reg [7:0] acmd;
|
||||
reg [7:0] abyte_cnt; // counts bytes
|
||||
|
||||
//synchronize between SPI and sd clock domains
|
||||
spi_receiver_strobeD <= spi_receiver_strobe_r;
|
||||
spi_receiver_strobe <= spi_receiver_strobeD;
|
||||
spi_transfer_endD <= spi_transfer_end_r;
|
||||
spi_transfer_end <= spi_transfer_endD;
|
||||
spi_byte_inD <= spi_byte_in_r;
|
||||
spi_byte_in <= spi_byte_inD;
|
||||
|
||||
if(sd_dout_strobe) begin
|
||||
sd_dout_strobe<= 0;
|
||||
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
|
||||
end
|
||||
|
||||
if(sd_din_strobe) begin
|
||||
sd_din_strobe<= 0;
|
||||
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
|
||||
end
|
||||
|
||||
img_mounted <= 0;
|
||||
|
||||
if (~spi_transfer_endD & spi_transfer_end) begin
|
||||
abyte_cnt <= 8'd0;
|
||||
sd_ack <= 1'b0;
|
||||
sd_ack_conf <= 1'b0;
|
||||
sd_dout_strobe <= 1'b0;
|
||||
sd_din_strobe <= 1'b0;
|
||||
sd_buff_addr<= 0;
|
||||
end else if (~spi_receiver_strobeD & spi_receiver_strobe) begin
|
||||
|
||||
if(abyte_cnt != 8'd255)
|
||||
abyte_cnt <= byte_cnt + 8'd1;
|
||||
|
||||
if(abyte_cnt == 0) begin
|
||||
acmd <= spi_byte_in;
|
||||
|
||||
// fetch first byte when sectore FPGA->IO command has been seen
|
||||
if(spi_byte_in == 8'h18)
|
||||
sd_din_strobe <= 1'b1;
|
||||
|
||||
if((spi_byte_in == 8'h17) || (spi_byte_in == 8'h18))
|
||||
sd_ack <= 1'b1;
|
||||
|
||||
end else begin
|
||||
case(acmd)
|
||||
|
||||
// send sector IO -> FPGA
|
||||
8'h17: begin
|
||||
// flag that download begins
|
||||
sd_dout_strobe <= 1'b1;
|
||||
sd_buff_dout <= spi_byte_in;
|
||||
end
|
||||
|
||||
// send sector FPGA -> IO
|
||||
8'h18: sd_din_strobe <= 1'b1;
|
||||
|
||||
// send SD config IO -> FPGA
|
||||
8'h19: begin
|
||||
// flag that download begins
|
||||
sd_dout_strobe <= 1'b1;
|
||||
sd_ack_conf <= 1'b1;
|
||||
sd_buff_dout <= spi_byte_in;
|
||||
end
|
||||
|
||||
8'h1c: img_mounted <= 1;
|
||||
|
||||
// send image info
|
||||
8'h1d: if(abyte_cnt<6) img_size[(byte_cnt-2)<<3 +:8] <= spi_byte_in;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user