]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
i2c seems to be working now
authorhadaq <hadaq>
Sat, 10 Nov 2012 20:53:47 +0000 (20:53 +0000)
committerhadaq <hadaq>
Sat, 10 Nov 2012 20:53:47 +0000 (20:53 +0000)
nxyter/source/nx_i2c_master.vhd
nxyter/source/nx_i2c_readbyte.vhd [new file with mode: 0644]
nxyter/source/nx_i2c_startstop.vhd
nxyter/source/nxyter.vhd
nxyter/source/nxyter_components.vhd
nxyter/source/nxyter_registers.vhd

index d092a0683fbf8c27b8cf62aeeb5e84f7ce43b508..2c74b9d6e0ba7d75a6a37a456329aa6f8525d67a 100644 (file)
@@ -45,32 +45,43 @@ architecture Behavioral of nx_i2c_master is
   signal sda_o                 : std_logic;\r
   signal scl_o                 : std_logic;\r
   signal i2c_start             : std_logic;\r
-  \r
+\r
+  signal i2c_busy              : std_logic;\r
   signal startstop_select      : std_logic;\r
   signal startstop_seq_start   : std_logic;\r
   signal sendbyte_seq_start    : std_logic;\r
+  signal readbyte_seq_start    : std_logic;\r
   signal sendbyte_byte         : std_logic_vector(7 downto 0);\r
+  signal read_seq_ctr          : std_logic;\r
+  signal reg_data              : std_logic_vector(31 downto 0);\r
 \r
+  signal i2c_busy_x            : std_logic;\r
   signal startstop_select_x    : std_logic;\r
   signal startstop_seq_start_x : std_logic;\r
   signal wait_timer_init_x     : std_logic_vector(11 downto 0);\r
   signal sendbyte_seq_start_x  : std_logic;\r
   signal sendbyte_byte_x       : std_logic_vector(7 downto 0);\r
-  signal i2c_ack_x             : std_logic;\r
+  signal readbyte_seq_start_x  : std_logic;\r
+  signal read_seq_ctr_x        : std_logic;\r
+  signal reg_data_x            : std_logic_vector(31 downto 0);\r
   \r
   signal sda_startstop         : std_logic;\r
   signal scl_startstop         : std_logic;\r
-  signal sda_sendbyte          : std_logic;\r
-  signal scl_sendbyte          : std_logic;\r
+  signal i2c_notready          : std_logic;\r
   signal startstop_done        : std_logic;\r
 \r
-  signal sendbyte_done         : std_logic;\r
+  signal sda_sendbyte          : std_logic;\r
+  signal scl_sendbyte          : std_logic;\r
   signal sendbyte_ack          : std_logic;\r
