summaryrefslogtreecommitdiff
path: root/hdl/rs232.sv
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-05-08 15:51:35 -0700
committerJulian Blake Kongslie2022-05-08 15:51:35 -0700
commit38c5ae5b60eae9562b97da42f47af3861847f8e5 (patch)
tree556fd9e5c38fb2feea56ce5741ca02a5e110ad63 /hdl/rs232.sv
parentMake the script for setting up the TTY actually connect. (diff)
downloadmultipdp8-38c5ae5b60eae9562b97da42f47af3861847f8e5.tar.xz
*Proper* serial port for memory downloads. 115200 8O2 RS232 with CRTRTS.
Diffstat (limited to 'hdl/rs232.sv')
-rw-r--r--hdl/rs232.sv109
1 files changed, 76 insertions, 33 deletions
diff --git a/hdl/rs232.sv b/hdl/rs232.sv
index 31beb1e..ef53f12 100644
--- a/hdl/rs232.sv
+++ b/hdl/rs232.sv
@@ -1,6 +1,9 @@
1`include "defs.svh" 1`include "defs.svh"
2 2
3module rs232_tx 3module rs232_tx
4 #( PARITY = 0
5 , STOP_BITS = 2
6 )
4 ( input bit clock 7 ( input bit clock
5 , input bit reset 8 , input bit reset
6 9
@@ -9,6 +12,7 @@ module rs232_tx
9 , input uart_byte_t out_data 12 , input uart_byte_t out_data
10 13
11 , output bit tx 14 , output bit tx
15 , input bit cts
12 ); 16 );
13 17
14 bit hold_valid; 18 bit hold_valid;
@@ -18,40 +22,45 @@ module rs232_tx
18 (* syn_encoding = "one-hot" *) enum int unsigned 22 (* syn_encoding = "one-hot" *) enum int unsigned
19 { START 23 { START
20 , DATA 24 , DATA
21 , PARITY 25 , PARITY_BIT
22 , STOP1 26 , STOP
23 , STOP2
24 } state; 27 } state;
25 28
26 bit [$clog2(`UART_BYTE_BITS):0] data_bits; 29 bit [$clog2($bits(uart_byte_t)):0] data_bits;
30 bit [$clog2(STOP_BITS):0] stop_bits;
27 31
28 always @(posedge clock, posedge reset) begin 32 always @(posedge clock, posedge reset) begin
29 if (reset) begin 33 if (reset) begin
30 out_ready = 0; 34 out_ready = 0;
31 tx = 1; 35 tx = 1;
32 hold_valid = 0; 36 hold_valid = 0;
33 parity = 0; 37 parity = PARITY;
34 state = state.first; 38 state = state.first;
35 data_bits = 0; 39 data_bits = 0;
40 stop_bits = 0;
36 end else begin 41 end else begin
37 if (out_ready && out_valid) begin 42 if (out_ready && out_valid) begin
38 hold_valid = 1; 43 hold_valid = 1;
39 hold = out_data; 44 hold = out_data;
40 parity = 0; 45 parity = PARITY;
41 state = state.first; 46 state = state.first;
42 data_bits = 0; 47 data_bits = 0;
48 stop_bits = 0;
43 end 49 end
44 50
45 if (hold_valid) begin 51 if (hold_valid) begin
46 case (state) 52 case (state)
47 53
48 START: begin 54 START: begin
49 tx = 0; 55 if (!cts) begin
50 state = state.next; 56 tx = 0;
57 state = state.next;
58 end
51 end 59 end
52 60
53 DATA: begin 61 DATA: begin
54 tx = hold[data_bits]; 62 tx = hold[0];
63 hold = hold >> 1;
55 parity = parity ^ tx; 64 parity = parity ^ tx;
56 if (data_bits == `UART_BYTE_BITS-1) 65 if (data_bits == `UART_BYTE_BITS-1)
57 state = state.next; 66 state = state.next;
@@ -59,20 +68,19 @@ module rs232_tx
59 ++data_bits; 68 ++data_bits;
60 end 69 end
61 70
62 PARITY: begin 71 PARITY_BIT: begin
63 tx = parity; 72 tx = parity;
64 state = state.next; 73 state = state.next;
65 end 74 end
66 75
67 STOP1: begin 76 STOP: begin
68 tx = 1;
69 state = state.next;
70 end
71
72 STOP2: begin
73 hold_valid = 0;
74 tx = 1; 77 tx = 1;
75 state = state.next; 78 if (stop_bits == STOP_BITS-1) begin
79 hold_valid = 0;
80 state = state.next;
81 end else begin
82 ++stop_bits;
83 end
76 end 84 end
77 85
78 endcase 86 endcase
@@ -87,69 +95,94 @@ module rs232_tx
87endmodule 95endmodule
88 96
89module rs232_rx 97module rs232_rx
90 #( OVERSAMPLE = 0 98 #( PARITY = 0
99 , OVERSAMPLE = 0
91 ) 100 )
92 ( input bit clock 101 ( input bit clock
93 , input bit reset 102 , input bit reset
94 103
104 , output bit clock_out
105
95 , input bit in_ready 106 , input bit in_ready
96 , output bit in_valid 107 , output bit in_valid
97 , output uart_byte_t in_data 108 , output uart_byte_t in_data
98 109
99 , input bit rx 110 , input bit rx
111 , output bit rts
100 ); 112 );
101 113
102 (* syn_encoding = "one-hot" *) enum int unsigned 114 (* syn_encoding = "one-hot" *) enum int unsigned
103 { START 115 { START
116 , ALIGN
104 , DATA 117 , DATA
105 , PARITY 118 , PARITY_BIT
106 , STOP 119 , STOP
120 , REALSTOP
107 } state; 121 } state;
108 122
109 uart_byte_t buffer; 123 uart_byte_t buffer;
110 bit [$clog2(`UART_BYTE_BITS):0] data_bits; 124 bit [$clog2(`UART_BYTE_BITS):0] data_bits;
111 bit parity; 125 bit parity;
112 126
113 bit [$clog2(OVERSAMPLE+1):0] sample; 127 bit [$clog2(OVERSAMPLE+1)+2:0] sample;
128 bit [$clog2(OVERSAMPLE+1):0] clock_counter;
114 129
115 always @(posedge clock, posedge reset) begin 130 always @(posedge clock, posedge reset) begin
116 if (reset) begin 131 if (reset) begin
132 clock_out = 0;
117 in_valid = 0; 133 in_valid = 0;
134 rts = 1;
118 state = state.first; 135 state = state.first;
119 buffer = 0; 136 buffer = 0;
120 data_bits = 0; 137 data_bits = 0;
121 parity = 0; 138 parity = PARITY;
122 sample = 0; 139 sample = 0;
140 clock_counter = 0;
123 end else begin 141 end else begin
124 automatic bit ok = 0; 142 automatic bit ok = 0;
125 143
126 if (in_ready && in_valid) 144 if (in_ready && in_valid)
127 in_valid = 0; 145 in_valid = 0;
128 146
129 if (state == state.first) begin 147 if (state == state.first || state == state.last) begin
148 sample = 0;
130 ok = 1; 149 ok = 1;
131 end else begin 150 end else begin
132 ++sample; 151 ++sample;
133 if (sample == OVERSAMPLE+1) begin 152 if (sample > OVERSAMPLE) begin
134 sample = 0; 153 sample = 0;
135 ok = 1; 154 ok = 1;
136 end 155 end
137 end 156 end
138 157
158 ++clock_counter;
159 if (clock_counter > OVERSAMPLE) begin
160 clock_out = 1;
161 clock_counter = 0;
162 end else begin
163 clock_out = 0;
164 end
165
139 if (ok) begin 166 if (ok) begin
140 case (state) 167 case (state)
141 168
142 START: begin 169 START: begin
143 if (rx == 0) begin 170 if (rx == 0) begin
144 state = state.next; 171 state = state.next;
172 if (OVERSAMPLE == 0)
173 state = state.next;
174 sample = (OVERSAMPLE+1) / 2;
145 buffer = 0; 175 buffer = 0;
146 data_bits = 0; 176 data_bits = 0;
147 parity = 0; 177 parity = PARITY;
148 end 178 end
149 end 179 end
150 180
181 ALIGN: state = state.next;
182
151 DATA: begin 183 DATA: begin
152 buffer[data_bits] = rx; 184 buffer = buffer >> 1;
185 buffer[`UART_BYTE_BITS-1] = rx;
153 parity = parity ^ rx; 186 parity = parity ^ rx;
154 if (data_bits == `UART_BYTE_BITS-1) 187 if (data_bits == `UART_BYTE_BITS-1)
155 state = state.next; 188 state = state.next;
@@ -157,24 +190,34 @@ module rs232_rx
157 ++data_bits; 190 ++data_bits;
158 end 191 end
159 192
160 PARITY: begin 193 PARITY_BIT: begin
161 parity = parity ^ rx; 194 parity = parity ^ rx;
162 if (parity == 0) 195 state = state.next;
163 state = state.next;
164 else
165 state = state.first;
166 end 196 end
167 197
168 STOP: begin 198 STOP: begin
169 if (!in_valid && rx == 1) begin 199 if (!in_valid && rx == 1 && parity == 0) begin
170 in_valid = 1; 200 in_valid = 1;
171 in_data = buffer; 201 in_data = buffer;
172 end 202 end
173 state = state.next; 203 if (rx == 1 && parity == 0) begin
204 clock_counter = (OVERSAMPLE+1)/2;
205 end
206 if (rx == 1)
207 state = state.first;
208 else
209 state = state.next;
210 end
211
212 REALSTOP: begin
213 if (rx == 1)
214 state = state.first;
174 end 215 end
175 216
176 endcase 217 endcase
177 end 218 end
219
220 rts = !(state == state.first && !in_valid);
178 end 221 end
179 end 222 end
180 223