]> rtime.felk.cvut.cz Git - fpga/virtex2/uart.git/commitdiff
Omsp_quadcount periphery changed.
authorVladimir Burian <buriavl2@fel.cvut.cz>
Mon, 7 Feb 2011 14:44:01 +0000 (15:44 +0100)
committerVladimir Burian <buriavl2@fel.cvut.cz>
Sun, 13 Feb 2011 12:46:23 +0000 (13:46 +0100)
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.

omsp_quadcount.vhd
openMSP430_uart.vhd
software/main.c
software/uart.c
software/uart.h

index 43e9750793fc26e621d1c5f02c822f36c860375e..c58c5ed64bb7f476474e21b8da05afa623a5d7f4 100644 (file)
@@ -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;
index d742fe2cd8a1ca1d14a470424b465fb9d20c9087..27c4acccb0029cf81c43036a0dcf00cc5755db15 100644 (file)
@@ -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
-  );
 
 --------------------------------------------------------------------------------
 
index 1f2c2efef5cddbb93f570766afd8b1124f4b7954..44235055e74a8799ed2a92b3cdc8c3ba8782534c 100644 (file)
@@ -3,8 +3,10 @@ This is a sample application for openMSP430 softcore MCU with external HW UART
 peripheral <git@rtime.felk.cvut.cz:fpga/uart> 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;
+      }
     }
 
 }
index 1c578319c518f3d4e6b9a94d31db1d16172a2bb0..87d7222659ce9135dd8aa68d2bdc8fdd28e4d220 100644 (file)
@@ -12,3 +12,6 @@ int getchar() {
   return URX;
 }
 
+int isRxEmpty() {
+  return (~USTAT) & 0x10;
+}
index c3290b4e820a44bfc27b7d8d1eb3adb6609f0b83..c659568b67f8d8092b1255de00b77fd8420d113d 100644 (file)
@@ -5,5 +5,7 @@ int putchar(int c);
 
 int getchar();
 
+int isRxEmpty();
+
 #endif