-  signal i2c_ack               : std_logic;\r
-  signal i2c_notready          : std_logic;\r
-  signal i2c_error             : std_logic_vector(3 downto 0);\r
-\r
-  type STATES is (S_IDLE,\r
+  signal sendbyte_done         : std_logic;\r
+  \r
+  signal sda_readbyte          : std_logic;\r
+  signal scl_readbyte          : std_logic;\r
+  signal readbyte_byte         : std_logic_vector(7 downto 0);\r
+  signal readbyte_done         : std_logic;\r
+  \r
+  type STATES is (S_RESET,\r
+                  S_IDLE,\r
                   S_START,\r
                   S_START_WAIT,\r
 \r
@@ -78,6 +89,10 @@ architecture Behavioral of nx_i2c_master is
                   S_SEND_CHIP_ID_WAIT,\r
                   S_SEND_REGISTER,\r
                   S_SEND_REGISTER_WAIT,\r
+                  S_SEND_DATA,\r
+                  S_SEND_DATA_WAIT,\r
+                  S_GET_DATA,\r
+                  S_GET_DATA_WAIT,\r
 \r
                   S_STOP,\r
                   S_STOP_WAIT\r
@@ -94,7 +109,6 @@ architecture Behavioral of nx_i2c_master is
   signal slv_no_more_data_o      : std_logic;\r
   signal slv_unknown_addr_o      : std_logic;\r
   signal slv_ack_o               : std_logic;\r
-  signal reg_data                : std_logic_vector(31 downto 0);\r
   signal i2c_chipid              : std_logic_vector(6 downto 0);\r
   signal i2c_rw_bit              : std_logic;\r
   signal i2c_registerid          : std_logic_vector(7 downto 0);\r
@@ -143,25 +157,41 @@ begin
       SDA_IN            => sda,\r
       ACK_OUT           => sendbyte_ack\r
       );\r
+\r
+  nx_i2c_readbyte_1: nx_i2c_readbyte\r
+    generic map (\r
+      i2c_speed => i2c_speed\r
+      )\r
+    port map (\r
+      CLK_IN            => CLK_IN,\r
+      RESET_IN          => RESET_IN,\r
+      START_IN          => readbyte_seq_start,\r
+      BYTE_OUT          => readbyte_byte,\r
+      SEQUENCE_DONE_OUT => readbyte_done,\r
+      SDA_OUT           => sda_readbyte,\r
+      SCL_OUT           => scl_readbyte,\r
+      SDA_IN            => sda\r
+      );\r
   \r
   -- Debug Line\r
-  DEBUG_OUT(0) <= sda_o;\r
-  DEBUG_OUT(1) <= scl_o;\r
-  DEBUG_OUT(2) <= i2c_start;\r
-  DEBUG_OUT(3) <= startstop_done;\r
-  DEBUG_OUT(4) <= sda_startstop;\r
-  DEBUG_OUT(5) <= scl_startstop;\r
-  DEBUG_OUT(6) <= sda_sendbyte;\r
-  DEBUG_OUT(7) <= scl_sendbyte;\r
+  -- DEBUG_OUT(0) <= not sendbyte_ack;\r
+  -- DEBUG_OUT(1) <= sda_o;\r
+  -- DEBUG_OUT(2) <= scl_o;\r
+  -- DEBUG_OUT(3) <= sda_startstop;\r
+  -- DEBUG_OUT(4) <= scl_startstop;\r
+  -- DEBUG_OUT(5) <= sda_sendbyte;\r
+  -- DEBUG_OUT(6) <= scl_sendbyte;\r
+  -- DEBUG_OUT(7) <= sda_readbyte;\r
+  -- DEBUG_OUT(8) <= scl_readbyte;\r
+  -- DEBUG_OUT(9) <= i2c_start;\r
   \r
---  DEBUG_OUT(11 downto 8)  <= i2c_error;\r
+  --  DEBUG_OUT(8) <= i2c_start;\r
+  --  DEBUG_OUT(15 downto 10) <= (others => '0');\r
+  DEBUG_OUT(0) <= i2c_start;\r
+  DEBUG_OUT(15 downto 14) <= (others => '0');\r
+  DEBUG_OUT(13 downto 9)  <= reg_data(28 downto 24);\r
+  DEBUG_OUT(8 downto 1)   <= reg_data(7 downto 0);\r
 \r
-  DEBUG_OUT(15 downto 8) <= (others => '0');\r
-\r
-  i2c_error(0)          <= i2c_notready;\r
-  i2c_error(1)          <= not sendbyte_ack;\r
-  i2c_error(3 downto 2) <= (others => '0');\r
-  \r
   -- Sync I2C Lines\r
   sda_i <= SDA_INOUT;\r
   scl_i <= SCL_INOUT;\r
@@ -189,20 +219,26 @@ begin
   begin \r
     if( rising_edge(CLK_IN) ) then\r
       if( RESET_IN = '1' ) then\r
-        i2c_ack               <= '0';\r
+        i2c_busy              <= '1';\r
         startstop_select      <= '0';\r
         startstop_seq_start   <= '0';\r
         sendbyte_seq_start    <= '0';\r
+        readbyte_seq_start    <= '0';\r
         sendbyte_byte         <= (others => '0');\r
         wait_timer_init       <= (others => '0');\r
-        STATE                 <= S_IDLE;\r
+        reg_data              <= (others => '0');\r
+        read_seq_ctr          <= '0';\r
+        STATE                 <= S_RESET;\r
       else\r
-        i2c_ack               <= i2c_ack_x;\r
+        i2c_busy              <= i2c_busy_x;\r
         startstop_select      <= startstop_select_x;\r
         startstop_seq_start   <= startstop_seq_start_x;\r
         sendbyte_seq_start    <= sendbyte_seq_start_x;\r
+        readbyte_seq_start    <= readbyte_seq_start_x;\r
         sendbyte_byte         <= sendbyte_byte_x;\r
         wait_timer_init       <= wait_timer_init_x;\r
+        reg_data              <= reg_data_x;\r
+        read_seq_ctr          <= read_seq_ctr_x;\r
         STATE                 <= NEXT_STATE;\r
       end if;\r
     end if;\r
@@ -210,24 +246,36 @@ begin
   \r
         \r
   PROC_I2C_MASTER: process(STATE)\r
+\r
   begin\r
     -- Defaults\r
     sda_o                   <= '1';\r
     scl_o                   <= '1';\r
-    i2c_ack_x               <= '0';\r
+    i2c_busy_x              <= '1';\r
     startstop_select_x      <= '0';\r
     startstop_seq_start_x   <= '0';\r
     sendbyte_seq_start_x    <= '0';\r
     sendbyte_byte_x         <= (others => '0');\r
+    readbyte_seq_start_x    <= '0';\r
     wait_timer_init_x       <= (others => '0');\r
+    reg_data_x              <= reg_data;\r
+    read_seq_ctr_x          <= read_seq_ctr;\r
     \r
     case STATE is\r
 \r
+      when S_RESET =>\r
+        reg_data_x <= (others => '0');\r
+        NEXT_STATE <= S_IDLE;\r
+        \r
       when S_IDLE =>\r
         if (i2c_start = '1') then\r
+          reg_data_x <= x"8000_0000";  -- Set Running , clear all other bits \r
           NEXT_STATE <= S_START;\r
         else\r
-          NEXT_STATE <= S_IDLE;\r
+          i2c_busy_x     <= '0';\r
+          reg_data_x     <= reg_data and x"7fff_ffff";  -- clear running bit;\r
+          read_seq_ctr_x <= '0';\r
+          NEXT_STATE     <= S_IDLE;\r
         end if;\r
             \r
         -- I2C START Sequence \r
@@ -247,10 +295,13 @@ begin
                    \r
         -- I2C SEND ChipId Sequence\r
       when S_SEND_CHIP_ID =>\r
-        sda_o <= '0';\r
         scl_o <= '0';\r
         sendbyte_byte_x(7 downto 1) <= i2c_chipid;\r
-        sendbyte_byte_x(0)          <= i2c_rw_bit;\r
+        if (read_seq_ctr = '0') then\r
+          sendbyte_byte_x(0)        <= '0';\r
+        else\r
+          sendbyte_byte_x(0)        <= '1';\r
+        end if;\r
         sendbyte_seq_start_x        <= '1';\r
         NEXT_STATE                  <= S_SEND_CHIP_ID_WAIT;\r
         \r
@@ -258,29 +309,77 @@ begin
         if (sendbyte_done = '0') then\r
           NEXT_STATE <= S_SEND_CHIP_ID_WAIT;\r
         else\r
-          sda_o      <= '0';\r
           scl_o      <= '0';\r
-          NEXT_STATE <= S_SEND_REGISTER;\r
+          if (sendbyte_ack = '0') then\r
+            reg_data_x <= reg_data or x"0100_0000";\r
+            NEXT_STATE <= S_STOP;\r
+          else\r
+            if (read_seq_ctr = '0') then\r
+              read_seq_ctr_x <= '1';\r
+              NEXT_STATE <= S_SEND_REGISTER;\r
+            else\r
+              NEXT_STATE <= S_GET_DATA;\r
+            end if;\r
+          end if;\r
         end if;\r
-\r
-        -- I2C SEND RegisterId Sequence\r
-\r
+        \r
+        -- I2C SEND RegisterId\r
       when S_SEND_REGISTER =>\r
-        sda_o <= '0';\r
         scl_o <= '0';\r
-        sendbyte_byte_x        <= i2c_registerid;\r
-        sendbyte_seq_start_x   <= '1';\r
-        NEXT_STATE             <= S_SEND_REGISTER_WAIT;\r
+        sendbyte_byte_x       <= i2c_registerid;          \r
+        sendbyte_seq_start_x  <= '1';\r
+        NEXT_STATE            <= S_SEND_REGISTER_WAIT;\r
         \r
       when S_SEND_REGISTER_WAIT =>\r
         if (sendbyte_done = '0') then\r
           NEXT_STATE <= S_SEND_REGISTER_WAIT;\r
         else\r
-          sda_o      <= '0';\r
           scl_o      <= '0';\r
+          if (sendbyte_ack = '0') then\r
+            reg_data_x <= reg_data or x"0200_0000";\r
+            NEXT_STATE <= S_STOP;\r
+          else\r
+            if (i2c_rw_bit = '0') then\r
+              NEXT_STATE <= S_SEND_DATA;\r
+            else\r
+              NEXT_STATE <= S_START;\r
+            end if;\r
+          end if;\r
+        end if;\r
+\r
+        -- I2C SEND DataWord\r
+      when S_SEND_DATA =>\r
+        scl_o <= '0';\r
+        sendbyte_byte_x        <= i2c_register_data;\r
+        sendbyte_seq_start_x   <= '1';\r
+        NEXT_STATE             <= S_SEND_DATA_WAIT;\r
+        \r
+      when S_SEND_DATA_WAIT =>\r
+        if (sendbyte_done = '0') then\r
+          NEXT_STATE <= S_SEND_DATA_WAIT;\r
+        else\r
+          scl_o      <= '0';\r
+          if (sendbyte_ack = '0') then\r
+            reg_data_x <= reg_data or x"0400_0000";\r
+          end if;\r
           NEXT_STATE <= S_STOP;\r
         end if;\r
-                \r
+\r
+        -- I2C GET DataWord\r
+      when S_GET_DATA =>\r
+        scl_o <= '0';\r
+        readbyte_seq_start_x   <= '1';\r
+        NEXT_STATE             <= S_GET_DATA_WAIT;\r
+        \r
+      when S_GET_DATA_WAIT =>\r
+        if (readbyte_done = '0') then\r
+          NEXT_STATE <= S_GET_DATA_WAIT;\r
+        else\r
+          scl_o                  <= '0';\r
+          reg_data_x(7 downto 0) <= readbyte_byte; \r
+          NEXT_STATE             <= S_STOP;\r
+        end if;\r
+        \r
         -- I2C STOP Sequence \r
       when S_STOP =>\r
         sda_o                 <= '0';\r
@@ -293,6 +392,7 @@ begin
         if (startstop_done = '0') then\r
           NEXT_STATE <= S_STOP_WAIT;\r
         else\r
+          reg_data_x <= reg_data or x"4000_0000"; -- Set DONE Bit\r
           NEXT_STATE <= S_IDLE;\r
         end if;\r
         \r
@@ -302,12 +402,41 @@ begin
   -----------------------------------------------------------------------------\r
   -- TRBNet Slave Bus\r
   -----------------------------------------------------------------------------\r
-\r
+  --\r
+  --   Write bit definition\r
+  --   ====================\r
+  -- \r
+  --   D[31]    I2C_GO          0 => don't do anything on I2C,\r
+  --                            1 => start I2C access\r
+  --   D[30]    I2C_ACTION      0 => write byte, 1 => read byte\r
+  --   D[29:24] I2C_SPEED       set to all '1'\r
+  --   D[23:16] I2C_ADDRESS     address of I2C chip\r
+  --   D[15:8]  I2C_CMD         command byte for access\r
+  --   D[7:0]   I2C_DATA        data to be written\r
+  -- \r
+  --   \r
+  --   Read bit definition\r
+  --   ===================\r
+  --   \r
+  --   D[31:24] status          status information\r
+  --   D[31]    RUNNING         whatever\r
+  --   D[30]    I2C_DONE        whatever\r
+  --   D[29]    ERROR_RADDACK   no acknowledge for repeated address byte\r
+  --   D[28]    ERROR_RSTART    generation of repeated START condition failed\r
+  --   D[27]    ERROR_DATACK    no acknowledge for data byte\r
+  --   D[26]    ERROR_CMDACK    no acknowledge for command byte\r
+  --   D[25]    ERROR_ADDACK    no acknowledge for address byte\r
+  --   D[24]    ERROR_START     generation of START condition failed\r
+  --   D[23:21] reserved        reserved\r
+  --   D[20:16] debug           subject to change, don't use\r
+  --   D[15:8]  reserved        reserved\r
+  --   D[7:0]   I2C_DATA        result of I2C read operation\r
+  --\r
+  \r
   PROC_SLAVE_BUS: process(CLK_IN)\r
   begin\r
     if( rising_edge(CLK_IN) ) then\r
       if( RESET_IN = '1' ) then\r
-        reg_data           <= x"affeaffe";\r
         slv_data_out_o     <= (others => '0');\r
         slv_no_more_data_o <= '0';\r
         slv_unknown_addr_o <= '0';\r
@@ -321,21 +450,30 @@ begin
         i2c_register_value_read <= (others => '0');\r
             \r
       else\r
-        slv_ack_o <= '1';\r
+        slv_ack_o          <= '1';\r
         slv_unknown_addr_o <= '0';\r
         slv_no_more_data_o <= '0';\r
         slv_data_out_o     <= (others => '0');\r
         i2c_start          <= '0';\r
         \r
         if (SLV_WRITE_IN  = '1') then\r
-          i2c_chipid        <= SLV_DATA_IN(30 downto 24);\r
-          i2c_registerid    <= SLV_DATA_IN(23 downto 16);\r
-          i2c_rw_bit        <= SLV_DATA_IN(8);\r
-          i2c_register_data <= SLV_DATA_IN(7 downto 0); \r
-          i2c_start         <= '1';\r
+          if (i2c_busy = '0' and SLV_DATA_IN(31) = '1') then\r
+            i2c_rw_bit        <= SLV_DATA_IN(30);\r
+            i2c_chipid        <= SLV_DATA_IN(22 downto 16);\r
+            i2c_registerid    <= SLV_DATA_IN(15 downto 8);\r
+            i2c_register_data <= SLV_DATA_IN(7 downto 0); \r
+            i2c_start         <= '1';\r
+          end if;\r
+\r
         elsif (SLV_READ_IN = '1') then\r
-          slv_data_out_o    <= reg_data;\r
-          \r
+          if (i2c_busy = '1') then\r
+            slv_data_out_o     <= (others => '0');\r
+            slv_no_more_data_o <= '1';\r
+            slv_ack_o          <= '0';\r
+          else\r
+          slv_data_out_o       <= reg_data;\r
+          end if;\r
+\r
         else\r
           slv_ack_o <= '0';\r
         end if;\r
@@ -344,33 +482,21 @@ begin
   end process PROC_SLAVE_BUS;\r
 \r
 \r
-\r
---   Write bit definition OLD boehmer\r
---   ====================\r
--- \r
--- \r
---   D[31]    I2C_GO          0 => don't do anything on I2C, 1 => start I2C access\r
---   D[30]    I2C_ACTION      0 => write byte, 1 => read byte\r
---   D[29:24] I2C_SPEED       set to all '1'\r
---   D[23:16] I2C_ADDRESS     address of I2C chip\r
---   D[15:8]  I2C_CMD         command byte for access\r
---   D[7:0]   I2C_DATA        data to be written\r
---\r
---\r
-  \r
   -----------------------------------------------------------------------------\r
   -- Output Signals\r
   -----------------------------------------------------------------------------\r
 \r
-  -- I2c Outputs\r
+  -- I2C Outputs\r
   SDA_INOUT <= '0' when (sda_o = '0' or\r
                          sda_startstop = '0' or\r
-                         sda_sendbyte = '0')\r
+                         sda_sendbyte = '0' or\r
+                         sda_readbyte = '0')\r
                else 'Z';\r
   \r
   SCL_INOUT <= '0' when (scl_o = '0' or\r
                          scl_startstop = '0' or\r
-                         scl_sendbyte = '0')\r
+                         scl_sendbyte = '0' or\r
+                         scl_readbyte = '0')\r
                else 'Z';\r
 \r
   -- Slave Bus\r
