From 5b743dea3859caeb64330a40ea7ee704f5e2abc9 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Tue, 13 Oct 2009 21:21:22 +0000 Subject: [PATCH] - fixed broken tx-interrupt - added tx_int and rx_int to status reg - tx-int is acked by writing to ctrl reg Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@507 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/uart/uart_wb.vhd | 51 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/lib/uart/uart_wb.vhd b/lib/uart/uart_wb.vhd index 1aa646b..0c767c6 100644 --- a/lib/uart/uart_wb.vhd +++ b/lib/uart/uart_wb.vhd @@ -35,6 +35,8 @@ ARCHITECTURE behavior OF uart_wb IS serial_out : out std_logic; buffer_full : out std_logic; buffer_half_full : out std_logic; + tx_complete : out std_logic; + tx_empty : out std_logic; clk : in std_logic ); END COMPONENT; @@ -66,11 +68,17 @@ ARCHITECTURE behavior OF uart_wb IS signal rx_data_present : std_logic; signal rx_full : std_logic; signal rx_half_full : std_logic; - signal uart_status_port : unsigned(7 downto 0); + signal uart_status_port : unsigned(15 downto 0); signal reg_uart_baud : unsigned(15 downto 0); signal rx_int_en : std_logic; signal tx_int_en : std_logic; - + signal irq_rx : std_logic; + signal irq_tx : std_logic; + signal irq_tx_ack : std_logic; + signal tx_complete : std_logic; + signal tx_empty : std_logic; + signal tx_busy : std_logic; + begin SRDY_O <= CYC_I; @@ -81,8 +89,9 @@ registers_write: begin if rising_edge(CLK_I) then reg_we_uart_tx <= '0'; + irq_tx_ack <= '0'; if RST_I = '1' then - reg_uart_baud <= to_unsigned(53, 8); + reg_uart_baud <= to_unsigned(53, 16); rx_int_en <= '0'; tx_int_en <= '0'; elsif (STB_I and CYC_I and WE_I) = '1' then @@ -90,12 +99,13 @@ registers_write: when "0000" => reg_we_uart_tx <= '1'; - reg_uart_tx <= DAT_I(7 downto 0); + reg_uart_tx <= DAT_I(7 downto 0); when "0001" => rx_int_en <= DAT_I(6); tx_int_en <= DAT_I(5); - + irq_tx_ack <= DAT_I(8); + when "0010" => reg_uart_baud <= DAT_I(15 downto 0); @@ -121,7 +131,7 @@ registers_read: DAT_O(7 downto 0) <= unsigned(reg_uart_rx); when "0001" => - DAT_O(7 downto 0) <= uart_status_port; + DAT_O(15 downto 0) <= uart_status_port; when "0010" => DAT_O(15 downto 0) <= reg_uart_baud; @@ -148,6 +158,27 @@ baud_timer: end if; end process; +tx_interrupt: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + irq_tx <= '0'; + tx_busy <= '0'; + elsif irq_tx_ack = '1' then + irq_tx <= '0'; + else + if tx_empty = '0' then + tx_busy <= '1'; + elsif tx_busy = '1' then + irq_tx <= tx_int_en; + tx_busy <= '0'; + end if; + end if; + irq_rx <= rx_data_present and rx_int_en; + end if; + end process; + inst_uart_tx: uart_tx port map ( @@ -158,6 +189,8 @@ inst_uart_tx: uart_tx serial_out => ser_tx, buffer_full => tx_full, buffer_half_full => tx_half_full, + tx_complete => tx_complete, + tx_empty => tx_empty, clk => CLK_I ); @@ -174,8 +207,8 @@ inst_uart_rx: uart_rx buffer_half_full => rx_half_full, clk => CLK_I ); - - uart_status_port <= '0' & rx_int_en & tx_int_en & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full; - INT_O <= (rx_data_present and rx_int_en) or (not tx_full and tx_int_en); + + uart_status_port <= "000000" & irq_rx & irq_tx & '0' & rx_int_en & tx_int_en & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full; + INT_O <= irq_rx or irq_tx; end behavior;