mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-01-28 12:38:43 +00:00
[FIRMWARE/ATARI ST] Initial support for pl2303 usb/rs232 cable
This commit is contained in:
@@ -36,11 +36,13 @@ module mfp (
|
||||
output serial_data_out_available,
|
||||
input serial_strobe_out,
|
||||
output [7:0] serial_data_out,
|
||||
output [63:0] serial_status_out,
|
||||
|
||||
// serial rs223 connection from io controller
|
||||
input serial_strobe_in,
|
||||
input [7:0] serial_data_in,
|
||||
output serial_data_in_full,
|
||||
input [7:0] serial_status_in,
|
||||
|
||||
// inputs
|
||||
input clk_ext, // external 2.457MHz
|
||||
@@ -86,16 +88,20 @@ io_fifo mfp_in_fifo (
|
||||
.out_strobe (1'b0),
|
||||
.out_enable (serial_cpu_data_read && serial_data_in_available),
|
||||
|
||||
.empty (serial_data_in_empty),
|
||||
.full (serial_data_in_full),
|
||||
.data_available (serial_data_in_available)
|
||||
);
|
||||
|
||||
// ---------------- mfp uart data to/from io controller ------------
|
||||
reg serial_cpu_data_read;
|
||||
reg serial_cpu_data_read, serial_cpu_data_readD;
|
||||
wire serial_data_in_available;
|
||||
wire [7:0] serial_data_in_cpu;
|
||||
wire serial_data_in_empty;
|
||||
|
||||
always @(negedge clk) begin
|
||||
serial_cpu_data_readD <= serial_cpu_data_read;
|
||||
|
||||
// read on uart data register
|
||||
serial_cpu_data_read <= 1'b0;
|
||||
if(sel && ~ds && rw && (addr == 5'h17))
|
||||
@@ -165,6 +171,7 @@ mfp_timer timer_c (
|
||||
wire timerd_done;
|
||||
wire [7:0] timerd_dat_o;
|
||||
wire [3:0] timerd_ctrl_o;
|
||||
wire [7:0] timerd_set_data;
|
||||
|
||||
mfp_timer timer_d (
|
||||
.CLK (clk),
|
||||
@@ -176,7 +183,8 @@ mfp_timer timer_d (
|
||||
.DAT_I (din),
|
||||
.DAT_O (timerd_dat_o),
|
||||
.DAT_WE ((addr == 5'h12) && write),
|
||||
.T_O_PULSE (timerd_done)
|
||||
.T_O_PULSE (timerd_done),
|
||||
.SET_DATA_OUT (timerd_set_data)
|
||||
);
|
||||
|
||||
reg [7:0] aer, ddr, gpip;
|
||||
@@ -207,6 +215,60 @@ mfp_hbit16 irq_pending_index (
|
||||
// gpip as output to the cpu (ddr bit == 1 -> gpip pin is output)
|
||||
wire [7:0] gpip_cpu_out = (i & ~ddr) | (gpip & ddr);
|
||||
|
||||
// assemble output status structure. Adjust bitrate endianess
|
||||
assign serial_status_out = {
|
||||
bitrate[7:0], bitrate[15:8], bitrate[23:16], bitrate[31:24],
|
||||
databits, parity, stopbits, input_fifo_status };
|
||||
|
||||
wire [11:0] timerd_state = { timerd_ctrl_o, timerd_set_data };
|
||||
|
||||
// Atari RTS: YM-A-4 ->
|
||||
// Atari CTS: mfp gpio-2 <-
|
||||
|
||||
// --- export bit rate ---
|
||||
// try to calculate bitrate from timer d config
|
||||
// bps is 2.457MHz/2/16/prescaler/datavalue
|
||||
wire [31:0] bitrate =
|
||||
(uart_ctrl[6] != 1'b1)?32'h80000000: // uart prescaler not 1
|
||||
(timerd_state == 12'h101)?32'd19200: // 19200 bit/s
|
||||
(timerd_state == 12'h102)?32'd9600: // 9600 bit/s
|
||||
(timerd_state == 12'h104)?32'd4800: // 4800 bit/s
|
||||
(timerd_state == 12'h105)?32'd3600: // 3600 bit/s (?? isn't that 3840?)
|
||||
(timerd_state == 12'h108)?32'd2400: // 2400 bit/s
|
||||
(timerd_state == 12'h10a)?32'd2000: // 2000 bit/s (exact 1920)
|
||||
(timerd_state == 12'h10b)?32'd1800: // 1800 bit/s (exact 1745)
|
||||
(timerd_state == 12'h110)?32'd1200: // 1200 bit/s
|
||||
(timerd_state == 12'h120)?32'd600: // 600 bit/s
|
||||
(timerd_state == 12'h140)?32'd300: // 300 bit/s
|
||||
(timerd_state == 12'h160)?32'd200: // 200 bit/s
|
||||
(timerd_state == 12'h180)?32'd150: // 150 bit/s
|
||||
(timerd_state == 12'h18f)?32'd134: // 134 bit/s
|
||||
(timerd_state == 12'h18f)?32'd134: // 134 bit/s (134.27)
|
||||
(timerd_state == 12'h1af)?32'd110: // 110 bit/s (109.71)
|
||||
(timerd_state == 12'h240)?32'd75: // 75 bit/s (120)
|
||||
(timerd_state == 12'h260)?32'd50: // 50 bit/s (80)
|
||||
32'h80000001; // unsupported bit rate
|
||||
|
||||
wire [7:0] input_fifo_status = { 5'd0,
|
||||
serial_data_in_empty, serial_data_in_full, serial_data_in_available };
|
||||
|
||||
wire [7:0] parity =
|
||||
(uart_ctrl[1] == 1'b0)?8'h00: // no parity
|
||||
(uart_ctrl[0] == 1'b0)?8'h01: // odd parity
|
||||
8'h02; // even parity
|
||||
|
||||
wire [7:0] stopbits =
|
||||
(uart_ctrl[3:2] == 2'b00)?8'hff: // sync mode not supported
|
||||
(uart_ctrl[3:2] == 2'b01)?8'h00: // async 1 stop bit
|
||||
(uart_ctrl[3:2] == 2'b10)?8'h01: // async 1.5 stop bits
|
||||
8'h11; // async 2 stop bits
|
||||
|
||||
wire [7:0] databits =
|
||||
(uart_ctrl[5:4] == 2'b00)?8'd8: // 8 data bits
|
||||
(uart_ctrl[5:4] == 2'b01)?8'd7: // 7 data bits
|
||||
(uart_ctrl[5:4] == 2'b10)?8'd6: // 6 data bits
|
||||
8'd5; // 5 data bits
|
||||
|
||||
// cpu controllable uart control bits
|
||||
reg [1:0] uart_rx_ctrl;
|
||||
reg [3:0] uart_tx_ctrl;
|
||||
@@ -270,10 +332,19 @@ wire [7:0] gpio_irq = ~aer ^ ((i & ~ti_irq_mask) | (ti_irq & ti_irq_mask));
|
||||
wire [15:0] ipr;
|
||||
reg [15:0] ipr_reset;
|
||||
|
||||
// the cpu reading data clears rx irq. It may raise again immediately if there's more
|
||||
// data in the input fifo. Use a delayed cpu read signal to make sure the fifo finishes
|
||||
// removing the byte before
|
||||
wire uart_rx_irq = serial_data_in_available && !serial_cpu_data_readD;
|
||||
|
||||
// the io controller reading data clears tx irq. It may raus again immediately if
|
||||
// there's more data in the output fifo
|
||||
wire uart_tx_irq = !serial_data_out_fifo_full && !serial_strobe_out;
|
||||
|
||||
// map the 16 interrupt sources onto the 16 interrupt register bits
|
||||
wire [15:0] ipr_set = {
|
||||
gpio_irq[7:6], timera_done, serial_data_in_available,
|
||||
1'b0 /* rcv err */, !serial_data_out_fifo_full, 1'b0 /* tx err */, timerb_done,
|
||||
gpio_irq[7:6], timera_done, uart_rx_irq,
|
||||
1'b0 /* rcv err */, uart_tx_irq, 1'b0 /* tx err */, timerb_done,
|
||||
gpio_irq[5:4], timerc_done, timerd_done, gpio_irq[3:0]
|
||||
};
|
||||
|
||||
|
||||
@@ -39,9 +39,15 @@ module mfp_timer(
|
||||
output PULSE_MODE, // pulse mode disables input port irq
|
||||
|
||||
output reg T_O,
|
||||
output reg T_O_PULSE
|
||||
output reg T_O_PULSE,
|
||||
|
||||
// current data bits are exported to allow mfp some rs232 bitrate
|
||||
// calculations
|
||||
output [7:0] SET_DATA_OUT
|
||||
);
|
||||
|
||||
assign SET_DATA_OUT = data;
|
||||
|
||||
reg [7:0] data, down_counter, cur_counter;
|
||||
reg [3:0] control;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/********************************************/
|
||||
/* */
|
||||
/********************************************/
|
||||
|
||||
|
||||
module mist_top (
|
||||
// clock inputs
|
||||
input wire [ 2-1:0] CLOCK_27, // 27 MHz
|
||||
@@ -365,7 +365,7 @@ wire mfp_io7 = system_ctrl[8] ^ (ste?ste_dma_snd_xsirq:1'b0);
|
||||
wire parallel_fifo_full;
|
||||
wire mfp_io0 = (usb_redirection == 2'd2)?parallel_fifo_full:~joy0[4];
|
||||
|
||||
// inputs 1,2 and 6 are inputs from serial which have pullups before an inverter
|
||||
// inputs 1,2 and 6 are inputs from serial which have pullups before and inverter
|
||||
wire [7:0] mfp_gpio_in = {mfp_io7, 1'b0, !dma_irq, !acia_irq, !blitter_irq, 2'b00, mfp_io0};
|
||||
wire [1:0] mfp_timer_in = {!st_de, ste?ste_dma_snd_xsirq_delayed:!parallel_fifo_full};
|
||||
|
||||
@@ -386,8 +386,10 @@ mfp mfp (
|
||||
.serial_data_out_available (serial_data_from_mfp_available),
|
||||
.serial_strobe_out (serial_strobe_from_mfp),
|
||||
.serial_data_out (serial_data_from_mfp),
|
||||
.serial_status_out (serial_status_from_mfp),
|
||||
.serial_strobe_in (serial_strobe_to_mfp),
|
||||
.serial_data_in (serial_data_to_mfp),
|
||||
.serial_status_in (serial_status_to_mfp),
|
||||
|
||||
// input signals
|
||||
.clk_ext (clk_mfp ), // 2.457MHz clock
|
||||
@@ -1102,6 +1104,8 @@ wire serial_strobe_from_mfp;
|
||||
wire serial_data_from_mfp_available;
|
||||
wire [7:0] serial_data_to_mfp;
|
||||
wire serial_strobe_to_mfp;
|
||||
wire [7:0] serial_status_to_mfp;
|
||||
wire [63:0] serial_status_from_mfp;
|
||||
|
||||
// connection to transfer parallel data from psg to io controller
|
||||
wire [7:0] parallel_data_out;
|
||||
@@ -1147,8 +1151,10 @@ user_io user_io(
|
||||
.serial_strobe_out (serial_strobe_from_mfp),
|
||||
.serial_data_out (serial_data_from_mfp),
|
||||
.serial_data_out_available (serial_data_from_mfp_available),
|
||||
.serial_status_out (serial_status_from_mfp),
|
||||
.serial_strobe_in (serial_strobe_to_mfp),
|
||||
.serial_data_in (serial_data_to_mfp),
|
||||
.serial_status_in (serial_status_to_mfp),
|
||||
|
||||
// parallel interface
|
||||
.parallel_strobe_out (parallel_strobe_out),
|
||||
|
||||
@@ -21,11 +21,15 @@ module user_io(
|
||||
output reg serial_strobe_out,
|
||||
input serial_data_out_available,
|
||||
input [7:0] serial_data_out,
|
||||
// serial status from mfp to io controller
|
||||
input [63:0] serial_status_out,
|
||||
|
||||
// serial data from io controller to mfp
|
||||
output reg serial_strobe_in,
|
||||
output reg [7:0] serial_data_in,
|
||||
|
||||
// serial status from io controller to mfp
|
||||
output reg [7:0] serial_status_in,
|
||||
|
||||
// parallel data from psg/ym to io controller
|
||||
output reg parallel_strobe_out,
|
||||
input parallel_data_out_available,
|
||||
@@ -62,7 +66,7 @@ module user_io(
|
||||
wire [7:0] spi_sck_D = { spi_sck_D[6:0], SPI_CLK } /* synthesis keep */;
|
||||
wire spi_sck = (spi_sck && spi_sck_D != 8'h00) || (!spi_sck && spi_sck_D == 8'hff);
|
||||
|
||||
reg [1:0] byte_cnt;
|
||||
reg [3:0] byte_cnt;
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [3:0] bit_cnt; // 0..15
|
||||
@@ -74,7 +78,11 @@ wire [2:0] tx_bit = ~(bit_cnt[2:0]);
|
||||
assign BUTTONS = but_sw[1:0];
|
||||
assign SWITCHES = but_sw[3:2];
|
||||
assign scandoubler_disable = but_sw[4];
|
||||
|
||||
|
||||
// prepent "a5" to status to make sure io controller can detect that a core
|
||||
// doesn't support the command
|
||||
wire [63+8:0] serial_status_out_x = { 8'ha5, serial_status_out };
|
||||
|
||||
always@(negedge spi_sck) begin
|
||||
if(bit_cnt <= 7)
|
||||
SPI_MISO <= CORE_TYPE[7-bit_cnt];
|
||||
@@ -113,18 +121,22 @@ always@(negedge spi_sck) begin
|
||||
|
||||
// ethernet status
|
||||
if(cmd == 8'h0a)
|
||||
SPI_MISO <= eth_status[{~byte_cnt, tx_bit}];
|
||||
SPI_MISO <= eth_status[{~byte_cnt[1:0], tx_bit}];
|
||||
|
||||
// read ethernet tx buffer
|
||||
if(cmd == 8'h0b)
|
||||
SPI_MISO <= eth_tx_read_byte[tx_bit];
|
||||
|
||||
// serial status
|
||||
if(cmd == 8'h0d)
|
||||
SPI_MISO <= serial_status_out_x[{4'h8-byte_cnt, tx_bit}];
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge spi_sck, posedge SPI_SS_IO) begin
|
||||
if(SPI_SS_IO == 1) begin
|
||||
bit_cnt <= 4'd0;
|
||||
byte_cnt <= 2'd0;
|
||||
byte_cnt <= 4'd0;
|
||||
|
||||
// ikbd (kbd, joysticks, mouse)
|
||||
ikbd_strobe_in <= 1'b0;
|
||||
@@ -152,7 +164,7 @@ always@(negedge spi_sck) begin
|
||||
bit_cnt <= bit_cnt + 4'd1;
|
||||
else begin
|
||||
bit_cnt <= 4'd8;
|
||||
byte_cnt <= byte_cnt + 2'd1;
|
||||
byte_cnt <= byte_cnt + 4'd1;
|
||||
end
|
||||
|
||||
// command byte finished
|
||||
@@ -236,9 +248,12 @@ always@(negedge spi_sck) begin
|
||||
if(cmd == 8'h0c) begin
|
||||
eth_rx_write_byte <= { sbuf, SPI_MOSI };
|
||||
eth_rx_write_strobe <= 1'b1;
|
||||
// eth_rx_write_begin <= 1'b1;
|
||||
end
|
||||
|
||||
// serial_status from io controller
|
||||
if((cmd == 8'h0d) && (byte_cnt == 1))
|
||||
serial_status_in <= { sbuf, SPI_MOSI };
|
||||
|
||||
// four extra joysticks ...
|
||||
if(cmd == 8'h10)
|
||||
joy0 <= { sbuf[4:0], SPI_MOSI };
|
||||
|
||||
Reference in New Issue
Block a user