From: Vladimir Burian Date: Mon, 7 Feb 2011 14:44:01 +0000 (+0100) Subject: Omsp_quadcount periphery changed. X-Git-Url: https://rtime.felk.cvut.cz/gitweb/fpga/virtex2/uart.git/commitdiff_plain/f4d5b9f6f38ec1ae218a400828900d8f01405013 Omsp_quadcount periphery changed. Omsp_quadcount now includes qcounter component. So the top level design has better hierarchy. IRQ is changed to raise when qcounter AB error occures. Software is accordingly modified. --- diff --git a/omsp_quadcount.vhd b/omsp_quadcount.vhd index 43e9750..c58c5ed 100644 --- a/omsp_quadcount.vhd +++ b/omsp_quadcount.vhd @@ -7,18 +7,18 @@ entity omsp_quadcount is generic ( ADDR : std_logic_vector (15 downto 0) := X"0150"); port ( - mclk : in std_logic; - per_addr : in std_logic_vector (7 downto 0); - per_din : in std_logic_vector (15 downto 0); -- unused - per_en : in std_logic; - per_wen : in std_logic_vector (1 downto 0); -- unused - puc : in std_logic; -- unused - per_irq_acc : in std_logic; -- unused - per_irq : out std_logic; - per_dout : out std_logic_vector (15 downto 0); - - qcount : in std_logic_vector (31 downto 0) - ); + -- MCU peripheral interface + mclk : in std_logic; + puc : in std_logic; + per_addr : in std_logic_vector (7 downto 0); + per_en : in std_logic; + per_irq : out std_logic; + per_dout : out std_logic_vector (15 downto 0); + -- QCounter component interface + qclk : in std_logic; + qreset : in std_logic; + a0, b0 : in std_logic; + qcount : out std_logic_vector (31 downto 0)); end omsp_quadcount; -------------------------------------------------------------------------------- @@ -34,42 +34,86 @@ architecture behavioral of omsp_quadcount is -- qcount higher word logic address constant QCNTH : std_logic_vector (15 downto 0) := ADDR + 2; + -- Address read decoder signal qcntl_sel : boolean; signal qcnth_sel : boolean; - signal qcnth_latch : std_logic_vector (15 downto 0) := (others => '0'); - - signal qcount_prev : std_logic_vector (31 downto 0) := (others => '0'); - + -- Latch of high work of qcounter component + signal qcnth_latch : std_logic_vector (15 downto 0); + + signal qcount_out : std_logic_vector (31 downto 0); + -- AB error of qcounter component (lead in peripheral irq) + signal ab_error : std_logic; + + + component qcounter is + port ( + clock : in std_logic; + reset : in std_logic; + a0, b0 : in std_logic; + qcount : out std_logic_vector (31 downto 0); + a_rise : out std_logic; + a_fall : out std_logic; + b_rise : out std_logic; + b_fall : out std_logic; + ab_event : out std_logic; + ab_error : out std_logic); + end component qcounter; + -------------------------------------------------------------------------------- begin + qcounter_1: qcounter + port map ( + clock => qclk, + reset => qreset, + a0 => a0, + b0 => b0, + qcount => qcount_out, + a_rise => open, + a_fall => open, + b_rise => open, + b_fall => open, + ab_event => open, + ab_error => ab_error); + + qcntl_sel <= (per_addr = QCNTL(8 downto 1)) and (per_en = '1'); qcnth_sel <= (per_addr = QCNTH(8 downto 1)) and (per_en = '1'); - per_dout <= qcount (15 downto 0) when qcntl_sel else - qcnth_latch when qcnth_sel else + per_dout <= qcount_out (15 downto 0) when qcntl_sel else + qcnth_latch when qcnth_sel else (others => '0'); - - process (mclk) + qcount <= qcount_out; + + + -- QCNTL latch. + process (mclk, puc) begin - if (rising_edge(mclk) and qcntl_sel) then - qcnth_latch <= qcount (31 downto 16); + if (puc = '1') then + qcnth_latch <= (others => '0'); + + elsif (rising_edge(mclk) and qcntl_sel) then + qcnth_latch <= qcount_out (31 downto 16); + end if; end process; - -- Generation of IRQ signal. (changes in lower 2 bits are suppresed) - process (mclk) + -- Generation of IRQ signal. IRQ is cleared by QCNTL read operation. + process (mclk, puc) begin - if (rising_edge(mclk)) then - qcount_prev <= qcount; - - if (qcntl_sel) then - per_irq <= '0'; - elsif (qcount_prev (31 downto 2) /= qcount (31 downto 2)) then + if (puc = '1') then + per_irq <= '0'; + + elsif (rising_edge(mclk)) then + if (ab_error = '1') then per_irq <= '1'; + + elsif (qcntl_sel) then + per_irq <= '0'; + end if; end if; end process; diff --git a/openMSP430_uart.vhd b/openMSP430_uart.vhd index d742fe2..27c4acc 100644 --- a/openMSP430_uart.vhd +++ b/openMSP430_uart.vhd @@ -78,20 +78,20 @@ architecture rtl of openMSP430_uart is end component; component omsp_quadcount is + generic ( + ADDR : std_logic_vector (15 downto 0)); port ( - mclk : in std_logic; - per_addr : in std_logic_vector (7 downto 0); - per_din : in std_logic_vector (15 downto 0); -- unused - per_en : in std_logic; - per_wen : in std_logic_vector (1 downto 0); -- unused - puc : in std_logic; -- unused - per_irq_acc : in std_logic; -- unused - per_irq : out std_logic; -- unused - per_dout : out std_logic_vector (15 downto 0); - - qcount : in std_logic_vector (31 downto 0) - ); - end component; + mclk : in std_logic; + puc : in std_logic; + per_addr : in std_logic_vector (7 downto 0); + per_en : in std_logic; + per_irq : out std_logic; + per_dout : out std_logic_vector (15 downto 0); + qclk : in std_logic; + qreset : in std_logic; + a0, b0 : in std_logic; + qcount : out std_logic_vector (31 downto 0)); + end component omsp_quadcount; component uart is port ( @@ -110,17 +110,6 @@ architecture rtl of openMSP430_uart is ); end component; - component qcounter is - port ( - clock : in std_logic; - reset : in std_logic; - a0, b0 : in std_logic; - qcount : out std_logic_vector (31 downto 0); - a_rise, a_fall, b_rise, b_fall, ab_event : out std_logic; - ab_error : out std_logic - ); - end component; - signal mclk : std_logic; signal puc : std_logic; @@ -153,7 +142,6 @@ architecture rtl of openMSP430_uart is signal uart_dout : std_logic_vector (15 downto 0); signal uart_irq : std_logic; - signal qcount : std_logic_vector (31 downto 0); -------------------------------------------------------------------------------- @@ -226,18 +214,21 @@ begin we => '1' ); - omsp_quadcount_0 : omsp_quadcount port map ( - mclk => mclk, - per_addr => per_addr, - per_din => (others => '0'), - per_en => per_en, - per_wen => "00", - puc => '0', - per_irq_acc => '0', - per_irq => omsp_quadcount_irq, - per_dout => omsp_quadcount_dout, - - qcount => qcount + omsp_quadcount_1: omsp_quadcount + generic map ( + ADDR => X"0150") + port map ( + mclk => mclk, + puc => puc, + per_addr => per_addr, + per_en => per_en, + per_irq => omsp_quadcount_irq, + per_dout => omsp_quadcount_dout, + qclk => mclk, + qreset => ROT_PRESS, + a0 => ROT_A, + b0 => ROT_B, + qcount => open ); uart_o : uart port map ( @@ -255,19 +246,6 @@ begin txd => RXD ); - qcounter_0 : qcounter port map ( - clock => mclk, - reset => ROT_PRESS, - a0 => ROT_A, - b0 => ROT_B, - qcount => qcount, - a_rise => open, - a_fall => open, - b_rise => open, - b_fall => open, - ab_event => open, - ab_error => open - ); -------------------------------------------------------------------------------- diff --git a/software/main.c b/software/main.c index 1f2c2ef..4423505 100644 --- a/software/main.c +++ b/software/main.c @@ -3,8 +3,10 @@ This is a sample application for openMSP430 softcore MCU with external HW UART peripheral and quadcount peripheral. First of all "Hello world" is printed and then application works like echo and -also prints quadrature count whenever its value is changed (only whole turns -are reported). +also prints quadrature count whenever its value is changed. + +AB error of quadrature counter peripheral is handled by irq routine which prints +message "IRQ: QCounter AB error!". Baudrate is set to 115200. */ @@ -31,7 +33,8 @@ inline uint32_t qcount() { Handling of QuadCounter IRQ */ interrupt(QCNT_VECTOR) qcount_isr() { - printf("[QCount = 0x%08lX]\n", qcount() >> 2); + puts("IRQ: QCounter AB error!"); + qcount(); } @@ -79,6 +82,8 @@ void delay(unsigned long int a, unsigned long int b) { Main function with init and an endless loop. */ int main(void) { + uint32_t qcnt = qcount(); + uint32_t qcnt_new; //UBAUD = 0x04E1; //24.00MHz - 9600 baud UBAUD = 0x0067; //24.00MHz - 115200 baud @@ -88,8 +93,16 @@ int main(void) { puts("Hello world\n"); - for (;;) { - putchar(getchar()); + for (;;) { + while (!isRxEmpty()) { + putchar(URX); + } + + qcnt_new = qcount(); + if (qcnt != qcnt_new) { + printf("[QCount = 0x%08lX]\n", qcnt_new); + qcnt = qcnt_new; + } } } diff --git a/software/uart.c b/software/uart.c index 1c57831..87d7222 100644 --- a/software/uart.c +++ b/software/uart.c @@ -12,3 +12,6 @@ int getchar() { return URX; } +int isRxEmpty() { + return (~USTAT) & 0x10; +} diff --git a/software/uart.h b/software/uart.h index c3290b4..c659568 100644 --- a/software/uart.h +++ b/software/uart.h @@ -5,5 +5,7 @@ int putchar(int c); int getchar(); +int isRxEmpty(); + #endif