diff --git a/nxyter/source/nx_i2c_readbyte.vhd b/nxyter/source/nx_i2c_readbyte.vhd
new file mode 100644 (file)
index 0000000..58a3197
--- /dev/null
@@ -0,0 +1,237 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+library work;\r
+use work.nxyter_components.all;\r
+\r
+\r
+entity nx_i2c_readbyte is\r
+  generic (\r
+    i2c_speed : unsigned(11 downto 0) := x"3e8"\r
+    );\r
+  port(\r
+    CLK_IN               : in  std_logic;\r
+    RESET_IN             : in  std_logic;\r
+\r
+    START_IN             : in  std_logic;\r
+    BYTE_OUT             : out std_logic_vector(7 downto 0);\r
+    SEQUENCE_DONE_OUT    : out std_logic;\r
+\r
+    -- I2C connections\r
+    SDA_OUT              : out std_logic;\r
+    SCL_OUT              : out std_logic;\r
+    SDA_IN               : in  std_logic\r
+    );\r
+end entity;\r
+\r
+architecture Behavioral of nx_i2c_readbyte is\r
+\r
+  -- Send Byte  \r
+  signal sda_o             : std_logic;\r
+  signal scl_o             : std_logic;\r
+  signal i2c_start         : std_logic;\r
+\r
+  signal sequence_done_o   : std_logic;\r
+  signal i2c_byte          : unsigned(7 downto 0);\r
+  signal bit_ctr           : unsigned(3 downto 0);\r
+  signal i2c_ack_o         : std_logic;\r
+  signal wait_timer_init    : unsigned(11 downto 0);\r
+\r
+  signal sequence_done_o_x : std_logic;\r
+  signal i2c_byte_x        : unsigned(7 downto 0);\r
+  signal bit_ctr_x         : unsigned(3 downto 0);\r
+  signal i2c_ack_o_x       : std_logic;\r
+  signal wait_timer_init_x : unsigned(11 downto 0);\r
+  \r
+  type STATES is (S_IDLE,\r
+                  S_INIT,\r
+                  S_INIT_WAIT,\r
+\r
+                  S_READ_BYTE,\r
+                  S_UNSET_SCL1,\r
+                  S_SET_SCL1,\r
+                  s_GET_BIT,\r
+                  S_SET_SCL2,\r
+                  S_UNSET_SCL2,\r
+                  S_NEXT_BIT,\r
+\r
+                  S_SET_ACK,\r
+                  S_ACK_SET_SCL,\r
+                  S_ACK_UNSET_SCL\r
+                  );\r
+  signal STATE, NEXT_STATE : STATES;\r
+  \r
+  -- Wait Timer\r
+  signal wait_timer_done    : std_logic;\r
+\r
+begin\r
+\r
+  -- Timer\r
+  nx_i2c_timer_1: nx_i2c_timer\r
+    port map (\r
+      CLK_IN         => CLK_IN,\r
+      RESET_IN       => RESET_IN,\r
+      TIMER_START_IN => wait_timer_init,\r
+      TIMER_DONE_OUT => wait_timer_done\r
+      );\r
+\r
+\r
+  PROC_READ_BYTE_TRANSFER: process(CLK_IN)\r
+  begin \r
+    if( rising_edge(CLK_IN) ) then\r
+      if( RESET_IN = '1' ) then\r
+        sequence_done_o  <= '0';\r
+        bit_ctr          <= (others => '0');\r
+        i2c_ack_o        <= '0';\r
+        wait_timer_init  <= (others => '0');\r
+        STATE            <= S_IDLE;\r
+      else\r
+        sequence_done_o  <= sequence_done_o_x;\r
+        i2c_byte         <= i2c_byte_x;\r
+        bit_ctr          <= bit_ctr_x;\r
+        i2c_ack_o        <= i2c_ack_o_x;\r
+        wait_timer_init  <= wait_timer_init_x;\r
+        STATE            <= NEXT_STATE;\r
+      end if;\r
+    end if;\r
+  end process PROC_READ_BYTE_TRANSFER;  \r
+  \r
+  PROC_READ_BYTE: process(STATE)\r
+  begin \r
+    sda_o              <= '1';\r
+    scl_o              <= '1';\r
+    sequence_done_o_x  <= '0';\r
+    i2c_byte_x         <= i2c_byte;\r
+    bit_ctr_x          <= bit_ctr;       \r
+    i2c_ack_o_x        <= i2c_ack_o;\r
+    wait_timer_init_x  <= (others => '0');\r
+    \r
+    case STATE is\r
+      when S_IDLE =>\r
+        if (START_IN = '1') then\r
+          sda_o       <= '0';\r
+          scl_o       <= '0';\r
+          i2c_byte_x  <= (others => '0');\r
+          NEXT_STATE  <= S_INIT;\r
+        else\r
+          NEXT_STATE <= S_IDLE;\r
+        end if;\r
+\r
+        -- INIT\r
+      when S_INIT =>\r
+        sda_o              <= '0';\r
+        scl_o              <= '0';\r
+        wait_timer_init_x  <= i2c_speed srl 1;\r
+        NEXT_STATE <= S_INIT_WAIT;\r
+\r
+      when S_INIT_WAIT =>\r
+        sda_o              <= '0';\r
+        scl_o              <= '0';\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE <= S_INIT_WAIT;\r
+        else\r
+          NEXT_STATE <= S_READ_BYTE;\r
+        end if;\r
+        \r
+        -- I2C Read byte\r
+      when S_READ_BYTE =>\r
+        scl_o             <= '0';\r
+        bit_ctr_x         <= x"7";\r
+        wait_timer_init_x <= i2c_speed srl 2;\r
+        NEXT_STATE        <= S_UNSET_SCL1;\r
+\r
+      when S_UNSET_SCL1 =>\r
+        scl_o <= '0';\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE <= S_UNSET_SCL1;\r
+        else\r
+          wait_timer_init_x <= i2c_speed srl 2;\r
+          NEXT_STATE <= S_SET_SCL1;\r
+        end if;\r
+\r
+      when S_SET_SCL1 =>\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE <= S_SET_SCL1;\r
+        else\r
+          wait_timer_init_x <= i2c_speed srl 2;\r
+          NEXT_STATE        <= S_GET_BIT;\r
+        end if;\r
+\r
+      when S_GET_BIT =>\r
+        i2c_byte_x(0)   <= SDA_IN;\r
+        NEXT_STATE      <= S_SET_SCL2;\r
+                \r
+      when S_SET_SCL2 =>\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE <= S_SET_SCL2;\r
+        else\r
+          wait_timer_init_x <= i2c_speed srl 2;\r
+          NEXT_STATE        <= S_UNSET_SCL2;\r
+        end if;\r
+        \r
+      when S_UNSET_SCL2 =>\r
+        scl_o <= '0';\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE <= S_UNSET_SCL2;\r
+        else\r
+          NEXT_STATE <= S_NEXT_BIT;\r
+        end if;\r
+        \r
+      when S_NEXT_BIT =>\r
+        scl_o <= '0';\r
+        if (bit_ctr > 0) then\r
+          bit_ctr_x          <= bit_ctr - 1;\r
+          i2c_byte_x         <= i2c_byte sll 1;\r
+          wait_timer_init_x  <= i2c_speed srl 2;\r
+          NEXT_STATE         <= S_UNSET_SCL1;\r
+        else\r
+          wait_timer_init_x  <= i2c_speed srl 2;\r
+          NEXT_STATE         <= S_SET_ACK;\r
+        end if;\r
+\r
+        -- I2C Send ACK Sequence (doesn't work, so just send a clock)\r
+      when S_SET_ACK =>\r
+        --sda_o <= '0';\r
+        scl_o <= '0';\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE <= S_SET_ACK;\r
+        else\r
+          wait_timer_init_x <= i2c_speed srl 1;\r
+          NEXT_STATE        <= S_ACK_SET_SCL;\r
+        end if;\r
+\r
+      when S_ACK_SET_SCL =>\r
+        -- sda_o <= '0';\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE <= S_ACK_SET_SCL;\r
+        else\r
+          wait_timer_init_x <= i2c_speed srl 2;\r
+          NEXT_STATE        <= S_ACK_UNSET_SCL;\r
+        end if; \r
+        \r
+      when S_ACK_UNSET_SCL =>\r
+        --sda_o <= '0';\r
+        scl_o <= '0';\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE <= S_ACK_UNSET_SCL;\r
+        else\r
+          sequence_done_o_x <= '1';\r
+          NEXT_STATE        <= S_IDLE;\r
+        end if;\r
+\r
+    end case;\r
+  end process PROC_READ_BYTE;\r
+\r
+  -----------------------------------------------------------------------------\r
+  -- Output Signals\r
+  -----------------------------------------------------------------------------\r
+\r
+  SEQUENCE_DONE_OUT <= sequence_done_o;\r
+  BYTE_OUT          <= i2c_byte;\r
+  \r
+  -- I2c Outputs\r
+  SDA_OUT <= sda_o;\r
+  SCL_OUT <= scl_o;\r
+  \r
+end Behavioral;\r
index daba5fd2e034467681badcbef405e9aba47f1c03..7b9c0fe8af3a27a0c6cf530ca9e6ea1bdac98491 100644 (file)
@@ -79,7 +79,6 @@ begin
   \r
   PROC_START_STOP: process(STATE)\r
   begin\r
-\r
     sda_o             <= '1';\r
     scl_o             <= '1';\r
     wait_timer_init_x <= (others => '0');\r
index 69b9fa6788b957794ce9afc725081b1d3aae2c1c..60f07c28b41a96163eca638e9e1c0132fccc09ee 100644 (file)
@@ -121,13 +121,15 @@ begin
 --   DEBUG_LINE_OUT(9)            <= i2c_sda_i;
 --   DEBUG_LINE_OUT(10)           <= i2c_scl_o;
 --   DEBUG_LINE_OUT(11)           <= i2c_scl_i;
---  DEBUG_LINE_OUT(15 downto 12) <= (others => '0');
-
-  DEBUG_LINE_OUT(0) <= CLK_IN;
-  DEBUG_LINE_OUT(1) <= I2C_SDA_INOUT;
-  DEBUG_LINE_OUT(2) <= I2C_SCL_INOUT;
-  
-  DEBUG_LINE_OUT(7 downto 3) <= (others => '0');
+--   DEBUG_LINE_OUT(15 downto 12) <= (others => '0');
+
+--   DEBUG_LINE_OUT(0) <= CLK_IN;
+--   DEBUG_LINE_OUT(1) <= I2C_SDA_INOUT;
+--   DEBUG_LINE_OUT(2) <= I2C_SCL_INOUT;
+--   DEBUG_LINE_OUT(3) <= i2c_sm_reset_o;
+--   DEBUG_LINE_OUT(4) <= i2c_reg_reset_o;
+--   
+--   DEBUG_LINE_OUT(5 downto 5) <= (others => '0');
   
 -------------------------------------------------------------------------------
 -- Port Maps
@@ -135,12 +137,12 @@ begin
 
 
 
-  -- pll_nx_clk256_1: pll_nx_clk256
-  --   port map (
-  --     CLK   => CLK_IN,
-  --     CLKOP => clk_256_o,
-  --     LOCK  => open
-  --     );
+  pll_nx_clk256_1: pll_nx_clk256
+    port map (
+      CLK   => CLK_IN,
+      CLKOP => clk_256_o,
+      LOCK  => open
+      );
 
   -- pll_25_1: pll_25
   --   port map (
@@ -148,7 +150,7 @@ begin
   --     CLKOP => clk_256_o,
   --     LOCK  => open
   --     );
-  clk_256_o      <= CLK_128_IN;
+  -- clk_256_o      <= CLK_128_IN;
 
   NX_RESET_OUT       <= '0';
   NX_CLK256A_OUT     <= clk_256_o;
@@ -283,13 +285,15 @@ begin
       SLV_ACK_OUT          => slv_ack(0),
       SLV_NO_MORE_DATA_OUT => slv_no_more_data(0),
       SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(0),
-
+      I2C_SM_RESET_OUT     => i2c_sm_reset_o,
+      I2C_REG_RESET_OUT    => i2c_reg_reset_o,
       DEBUG_OUT            => open
       );
 
 -------------------------------------------------------------------------------
 -- I2C master block for accessing the nXyter
 -------------------------------------------------------------------------------
