Skip to content

Commit

Permalink
Update user_io
Browse files Browse the repository at this point in the history
  • Loading branch information
gyurco committed Feb 11, 2019
1 parent e21a405 commit 0226b2c
Showing 1 changed file with 116 additions and 95 deletions.
211 changes: 116 additions & 95 deletions user_io.v
Original file line number Diff line number Diff line change
Expand Up @@ -25,58 +25,65 @@
module user_io #(parameter STRLEN=0, parameter PS2DIV=100) (
input [(8*STRLEN)-1:0] conf_str,

input clk_sys, // clock for system-related messages (kbd, joy, etc...)
input clk_sd, // clock for SD-card related messages

input SPI_CLK,
input SPI_SS_IO,
output reg SPI_MISO,
input SPI_MOSI,

output reg [7:0] joystick_0,
output reg [7:0] joystick_1,
output reg [15:0] joystick_analog_0,
output reg [15:0] joystick_analog_1,
output [1:0] buttons,
output [1:0] switches,
output scandoubler_disable,
output ypbpr,
output reg [31:0] status,
input clk_sys, // clock for system-related messages (kbd, joy, etc...)
input clk_sd, // clock for SD-card related messages

input SPI_CLK,
input SPI_SS_IO,
output reg SPI_MISO,
input SPI_MOSI,

output reg [31:0] joystick_0,
output reg [31:0] joystick_1,
output reg [31:0] joystick_2,
output reg [31:0] joystick_3,
output reg [31:0] joystick_4,
output reg [15:0] joystick_analog_0,
output reg [15:0] joystick_analog_1,
output [1:0] buttons,
output [1:0] switches,
output scandoubler_disable,
output ypbpr,
output reg [31:0] status,

// connection to sd card emulation
input [31:0] sd_lba,
input sd_rd,
input sd_wr,
output reg sd_ack,
output reg sd_ack_conf,
input sd_conf,
input sd_sdhc,
output reg [7:0] sd_dout, // valid on rising edge of sd_dout_strobe
output reg sd_dout_strobe,
input [7:0] sd_din,
output reg sd_din_strobe,
output reg [8:0] sd_buff_addr,

output reg img_mounted, //rising edge if a new image is mounted
output reg [31:0] img_size, // size of image in bytes

// ps2 keyboard emulation
output ps2_kbd_clk,
output reg ps2_kbd_data,
output ps2_mouse_clk,
output reg ps2_mouse_data,
input [31:0] sd_lba,
input sd_rd,
input sd_wr,
output reg sd_ack,
output reg sd_ack_conf,
input sd_conf,
input sd_sdhc,
output reg [7:0] sd_dout, // valid on rising edge of sd_dout_strobe
output reg sd_dout_strobe,
input [7:0] sd_din,
output reg sd_din_strobe,
output reg [8:0] sd_buff_addr,

output reg img_mounted, //rising edge if a new image is mounted
output reg [31:0] img_size, // size of image in bytes

// ps2 keyboard/mouse emulation
output ps2_kbd_clk,
output reg ps2_kbd_data,
output ps2_mouse_clk,
output reg ps2_mouse_data,

// mouse data
output reg [7:0] mouse_x,
output reg [7:0] mouse_y,
output reg [7:0] mouse_flags, // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
output reg mouse_strobe, // mouse data is valid on mouse_strobe

// serial com port
input [7:0] serial_data,
input serial_strobe
input [7:0] serial_data,
input serial_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 [9:0] byte_cnt; // counts bytes
reg [7:0] but_sw;
reg [2:0] stick_idx;

