1
0
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:
harbaum
2015-06-15 09:19:13 +00:00
parent a7ee9920b0
commit 4e103a2639
4 changed files with 112 additions and 14 deletions

View File

@@ -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]
};

View File

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

View File

@@ -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),

View File

@@ -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 };