+
   nx_i2c_master_1: nx_i2c_master
     generic map (
       i2c_speed => x"3e8"
@@ -306,35 +310,11 @@ begin
       SLV_ACK_OUT           => slv_ack(1), 
       SLV_NO_MORE_DATA_OUT  => slv_no_more_data(1),
       SLV_UNKNOWN_ADDR_OUT  => slv_unknown_addr(1),
-      DEBUG_OUT(7 downto 0) => DEBUG_LINE_OUT(15 downto 8)
+      DEBUG_OUT(13 downto 0) => DEBUG_LINE_OUT(13 downto 0)
+      --DEBUG_OUT             => open
       );
-
-
--- ADCM   i2c_master_1: i2c_master
--- ADCM     port map (
--- ADCM       CLK_IN       => CLK_IN,
--- ADCM       RESET_IN     => RESET_IN,
--- ADCM       SLV_READ_IN  => slv_read(1),
--- ADCM       SLV_WRITE_IN => slv_write(1),
--- ADCM       SLV_BUSY_OUT => open,
--- ADCM       SLV_ACK_OUT  => slv_ack(1),
--- ADCM       SLV_DATA_IN  => slv_data_wr(1*32+31 downto 1*32),
--- ADCM       SLV_DATA_OUT => slv_data_rd(1*32+31 downto 1*32),
--- ADCM       SDA_IN       => i2c_sda_i,
--- ADCM       SDA_OUT      => i2c_sda_o,
--- ADCM       SCL_IN       => i2c_scl_i,
--- ADCM       SCL_OUT      => i2c_scl_o,
--- ADCM       STAT         => open
--- ADCM       );
--- ADCM 
--- ADCM   -- I2c Outputs
--- ADCM   I2C_SDA_INOUT <= '0' when (i2c_sda_o = '0') else 'Z';
--- ADCM   i2c_sda_i     <= I2C_SDA_INOUT;
--- ADCM   I2C_SCL_INOUT <= '0' when (i2c_scl_o = '0') else 'Z';
--- ADCM   i2c_scl_i     <= I2C_SCL_INOUT;
-  
-  i2c_sm_reset_o    <= not '0';
-  i2c_reg_reset_o   <= not '0';
+  DEBUG_LINE_OUT(14) <= I2C_SDA_INOUT;
+  DEBUG_LINE_OUT(15) <= I2C_SCL_INOUT;
   
 -------------------------------------------------------------------------------
 -- nXyter TimeStamp Read