Expand Down Expand Up @@ -285,9 +292,9 @@ end
always@(posedge spi_sck or posedge SPI_SS_IO) begin
if(SPI_SS_IO == 1) begin
bit_cnt <= 0;
byte_cnt <= 0;
byte_cnt <= 0;
end else begin
if((bit_cnt == 7)&&(byte_cnt != 8'd255))
if((bit_cnt == 7)&&(~&byte_cnt))
byte_cnt <= byte_cnt + 8'd1;

bit_cnt <= bit_cnt + 1'd1;
Expand All @@ -307,60 +314,58 @@ end

always@(posedge spi_sck or posedge SPI_SS_IO) begin
reg [31:0] sd_lba_r;

if(SPI_SS_IO == 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_MOSI};

spi_byte_out <= 0;
case({(!byte_cnt) ? {sbuf, SPI_MOSI} : cmd})
// reading config string
8'h14: if(byte_cnt < STRLEN) spi_byte_out <= conf_str[(STRLEN - byte_cnt - 1)<<3 +:8];
spi_byte_out <= 0;
case({(!byte_cnt) ? {sbuf, SPI_MOSI} : 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
// 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_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;
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_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;
reg spi_receiver_strobe_r = 0;
reg spi_transfer_end_r = 1;
reg [7:0] spi_byte_in;

// Read at spi_sck clock domain, assemble bytes for transferring to clk_sys
always@(posedge spi_sck or posedge SPI_SS_IO) begin

if(SPI_SS_IO == 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_MOSI };

// finished reading a byte, prepare to transfer to clk_sys
if(bit_cnt == 7) begin
spi_byte_in_r <= { sbuf, SPI_MOSI};
spi_receiver_strobe_r <= 1;
if(bit_cnt == 7) begin
spi_byte_in <= { sbuf, SPI_MOSI};
spi_receiver_strobe_r <= ~spi_receiver_strobe_r;
end
end
end
Expand All @@ -370,40 +375,52 @@ 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

reg [7:0] mouse_flags_r;
reg [7:0] mouse_x_r;

//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;

mouse_strobe <= 0;

if (~spi_transfer_endD & spi_transfer_end) begin
abyte_cnt <= 8'd0;
end else if (~spi_receiver_strobeD & spi_receiver_strobe) begin
end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin

if(abyte_cnt != 8'd255)
abyte_cnt <= byte_cnt + 8'd1;
if(~&abyte_cnt)
abyte_cnt <= abyte_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'h60: if (abyte_cnt < 5) joystick_0[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h61: if (abyte_cnt < 5) joystick_1[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h62: if (abyte_cnt < 5) joystick_2[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h63: if (abyte_cnt < 5) joystick_3[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h64: if (abyte_cnt < 5) joystick_4[(abyte_cnt-1)<<3 +:8] <= 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;
if (abyte_cnt == 1) mouse_flags_r <= spi_byte_in;
else if (abyte_cnt == 2) mouse_x_r <= spi_byte_in;
else if (abyte_cnt == 3) begin
mouse_flags <= mouse_flags_r;
mouse_x <= mouse_x_r;
mouse_y <= spi_byte_in;
mouse_strobe <= 1;
end
end
8'h05: begin
// store incoming ps2 keyboard bytes
Expand All @@ -413,7 +430,7 @@ always @(posedge clk_sys) begin

// joystick analog
8'h1a: begin
// first byte is joystick indes
// first byte is joystick index
if(abyte_cnt == 1)
stick_idx <= spi_byte_in[2:0];
else if(abyte_cnt == 2) begin
Expand All @@ -434,7 +451,7 @@ always @(posedge clk_sys) begin
8'h15: status <= spi_byte_in;

// status, 32bit version
8'h1e: if(abyte_cnt<6) status[(abyte_cnt-2)<<3 +:8] <= spi_byte_in;
8'h1e: if(abyte_cnt<5) status[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;

endcase
end
Expand All @@ -446,10 +463,9 @@ 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 sd_wrD;
reg [7:0] acmd;
reg [7:0] abyte_cnt; // counts bytes

Expand All @@ -458,17 +474,18 @@ always @(posedge clk_sd) begin
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;
sd_din_strobe<= 0;
sd_wrD <= sd_wr;
// fetch the first byte immediately after the write command seen
if (~sd_wrD & sd_wr) begin
sd_buff_addr <= 0;
sd_din_strobe <= 1;
end

img_mounted <= 0;
Expand All @@ -479,18 +496,19 @@ always @(posedge clk_sd) begin
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
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)
abyte_cnt <= abyte_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)
if(spi_byte_in == 8'h18) begin
sd_din_strobe <= 1'b1;
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
end

if((spi_byte_in == 8'h17) || (spi_byte_in == 8'h18))
sd_ack <= 1'b1;
Expand All @@ -506,7 +524,10 @@ always @(posedge clk_sd) begin
end

// send sector FPGA -> IO
8'h18: sd_din_strobe <= 1'b1;
8'h18: begin
sd_din_strobe <= 1'b1;
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
end

// send SD config IO -> FPGA
8'h19: begin
Expand All @@ -519,7 +540,7 @@ always @(posedge clk_sd) begin
8'h1c: img_mounted <= 1;

// send image info
8'h1d: if(abyte_cnt<6) img_size[(byte_cnt-2)<<3 +:8] <= spi_byte_in;
8'h1d: if(abyte_cnt<5) img_size[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
endcase
end
end
Expand Down

0 comments on commit 0226b2c

Please sign in to comment.