Stefan Schuermans commited on 2012-02-20 13:36:12
Showing 4 changed files, with 89 additions and 18 deletions.
... | ... |
@@ -7,6 +7,7 @@ |
7 | 7 |
//#define CFG_DELAY |
8 | 8 |
//#define CFG_LCD |
9 | 9 |
#define CFG_UART |
10 |
+#define CFG_UART_CHK |
|
10 | 11 |
|
11 | 12 |
const int myconst = 0x12345678; |
12 | 13 |
|
... | ... |
@@ -75,6 +76,16 @@ int main() |
75 | 76 |
uart_tx('I'); |
76 | 77 |
uart_tx('\r'); |
77 | 78 |
uart_tx('\n'); |
79 |
+#ifdef CFG_UART_CHK |
|
80 |
+ if (uart_rx() != 'M') while(1); |
|
81 |
+ if (uart_rx() != 'I') while(1); |
|
82 |
+ if (uart_rx() != 'P') while(1); |
|
83 |
+ if (uart_rx() != 'S') while(1); |
|
84 |
+ if (uart_rx() != ' ') while(1); |
|
85 |
+ if (uart_rx() != 'I') while(1); |
|
86 |
+ if (uart_rx() != '\r') while(1); |
|
87 |
+ if (uart_rx() != '\n') while(1); |
|
88 |
+#endif |
|
78 | 89 |
#endif |
79 | 90 |
|
80 | 91 |
while (1) { |
... | ... |
@@ -36,7 +36,19 @@ void uart_cfg_stop(unsigned char stop) |
36 | 36 |
*/ |
37 | 37 |
void uart_tx(unsigned short chr) |
38 | 38 |
{ |
39 |
- while (!*(uart_ptr + 4)); |
|
40 |
- *(unsigned short *)(uart_ptr + 8) = chr; |
|
39 |
+ while (!*(uart_ptr + 4)); /* wait for ready */ |
|
40 |
+ *(unsigned short *)(uart_ptr + 8) = chr; /* write data */ |
|
41 |
+} |
|
42 |
+ |
|
43 |
+/** |
|
44 |
+ * @brief receive a character |
|
45 |
+ * @return character received |
|
46 |
+ */ |
|
47 |
+unsigned short uart_rx(void) |
|
48 |
+{ |
|
49 |
+ while (!*(uart_ptr + 5)); /* wait for data */ |
|
50 |
+ unsigned short chr = *(unsigned short *)(uart_ptr + 12); /* read data */ |
|
51 |
+ *(unsigned short *)(uart_ptr + 12) = 0; /* remove data from FIFO */ |
|
52 |
+ return chr; |
|
41 | 53 |
} |
42 | 54 |
|
... | ... |
@@ -26,6 +26,13 @@ ARCHITECTURE a_io_uart OF e_io_uart IS |
26 | 26 |
SIGNAL n_cfg_stop: std_logic_vector( 1 DOWNTO 0); |
27 | 27 |
SIGNAL r_cfg_stop: std_logic_vector( 1 DOWNTO 0) := "01"; |
28 | 28 |
|
29 |
+ SIGNAL s_rx_wr_rdy: std_logic; |
|
30 |
+ SIGNAL s_rx_wr_data: std_logic_vector(15 DOWNTO 0); |
|
31 |
+ SIGNAL s_rx_wr_en: std_logic; |
|
32 |
+ SIGNAL s_rx_rd_rdy: std_logic; |
|
33 |
+ SIGNAL s_rx_rd_data: std_logic_vector(15 DOWNTO 0); |
|
34 |
+ SIGNAL s_rx_rd_en: std_logic; |
|
35 |
+ |
|
29 | 36 |
SIGNAL n_rx_scale: natural RANGE 2**16 - 1 DOWNTO 0; |
30 | 37 |
SIGNAL r_rx_scale: natural RANGE 2**16 - 1 DOWNTO 0 := 1; |
31 | 38 |
SIGNAL n_rx_bits: natural RANGE 15 DOWNTO 0; |
... | ... |
@@ -124,20 +131,42 @@ BEGIN |
124 | 131 |
END IF; |
125 | 132 |
END PROCESS p_cfg_sync; |
126 | 133 |
|
134 |
+ s_rx_rd_en <= '1' WHEN i_addr = "11" AND i_wr_en(1 DOWNTO 0) = "11" |
|
135 |
+ ELSE '0'; |
|
136 |
+ |
|
137 |
+ rx_fifo: e_block_fifo |
|
138 |
+ GENERIC MAP ( |
|
139 |
+ addr_width => 4, |
|
140 |
+ data_width => 16 |
|
141 |
+ ) |
|
142 |
+ PORT MAP ( |
|
143 |
+ rst => rst, |
|
144 |
+ clk => clk, |
|
145 |
+ o_wr_rdy => s_rx_wr_rdy, |
|
146 |
+ i_wr_data => s_rx_wr_data, |
|
147 |
+ i_wr_en => s_rx_wr_en, |
|
148 |
+ o_rd_rdy => s_rx_rd_rdy, |
|
149 |
+ o_rd_data => s_rx_rd_data, |
|
150 |
+ i_rd_en => s_rx_rd_en |
|
151 |
+ ); |
|
152 |
+ |
|
127 | 153 |
p_rx_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop, |
128 | 154 |
r_rx_scale, r_rx_bits, r_rx_stop, |
129 | 155 |
r_rx_state, r_rx_cnt, r_rx_sample, r_rx_bit, |
130 | 156 |
r_rx_samples, r_rx_data, |
131 |
- pin_i_rx) |
|
157 |
+ pin_i_rx, s_rx_wr_rdy) |
|
132 | 158 |
VARIABLE v_next_cnt: boolean; |
133 | 159 |
VARIABLE v_next_sample: boolean; |
134 | 160 |
VARIABLE v_next_bit: boolean; |
135 | 161 |
VARIABLE v_next_state: boolean; |
162 |
+ VARIABLE v_complete: boolean; |
|
136 | 163 |
VARIABLE v_bits: natural RANGE 15 DOWNTO 0; |
137 | 164 |
VARIABLE v_samples: std_logic_vector( 2 DOWNTO 0); |
138 | 165 |
VARIABLE v_bit_val: std_logic; |
139 |
- VARIABLE v_err: boolean; |
|
166 |
+ VARIABLE v_data: std_logic_vector(15 DOWNTO 0); |
|
140 | 167 |
BEGIN |
168 |
+ s_rx_wr_data <= (OTHERS => '0'); |
|
169 |
+ s_rx_wr_en <= '0'; |
|
141 | 170 |
n_rx_scale <= r_rx_scale; |
142 | 171 |
n_rx_bits <= r_rx_bits; |
143 | 172 |
n_rx_stop <= r_rx_stop; |
... | ... |
@@ -146,15 +175,15 @@ BEGIN |
146 | 175 |
n_rx_sample <= r_rx_sample; |
147 | 176 |
n_rx_bit <= r_rx_bit; |
148 | 177 |
n_rx_samples <= r_rx_samples; |
149 |
- n_rx_data <= r_rx_data; |
|
150 | 178 |
v_next_cnt := false; |
151 | 179 |
v_next_sample := false; |
152 | 180 |
v_next_bit := false; |
153 | 181 |
v_next_state := false; |
182 |
+ v_complete := false; |
|
154 | 183 |
v_bits := 0; |
155 | 184 |
v_samples := "000"; |
156 | 185 |
v_bit_val := '0'; |
157 |
- v_err := false; |
|
186 |
+ v_data := r_rx_data; |
|
158 | 187 |
IF r_rx_state = inactive THEN |
159 | 188 |
IF pin_i_rx = '0' THEN |
160 | 189 |
n_rx_scale <= to_integer(unsigned(r_cfg_scale)); |
... | ... |
@@ -164,8 +193,8 @@ BEGIN |
164 | 193 |
n_rx_cnt <= 0; |
165 | 194 |
n_rx_sample <= 3; -- sample in middle of received bits |
166 | 195 |
n_rx_bit <= 0; |
167 |
- n_rx_samples <= "00"; |
|
168 |
- n_rx_data <= X"0000"; |
|
196 |
+ -- n_rx_samples: no initialization needed |
|
197 |
+ -- n_rx_data/v_data: keep error bit (bit 15), no initialization needed for other bits |
|
169 | 198 |
END IF; |
170 | 199 |
ELSE |
171 | 200 |
v_next_cnt := true; |
... | ... |
@@ -190,18 +219,19 @@ BEGIN |
190 | 219 |
WHEN "011" | "101" | "110" | "111" => v_bit_val := '1'; |
191 | 220 |
WHEN OTHERS => NULL; |
192 | 221 |
END CASE; |
193 |
- IF r_rx_state = data THEN |
|
194 |
- n_rx_data(r_rx_bit) <= v_bit_val; |
|
195 |
- END IF; |
|
196 | 222 |
CASE r_rx_state IS |
197 |
- WHEN start => v_err := v_bit_val /= '0'; |
|
198 |
- WHEN data => v_err := false; |
|
199 |
- WHEN stop => v_err := v_bit_val /= '1'; |
|
223 |
+ WHEN start => |
|
224 |
+ IF v_bit_val /= '0' THEN |
|
225 |
+ v_data(15) := '1'; -- set error bit |
|
226 |
+ END IF; |
|
227 |
+ WHEN data => |
|
228 |
+ v_data(r_rx_bit) := v_bit_val; |
|
229 |
+ WHEN stop => |
|
230 |
+ IF v_bit_val /= '1' THEN |
|
231 |
+ v_data(15) := '1'; -- set error bit |
|
232 |
+ END IF; |
|
200 | 233 |
WHEN OTHERS => NULL; |
201 | 234 |
END CASE; |
202 |
- IF v_err THEN |
|
203 |
- n_rx_data(15) <= '1'; |
|
204 |
- END IF; |
|
205 | 235 |
END IF; |
206 | 236 |
IF r_rx_sample /= 6 THEN |
207 | 237 |
n_rx_sample <= r_rx_sample + 1; |
... | ... |
@@ -228,10 +258,20 @@ BEGIN |
228 | 258 |
CASE r_rx_state IS |
229 | 259 |
WHEN start => n_rx_state <= data; |
230 | 260 |
WHEN data => n_rx_state <= stop; |
231 |
- WHEN stop => n_rx_state <= inactive; |
|
261 |
+ WHEN stop => n_rx_state <= inactive; v_complete := true; |
|
232 | 262 |
WHEN OTHERS => NULL; |
233 | 263 |
END CASE; |
234 | 264 |
END IF; |
265 |
+ IF v_complete THEN |
|
266 |
+ IF s_rx_wr_rdy = '1' THEN |
|
267 |
+ s_rx_wr_data <= v_data; |
|
268 |
+ s_rx_wr_en <= '1'; |
|
269 |
+ v_data(15) := '0'; -- clear error bit |
|
270 |
+ ELSE |
|
271 |
+ v_data(15) := '1'; -- set error bit (RX FIFO overflow) |
|
272 |
+ END IF; |
|
273 |
+ END IF; |
|
274 |
+ n_rx_data <= v_data; |
|
235 | 275 |
END PROCESS p_rx_next; |
236 | 276 |
|
237 | 277 |
p_rx_sync: PROCESS(rst, clk) |
... | ... |
@@ -404,6 +444,9 @@ BEGIN |
404 | 444 |
o_rd_data(25 DOWNTO 24) <= r_cfg_stop; |
405 | 445 |
WHEN "01" => |
406 | 446 |
o_rd_data(0) <= s_tx_wr_rdy; |
447 |
+ o_rd_data(8) <= s_rx_rd_rdy; |
|
448 |
+ WHEN "11" => |
|
449 |
+ o_rd_data(15 DOWNTO 0) <= s_rx_rd_data; |
|
407 | 450 |
WHEN OTHERS => |
408 | 451 |
NULL; |
409 | 452 |
END CASE; |
410 | 453 |