@@ -395,8 +375,8 @@ begin
 -- I2C Signals
 -------------------------------------------------------------------------------
 
-  I2C_SM_RESET_OUT  <= i2c_sm_reset_o;
-  I2C_REG_RESET_OUT <= i2c_reg_reset_o;
+  I2C_SM_RESET_OUT  <= not i2c_sm_reset_o;
+  I2C_REG_RESET_OUT <= not i2c_reg_reset_o;
 
 -------------------------------------------------------------------------------
 -- END
index cdb9ab56d30aefdb320db93edcbc3505ae984da8..5a56b94d4c32c5a31f82d3491780f444235f4645 100644 (file)
@@ -119,11 +119,26 @@ component nx_i2c_sendbyte
     );
 end component;
 
+component nx_i2c_readbyte
+  generic (
+    i2c_speed : unsigned(11 downto 0)
+    );
+  port (
+    CLK_IN            : in  std_logic;
+    RESET_IN          : in  std_logic;
+    START_IN          : in  std_logic;
+    BYTE_OUT          : out std_logic_vector(7 downto 0);
+    SEQUENCE_DONE_OUT : out std_logic;
+    SDA_OUT           : out std_logic;
+    SCL_OUT           : out std_logic;
+    SDA_IN            : in  std_logic
+    );
+end component;
+
 -------------------------------------------------------------------------------
 -- TRBNet Registers
 -------------------------------------------------------------------------------
 
