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 |