-
 component nxyter_registers
   port (
     CLK_IN               : in  std_logic;
@@ -136,6 +151,8 @@ component nxyter_registers
     SLV_ACK_OUT          : out std_logic;
     SLV_NO_MORE_DATA_OUT : out std_logic;
     SLV_UNKNOWN_ADDR_OUT : out std_logic;
+    I2C_SM_RESET_OUT     : out std_logic;
+    I2C_REG_RESET_OUT    : out std_logic;
     DEBUG_OUT            : out std_logic_vector(15 downto 0)
     );
 end component;
index fc5290eb8892ec4f8d41c32b258ad967b0fd5231..c287f7cb089b797626186236874137184345ccfd 100644 (file)
@@ -4,6 +4,7 @@ use IEEE.STD_LOGIC_ARITH.ALL;
 use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
 \r
 library work;\r
+use work.nxyter_components.all;\r
 \r
 entity nxyter_registers is\r
   port(\r
@@ -19,6 +20,11 @@ entity nxyter_registers is
     SLV_ACK_OUT          : out std_logic;\r
     SLV_NO_MORE_DATA_OUT : out std_logic;\r
     SLV_UNKNOWN_ADDR_OUT : out std_logic;\r
+\r
+    -- Signals\r
+    I2C_SM_RESET_OUT     : out std_logic;\r
+    I2C_REG_RESET_OUT    : out std_logic;\r
+\r
     DEBUG_OUT            : out std_logic_vector(15 downto 0)\r
     );\r
 end entity;\r
@@ -30,40 +36,140 @@ architecture Behavioral of nxyter_registers is
   signal slv_unknown_addr_o : std_logic;\r
   signal slv_ack_o          : std_logic;\r
 \r
+\r
+  -- I2C Reset\r
+  signal i2c_sm_reset_start  : std_logic;\r
+  signal i2c_reg_reset_start : std_logic;\r
+  signal wait_timer_init_x   : unsigned(7 downto 0);\r
+  signal i2c_sm_reset_o      : std_logic;\r
+  signal i2c_reg_reset_o     : std_logic;\r
+  \r
+  type STATES is (S_IDLE,\r
+                  S_I2C_SM_RESET,\r
+                  S_I2C_SM_RESET_WAIT,\r
+                  S_I2C_REG_RESET,\r
+                  S_I2C_REG_RESET_WAIT\r
+                  );\r
+  \r
+  signal STATE, NEXT_STATE : STATES;\r
+  \r
+  -- Wait Timer\r
+  signal wait_timer_init    : unsigned(7 downto 0);\r
+  signal wait_timer_done    : std_logic;\r
+  \r
   type reg_32bit_t is array (0 to 7) of std_logic_vector(31 downto 0);\r
   signal reg_data   : reg_32bit_t;\r
   \r
 begin\r
 \r
   DEBUG_OUT  <= reg_data(0)(15 downto 0);\r
+\r
+  nx_i2c_timer_1: nx_i2c_timer\r
+    port map (\r
+      CLK_IN                      => CLK_IN,\r
+      RESET_IN                    => RESET_IN,\r
+      TIMER_START_IN(7 downto 0)  => wait_timer_init,\r
+      TIMER_START_IN(11 downto 8) => open,\r
+      TIMER_DONE_OUT              => wait_timer_done\r
+      );\r
+  -----------------------------------------------------------------------------\r
+  -- I2C SM Reset\r
+  -----------------------------------------------------------------------------\r
+\r
+  PROC_I2C_SM_RESET_TRANSFER: process(CLK_IN)\r
+  begin \r
+    if( rising_edge(CLK_IN) ) then\r
+      if( RESET_IN = '1' ) then\r
+        wait_timer_init  <= (others => '0');\r
+        STATE            <= S_IDLE;\r
+      else\r
+        wait_timer_init  <= wait_timer_init_x;\r
+        STATE            <= NEXT_STATE;\r
+      end if;\r
+    end if;\r
+  end process PROC_I2C_SM_RESET_TRANSFER;\r
+\r
+  PROC_I2C_SM_RESET: process(STATE)\r
+  begin\r
+    i2c_sm_reset_o     <= '0';\r
+    i2c_reg_reset_o    <= '0';\r
+    wait_timer_init_x  <= (others => '0');\r
+    \r
+    case STATE is\r
+      when S_IDLE =>\r
+        if (i2c_sm_reset_start = '1') then\r
+          NEXT_STATE       <= S_I2C_SM_RESET;\r
+        elsif (i2c_reg_reset_start = '1') then\r
+          NEXT_STATE       <= S_I2C_REG_RESET;\r
+        else\r
+          NEXT_STATE       <= S_IDLE;\r
+        end if;\r
+        \r
+      when S_I2C_SM_RESET =>\r
+        i2c_sm_reset_o     <= '1';\r
+        wait_timer_init_x  <= x"8f";\r
+        NEXT_STATE         <= S_I2C_SM_RESET_WAIT;\r
+\r
+      when S_I2C_SM_RESET_WAIT =>\r
+        i2c_sm_reset_o    <= '1';\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE       <= S_I2C_SM_RESET_WAIT;\r
+        else\r
+          NEXT_STATE       <= S_IDLE;\r
+        end if;\r
+\r
+      when S_I2C_REG_RESET =>\r
+        i2c_reg_reset_o    <= '1';\r
+        wait_timer_init_x  <= x"8f";\r
+        NEXT_STATE         <= S_I2C_REG_RESET_WAIT;\r
+\r
+      when S_I2C_REG_RESET_WAIT =>\r
+        i2c_reg_reset_o    <= '1';\r
+        if (wait_timer_done = '0') then\r
+          NEXT_STATE       <= S_I2C_REG_RESET_WAIT;\r
+        else\r
+          NEXT_STATE       <= S_IDLE;\r
+        end if;\r
+\r
+    end case;\r
+  end process PROC_I2C_SM_RESET;\r
+\r
+  -----------------------------------------------------------------------------\r
+  -- Slave Bus\r
+  -----------------------------------------------------------------------------\r
   \r
   PROC_NX_REGISTERS: process(CLK_IN)\r
   begin\r
     if( rising_edge(CLK_IN) ) then\r
       if( RESET_IN = '1' ) then\r
-        reg_data(0) <= x"babe_0000";\r
-        reg_data(1) <= x"babe_0001";\r
-        reg_data(2) <= x"babe_0002";\r
-        reg_data(3) <= x"babe_0003";\r
-        reg_data(4) <= x"babe_0004";\r
-        reg_data(5) <= x"babe_0005";\r
-        reg_data(6) <= x"babe_0006";\r
-        reg_data(7) <= x"babe_0007";\r
-\r
-        slv_data_out_o     <= (others => '0');\r
-        slv_no_more_data_o <= '0';\r
-        slv_unknown_addr_o <= '0';\r
-        slv_ack_o          <= '0';\r
+        reg_data(0)         <= x"babe_0000";\r
+        reg_data(1)         <= x"babe_0001";\r
+        reg_data(2)         <= x"babe_0002";\r
+        reg_data(3)         <= x"babe_0003";\r
+        reg_data(4)         <= x"babe_0004";\r
+        reg_data(5)         <= x"babe_0005";\r
+        reg_data(6)         <= x"babe_0006";\r
+        reg_data(7)         <= x"babe_0007";\r
+\r
+        slv_data_out_o      <= (others => '0');\r
+        slv_no_more_data_o  <= '0';\r
+        slv_unknown_addr_o  <= '0';\r
+        slv_ack_o           <= '0';\r
+        \r
+        i2c_sm_reset_start  <= '0';\r
+        i2c_reg_reset_start <= '0';\r
       else\r
         slv_ack_o <= '1';\r
-        slv_unknown_addr_o <= '0';\r
-        slv_no_more_data_o <= '0';\r
-        slv_data_out_o     <= (others => '0');    \r
+        slv_unknown_addr_o  <= '0';\r
+        slv_no_more_data_o  <= '0';\r
+        slv_data_out_o      <= (others => '0');    \r
+        i2c_sm_reset_start  <= '0';\r
+        i2c_reg_reset_start <= '0';\r
 \r
         if (SLV_WRITE_IN  = '1') then\r
           case SLV_ADDR_IN is\r
-            when x"0000" => reg_data(0) <= SLV_DATA_IN;\r
-            when x"0001" => reg_data(1) <= SLV_DATA_IN;\r
+            when x"0000" => i2c_sm_reset_start <= '1';\r
+            when x"0001" => i2c_reg_reset_start <= '1';\r
             when x"0002" => reg_data(2) <= SLV_DATA_IN;\r
             when x"0003" => reg_data(3) <= SLV_DATA_IN;\r
             when x"0004" => reg_data(4) <= SLV_DATA_IN;\r
@@ -101,4 +207,7 @@ begin
   SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o;\r
   SLV_ACK_OUT          <= slv_ack_o;          \r
 \r
+  I2C_SM_RESET_OUT     <= i2c_sm_reset_o;\r
+  I2C_REG_RESET_OUT    <= i2c_reg_reset_o;\r
+\r
 end Behavioral;\r