]> jspc29.x-matter.uni-frankfurt.de Git - vhdlbasics.git/commitdiff
direct I2C access blackcat
authorMichael Boehmer <mboehmer@ph.tum.de>
Wed, 9 Nov 2022 14:06:09 +0000 (15:06 +0100)
committerMichael Boehmer <mboehmer@ph.tum.de>
Wed, 9 Nov 2022 14:06:09 +0000 (15:06 +0100)
interface/i2c_gstart.vhd
interface/i2c_sendb.vhd
interface/i2c_slim2.vhd

index a8b3119216e09e465287787184f0020bfed04dab..e4316e8e611955db8273199b42cfaed08c0f3362 100644 (file)
@@ -8,20 +8,20 @@ use IEEE.STD_LOGIC_UNSIGNED.ALL;
 \r
 entity I2C_GSTART is\r
 port(\r
-       CLK_IN          : in    std_logic;\r
-       RESET_IN        : in    std_logic;\r
-       START_IN        : in    std_logic;\r
-       DOSTART_IN      : in    std_logic;\r
-       I2C_SPEED_IN    : in    std_logic_vector(8 downto 0);\r
-       SDONE_OUT       : out   std_logic;\r
-       SOK_OUT         : out   std_logic;\r
-       SDA_IN          : in    std_logic;\r
-       SCL_IN          : in    std_logic;\r
-       R_SCL_OUT       : out   std_logic;\r
-       S_SCL_OUT       : out   std_logic;\r
-       R_SDA_OUT       : out   std_logic;\r
-       S_SDA_OUT       : out   std_logic;\r
-       BSM_OUT         : out   std_logic_vector(3 downto 0)\r
+  CLK_IN          : in    std_logic;\r
+  RESET_IN        : in    std_logic;\r
+  START_IN        : in    std_logic;\r
+  DOSTART_IN      : in    std_logic;\r
+  I2C_SPEED_IN    : in    std_logic_vector(8 downto 0);\r
+  SDONE_OUT       : out   std_logic;\r
+  SOK_OUT         : out   std_logic;\r
+  SDA_IN          : in    std_logic;\r
+  SCL_IN          : in    std_logic;\r
+  R_SCL_OUT       : out   std_logic;\r
+  S_SCL_OUT       : out   std_logic;\r
+  R_SDA_OUT       : out   std_logic;\r
+  S_SDA_OUT       : out   std_logic;\r
+  BSM_OUT         : out   std_logic_vector(3 downto 0)\r
 );\r
 end entity;\r
 \r
@@ -46,14 +46,14 @@ signal sdone        : std_logic; -- Start/Stop done
 signal sok_x        : std_logic;\r
 signal sok          : std_logic; -- Start/Stop OK\r
 \r
-signal r_scl_x                 : std_logic;\r
-signal r_scl                           : std_logic;\r
-signal s_scl_x                 : std_logic;\r
-signal s_scl                           : std_logic;\r
-signal r_sda_x                 : std_logic;\r
-signal r_sda                           : std_logic;\r
-signal s_sda_x                 : std_logic;\r
-signal s_sda                           : std_logic;\r
+signal r_scl_x      : std_logic;\r
+signal r_scl        : std_logic;\r
+signal s_scl_x      : std_logic;\r
+signal s_scl        : std_logic;\r
+signal r_sda_x      : std_logic;\r
+signal r_sda        : std_logic;\r
+signal s_sda_x      : std_logic;\r
+signal s_sda        : std_logic;\r
 \r
 -- Moduls\r
 \r
@@ -62,15 +62,15 @@ begin
 -- Countdown for one half of SCL (adjustable clock width)\r
 THE_CYC_CTR_PROC: process( clk_in )\r
 begin\r
-       if( rising_edge(clk_in) ) then\r
-               if( reset_in = '1' ) then\r
-                       cctr <= (others => '0');\r
-               elsif( load_cyc = '1' ) then\r
-                       cctr <= i2c_speed_in;\r
-               elsif( dec_cyc = '1' ) then\r
-                       cctr <= cctr - 1;\r
-               end if;\r
-       end if;\r
+  if( rising_edge(clk_in) ) then\r
+    if( reset_in = '1' ) then\r
+      cctr <= (others => '0');\r
+    elsif( load_cyc = '1' ) then\r
+      cctr <= i2c_speed_in;\r
+    elsif( dec_cyc = '1' ) then\r
+      cctr <= cctr - 1;\r
+    end if;\r
+  end if;\r
 end process THE_CYC_CTR_PROC;\r
 \r
 -- end of cycle recognition\r
@@ -80,154 +80,154 @@ cycdone_x <= '1' when (cctr = x"00") else '0';
 -- State memory process\r
 STATE_MEM: process( clk_in )\r
 begin\r
-       if ( rising_edge(clk_in) ) then\r
-               if( reset_in = '1' ) then\r
-                       CURRENT_STATE <= SLEEP;\r
-                       load_cyc      <= '0';\r
-                       dec_cyc       <= '0';\r
-                       sdone         <= '0';\r
-                       sok           <= '0';\r
-                       cycdone       <= '0';\r
-                       r_scl         <= '0';\r
-                       s_scl         <= '0';\r
-                       r_sda         <= '0';\r
-                       s_sda         <= '0';\r
-               else\r
-                       CURRENT_STATE <= NEXT_STATE;\r
-                       load_cyc      <= load_cyc_x;\r
-                       dec_cyc       <= dec_cyc_x;\r
-                       sdone         <= sdone_x;\r
-                       sok           <= sok_x;\r
-                       cycdone       <= cycdone_x;\r
-                       r_scl         <= r_scl_x;\r
-                       s_scl         <= s_scl_x;\r
-                       r_sda         <= r_sda_x;\r
-                       s_sda         <= s_sda_x;\r
-               end if;\r
-       end if;\r
+  if ( rising_edge(clk_in) ) then\r
+    if( reset_in = '1' ) then\r
+      CURRENT_STATE <= SLEEP;\r
+      load_cyc      <= '0';\r
+      dec_cyc       <= '0';\r
+      sdone         <= '0';\r
+      sok           <= '0';\r
+      cycdone       <= '0';\r
+      r_scl         <= '0';\r
+      s_scl         <= '0';\r
+      r_sda         <= '0';\r
+      s_sda         <= '0';\r
+    else\r
+      CURRENT_STATE <= NEXT_STATE;\r
+      load_cyc      <= load_cyc_x;\r
+      dec_cyc       <= dec_cyc_x;\r
+      sdone         <= sdone_x;\r
+      sok           <= sok_x;\r
+      cycdone       <= cycdone_x;\r
+      r_scl         <= r_scl_x;\r
+      s_scl         <= s_scl_x;\r
+      r_sda         <= r_sda_x;\r
+      s_sda         <= s_sda_x;\r
+    end if;\r
+  end if;\r
 end process STATE_MEM;\r
 \r
 -- Transition matrix\r
 TRANSFORM: process(CURRENT_STATE, dostart_in, start_in, sda_in, scl_in, cycdone)\r
 begin\r
-       NEXT_STATE <= SLEEP;\r
-       load_cyc_x <= '0';\r
-       dec_cyc_x  <= '0';\r
-       sdone_x    <= '0';\r
-       sok_x      <= '1';\r
-       r_sda_x    <= '0';\r
-       s_sda_x    <= '0';\r
-       r_scl_x    <= '0';\r
-       s_scl_x    <= '0';\r
-       case CURRENT_STATE is\r
-               when SLEEP =>  \r
-                               if   ( (dostart_in = '1') and (start_in = '1') ) then\r
-                                       NEXT_STATE <= S_CHK0; -- generate a start condition\r
-                                       load_cyc_x <= '1';\r
-                               elsif( (dostart_in = '1') and (start_in = '0') ) then\r
-                                       NEXT_STATE <= WCTR2; -- generate a stop condition\r
-                                       load_cyc_x <= '1';\r
-                               else\r
-                                       NEXT_STATE <= SLEEP;\r
---                                     load_cyc_x <= '1';\r
-                               end if;\r
-               when WCTR2 =>\r
-                               if( (cycdone = '1') ) then\r
-                                       NEXT_STATE <= P_SCL;\r
-                                       load_cyc_x <= '1';\r
-                                       s_scl_x    <= '1';\r
-                               else\r
-                                       NEXT_STATE <= WCTR2;\r
-                                       dec_cyc_x  <= '1';\r
-                               end if;\r
-               when P_SCL => \r
-                               NEXT_STATE <= WCTR0;\r
-                               dec_cyc_x  <= '1';\r
-               when S_CHK0 =>\r
-                               if( (sda_in = '1') and (scl_in = '1') ) then\r
-                                       NEXT_STATE <= RS_SDA;\r
-                                       r_sda_x    <= '1';\r
-                               else\r
-                                       NEXT_STATE <= ERROR;\r
-                                       sok_x      <= '0';\r
-                               end if;\r
-               when RS_SDA =>\r
-                               NEXT_STATE <= WCTR0;\r
-                               dec_cyc_x  <= '1';\r
-               when WCTR0 =>\r
-                               if   ( (cycdone = '1') and (start_in = '1') ) then\r
-                                       NEXT_STATE <= S_CHK1;\r
-                               elsif( (cycdone = '1') and (start_in = '0') ) then\r
-                                       NEXT_STATE <= P_SDA;\r
-                                       load_cyc_x <= '1';\r
-                                       s_sda_x    <= '1';\r
-                               else\r
-                                       NEXT_STATE <= WCTR0;\r
-                                       dec_cyc_x  <= '1';\r
-                               end if;\r
-               when S_CHK1 =>\r
-                               if( (sda_in = '0') and (scl_in = '1') ) then\r
-                                       NEXT_STATE <= DONE;\r
-                               else\r
-                                       NEXT_STATE <= ERROR;\r
-                                       sok_x      <= '0';\r
-                               end if;\r
-               when P_SDA =>\r
-                               NEXT_STATE <= WCTR1;\r
-                               dec_cyc_x  <= '1';\r
-               when WCTR1 =>\r
-                               if( (cycdone = '1') ) then\r
-                                       NEXT_STATE <= P_CHK;\r
-                               else\r
-                                       NEXT_STATE <= WCTR1;\r
-                                       dec_cyc_x  <= '1';\r
-                               end if;\r
-               when P_CHK =>\r
-                               if( (sda_in = '1') and (scl_in = '1') ) then\r
-                                       NEXT_STATE <= DONE;\r
-                                       sdone_x    <= '1';\r
-                               else\r
-                                       NEXT_STATE <= ERROR;\r
-                                       sok_x      <= '0';\r
-                               end if;\r
-               when ERROR =>\r
-                               if( dostart_in = '0' ) then\r
-                                       NEXT_STATE <= SLEEP;\r
-                               else\r
-                                       NEXT_STATE <= ERROR;\r
-                                       sdone_x    <= '1';\r
-                                       sok_x      <= '0';\r
-                               end if;\r
-               when DONE =>\r
-                               if( dostart_in = '0' ) then\r
-                                       NEXT_STATE <= SLEEP;\r
-                               else\r
-                                       NEXT_STATE <= DONE;\r
-                                       sdone_x    <= '1';\r
-                               end if;\r
-               when others =>\r
-                               NEXT_STATE <= SLEEP;\r
-       end case;\r
+  NEXT_STATE <= SLEEP;\r
+  load_cyc_x <= '0';\r
+  dec_cyc_x  <= '0';\r
+  sdone_x    <= '0';\r
+  sok_x      <= '1';\r
+  r_sda_x    <= '0';\r
+  s_sda_x    <= '0';\r
+  r_scl_x    <= '0';\r
+  s_scl_x    <= '0';\r
+  case CURRENT_STATE is\r
+    when SLEEP =>  \r
+        if   ( (dostart_in = '1') and (start_in = '1') ) then\r
+          NEXT_STATE <= S_CHK0; -- generate a start condition\r
+          load_cyc_x <= '1';\r
+        elsif( (dostart_in = '1') and (start_in = '0') ) then\r
+          NEXT_STATE <= WCTR2; -- generate a stop condition\r
+          load_cyc_x <= '1';\r
+        else\r
+          NEXT_STATE <= SLEEP;\r
+--          load_cyc_x <= '1';\r
+        end if;\r
+    when WCTR2 =>\r
+        if( (cycdone = '1') ) then\r
+          NEXT_STATE <= P_SCL;\r
+          load_cyc_x <= '1';\r
+          s_scl_x    <= '1';\r
+        else\r
+          NEXT_STATE <= WCTR2;\r
+          dec_cyc_x  <= '1';\r
+        end if;\r
+    when P_SCL => \r
+        NEXT_STATE <= WCTR0;\r
+        dec_cyc_x  <= '1';\r
+    when S_CHK0 =>\r
+        if( (sda_in = '1') and (scl_in = '1') ) then\r
+          NEXT_STATE <= RS_SDA;\r
+          r_sda_x    <= '1';\r
+        else\r
+          NEXT_STATE <= ERROR;\r
+          sok_x      <= '0';\r
+        end if;\r
+    when RS_SDA =>\r
+        NEXT_STATE <= WCTR0;\r
+        dec_cyc_x  <= '1';\r
+    when WCTR0 =>\r
+        if   ( (cycdone = '1') and (start_in = '1') ) then\r
+          NEXT_STATE <= S_CHK1;\r
+        elsif( (cycdone = '1') and (start_in = '0') ) then\r
+          NEXT_STATE <= P_SDA;\r
+          load_cyc_x <= '1';\r
+          s_sda_x    <= '1';\r
+        else\r
+          NEXT_STATE <= WCTR0;\r
+          dec_cyc_x  <= '1';\r
+        end if;\r
+    when S_CHK1 =>\r
+        if( (sda_in = '0') and (scl_in = '1') ) then\r
+          NEXT_STATE <= DONE;\r
+        else\r
+          NEXT_STATE <= ERROR;\r
+          sok_x      <= '0';\r
+        end if;\r
+    when P_SDA =>\r
+        NEXT_STATE <= WCTR1;\r
+        dec_cyc_x  <= '1';\r
+    when WCTR1 =>\r
+        if( (cycdone = '1') ) then\r
+          NEXT_STATE <= P_CHK;\r
+        else\r
+          NEXT_STATE <= WCTR1;\r
+          dec_cyc_x  <= '1';\r
+        end if;\r
+    when P_CHK =>\r
+        if( (sda_in = '1') and (scl_in = '1') ) then\r
+          NEXT_STATE <= DONE;\r
+          sdone_x    <= '1';\r
+        else\r
+          NEXT_STATE <= ERROR;\r
+          sok_x      <= '0';\r
+        end if;\r
+    when ERROR =>\r
+        if( dostart_in = '0' ) then\r
+          NEXT_STATE <= SLEEP;\r
+        else\r
+          NEXT_STATE <= ERROR;\r
+          sdone_x    <= '1';\r
+          sok_x      <= '0';\r
+        end if;\r
+    when DONE =>\r
+        if( dostart_in = '0' ) then\r
+          NEXT_STATE <= SLEEP;\r
+        else\r
+          NEXT_STATE <= DONE;\r
+          sdone_x    <= '1';\r
+        end if;\r
+    when others =>\r
+        NEXT_STATE <= SLEEP;\r
+  end case;\r
 end process TRANSFORM;\r
 \r
 -- Output decoding\r
 DECODE: process(CURRENT_STATE)\r
 begin\r
-       case CURRENT_STATE is\r
-               when SLEEP  =>  bsm <= x"0";\r
-               when S_CHK0 =>  bsm <= x"1";\r
-               when RS_SDA =>  bsm <= x"2";\r
-               when P_SCL  =>  bsm <= x"3";\r
-               when WCTR0  =>  bsm <= x"4";\r
-               when S_CHK1 =>  bsm <= x"5";\r
-               when P_SDA  =>  bsm <= x"6";\r
-               when WCTR1  =>  bsm <= x"7";\r
-               when P_CHK  =>  bsm <= x"8";\r
-               when DONE   =>  bsm <= x"9";\r
-               when WCTR2  =>  bsm <= x"a";\r
-               when ERROR  =>  bsm <= x"e";\r
-               when others =>  bsm <= x"f";\r
-       end case;\r
+  case CURRENT_STATE is\r
+    when SLEEP  =>  bsm <= x"0";\r
+    when S_CHK0 =>  bsm <= x"1";\r
+    when RS_SDA =>  bsm <= x"2";\r
+    when P_SCL  =>  bsm <= x"3";\r
+    when WCTR0  =>  bsm <= x"4";\r
+    when S_CHK1 =>  bsm <= x"5";\r
+    when P_SDA  =>  bsm <= x"6";\r
+    when WCTR1  =>  bsm <= x"7";\r
+    when P_CHK  =>  bsm <= x"8";\r
+    when DONE   =>  bsm <= x"9";\r
+    when WCTR2  =>  bsm <= x"a";\r
+    when ERROR  =>  bsm <= x"e";\r
+    when others =>  bsm <= x"f";\r
+  end case;\r
 end process DECODE;\r
 \r
 -- Outputs\r
index be4e338eaf63e99820e05bf9d29eefa6169f4950..6adf91e49c097336e1e02b8f0e710247b7c5ac7c 100644 (file)
@@ -5,21 +5,21 @@ use IEEE.STD_LOGIC_UNSIGNED.ALL;
 \r
 entity i2c_sendb is\r
 port(\r
-       CLK_IN          : in    std_logic;\r
-       RESET_IN        : in    std_logic;\r
-       DOBYTE_IN       : in    std_logic;\r
-       I2C_SPEED_IN    : in    std_logic_vector(8 downto 0);\r
-       I2C_BYTE_IN     : in    std_logic_vector(8 downto 0);\r
-       I2C_BACK_OUT    : out   std_logic_vector(8 downto 0);\r
-       SDA_IN          : in    std_logic;\r
-       R_SDA_OUT       : out   std_logic;\r
-       S_SDA_OUT       : out   std_logic;\r
+  CLK_IN          : in    std_logic;\r
+  RESET_IN        : in    std_logic;\r
+  DOBYTE_IN       : in    std_logic;\r
+  I2C_SPEED_IN    : in    std_logic_vector(8 downto 0);\r
+  I2C_BYTE_IN     : in    std_logic_vector(8 downto 0);\r
+  I2C_BACK_OUT    : out   std_logic_vector(8 downto 0);\r
+  SDA_IN          : in    std_logic;\r
+  R_SDA_OUT       : out   std_logic;\r
+  S_SDA_OUT       : out   std_logic;\r
 --  SCL_IN          : in    std_logic;\r
-       R_SCL_OUT       : out   std_logic;\r
-       S_SCL_OUT       : out   std_logic;\r
-       BDONE_OUT       : out   std_logic;\r
-       BOK_OUT         : out   std_logic;\r
-       BSM_OUT         : out   std_logic_vector(3 downto 0)\r
+  R_SCL_OUT       : out   std_logic;\r
+  S_SCL_OUT       : out   std_logic;\r
+  BDONE_OUT       : out   std_logic;\r
+  BOK_OUT         : out   std_logic;\r
+  BSM_OUT         : out   std_logic_vector(3 downto 0)\r
 );\r
 end entity;\r
 \r
@@ -72,15 +72,15 @@ begin
 -- Bit counter  (for byte to send)\r
 THE_BIT_CTR_PROC: process( clk_in )\r
 begin\r
-       if( rising_edge(clk_in) ) then\r
-               if( reset_in = '1' ) then\r
-                       bctr <= (others => '0');\r
-               elsif( rst_bit = '1' ) then\r
-                       bctr <= (others => '0');\r
-               elsif( inc_bit = '1' ) then\r
-                       bctr <= bctr + 1;\r
-               end if;\r
-       end if;\r
+  if( rising_edge(clk_in) ) then\r
+    if( reset_in = '1' ) then\r
+      bctr <= (others => '0');\r
+    elsif( rst_bit = '1' ) then\r
+      bctr <= (others => '0');\r
+    elsif( inc_bit = '1' ) then\r
+      bctr <= bctr + 1;\r
+    end if;\r
+  end if;\r
 end process THE_BIT_CTR_PROC;\r
 \r
 -- end of byte recognition\r
@@ -89,15 +89,15 @@ bytedone <= '1' when (bctr = x"9") else '0';
 -- Countdown for one half of SCL (adjustable clock width)\r
 THE_CYC_CTR_PROC: process( clk_in )\r
 begin\r
-       if( rising_edge(clk_in) ) then\r
-               if( reset_in = '1' ) then\r
-                       cctr <= (others => '0');\r
-               elsif( load_cyc = '1' ) then\r
-                       cctr <= i2c_speed_in;\r
-               elsif( dec_cyc = '1' ) then\r
-                       cctr <= cctr - 1;\r
-               end if;\r
-       end if;\r
+  if( rising_edge(clk_in) ) then\r
+    if( reset_in = '1' ) then\r
+      cctr <= (others => '0');\r
+    elsif( load_cyc = '1' ) then\r
+      cctr <= i2c_speed_in;\r
+    elsif( dec_cyc = '1' ) then\r
+      cctr <= cctr - 1;\r
+    end if;\r
+  end if;\r
 end process THE_CYC_CTR_PROC;\r
 \r
 -- end of cycle recognition\r
@@ -106,44 +106,44 @@ cycdone <= '1' when (cctr = x"00") else '0';
 -- Bit output\r
 THE_BIT_OUT_PROC: process( clk_in )\r
 begin\r
-       if( rising_edge(clk_in) ) then\r
-               if( reset_in = '1' ) then\r
-                       out_sr <= (others => '0');\r
-                       i2c_d <= '1';\r
-               elsif( load_sr = '1' ) then\r
-                       out_sr <= i2c_byte_in;\r
-                       i2c_d  <= '1';\r
-               elsif( shift_o = '1' ) then\r
-                       i2c_d <= out_sr(8);\r
-                       out_sr(8 downto 0) <= out_sr(7 downto 0) & '0';\r
-               end if;\r
-       end if;\r
+  if( rising_edge(clk_in) ) then\r
+    if( reset_in = '1' ) then\r
+      out_sr <= (others => '0');\r
+      i2c_d <= '1';\r
+    elsif( load_sr = '1' ) then\r
+      out_sr <= i2c_byte_in;\r
+      i2c_d  <= '1';\r
+    elsif( shift_o = '1' ) then\r
+      i2c_d <= out_sr(8);\r
+      out_sr(8 downto 0) <= out_sr(7 downto 0) & '0';\r
+    end if;\r
+  end if;\r
 end process THE_BIT_OUT_PROC;\r
 \r
 -- Bit input\r
 THE_BIT_IN_PROC: process( clk_in )\r
 begin\r
-       if( rising_edge(clk_in) ) then\r
-               if   ( reset_in = '1' ) then\r
-                       in_sr <= (others => '1');\r
-               elsif( shift_o = '1' ) then\r
-                       in_sr(8 downto 1) <= in_sr(7 downto 0);\r
-                       in_sr(0) <= sda_in;\r
-               end if;\r
-       end if;\r
+  if( rising_edge(clk_in) ) then\r
+    if   ( reset_in = '1' ) then\r
+      in_sr <= (others => '1');\r
+    elsif( shift_o = '1' ) then\r
+      in_sr(8 downto 1) <= in_sr(7 downto 0);\r
+      in_sr(0) <= sda_in;\r
+    end if;\r
+  end if;\r
 end process THE_BIT_IN_PROC;\r
 \r
 -- Output register for readback data (could be reduced to SR_IN_INT)\r
 THE_I2C_BACK_PROC: process( clk_in )\r
 begin\r
-       if( rising_edge(clk_in) ) then\r
-               if( reset_in = '1' ) then\r
-                       i2c_back <= (others => '1');\r
-               elsif( shift_i = '1' ) then\r
-                       i2c_back(8 downto 1) <= in_sr(7 downto 0);\r
-                       i2c_back(0) <= sda_in;\r
-               end if;\r
-       end if;\r
+  if( rising_edge(clk_in) ) then\r
+    if( reset_in = '1' ) then\r
+      i2c_back <= (others => '1');\r
+    elsif( shift_i = '1' ) then\r
+      i2c_back(8 downto 1) <= in_sr(7 downto 0);\r
+      i2c_back(0) <= sda_in;\r
+    end if;\r
+  end if;\r
 end process THE_I2C_BACK_PROC;\r
 \r
 -- ByteOK is the inverted ACK bit from readback data.\r
@@ -153,131 +153,131 @@ bok <= not i2c_back(0); -- BUG
 -- State memory process\r
 STATE_MEM: process( clk_in )\r
 begin\r
-       if( rising_edge(clk_in) ) then\r
-               if( reset_in = '1') then\r
-                       CURRENT_STATE <= SLEEP;\r
-                       inc_bit       <= '0';\r
-                       rst_bit       <= '0';\r
-                       load_cyc      <= '0';\r
-                       dec_cyc       <= '0';\r
-                       load_sr       <= '0';\r
-                       shift_o       <= '0';\r
-                       shift_i       <= '0';\r
-                       bdone         <= '0';\r
-                       r_scl         <= '0';\r
-                       s_scl         <= '0';\r
-               else\r
-                       CURRENT_STATE <= NEXT_STATE;\r
-                       inc_bit       <= inc_bit_x;\r
-                       rst_bit       <= rst_bit_x;\r
-                       load_cyc      <= load_cyc_x;\r
-                       dec_cyc       <= dec_cyc_x;\r
-                       load_sr       <= load_sr_x;\r
-                       shift_o       <= shift_o_x;\r
-                       shift_i       <= shift_i_x;\r
-                       bdone         <= bdone_x;\r
-                       r_scl         <= r_scl_x;\r
-                       s_scl         <= s_scl_x;\r
-               end if;\r
-       end if;\r
+  if( rising_edge(clk_in) ) then\r
+    if( reset_in = '1') then\r
+      CURRENT_STATE <= SLEEP;\r
+      inc_bit       <= '0';\r
+      rst_bit       <= '0';\r
+      load_cyc      <= '0';\r
+      dec_cyc       <= '0';\r
+      load_sr       <= '0';\r
+      shift_o       <= '0';\r
+      shift_i       <= '0';\r
+      bdone         <= '0';\r
+      r_scl         <= '0';\r
+      s_scl         <= '0';\r
+    else\r
+      CURRENT_STATE <= NEXT_STATE;\r
+      inc_bit       <= inc_bit_x;\r
+      rst_bit       <= rst_bit_x;\r
+      load_cyc      <= load_cyc_x;\r
+      dec_cyc       <= dec_cyc_x;\r
+      load_sr       <= load_sr_x;\r
+      shift_o       <= shift_o_x;\r
+      shift_i       <= shift_i_x;\r
+      bdone         <= bdone_x;\r
+      r_scl         <= r_scl_x;\r
+      s_scl         <= s_scl_x;\r
+    end if;\r
+  end if;\r
 end process STATE_MEM;\r
 \r
 -- Transition matrix\r
 TRANSFORM: process(CURRENT_STATE, dobyte_in, cycdone, bytedone)\r
 begin\r
-       NEXT_STATE <= SLEEP;\r
-       inc_bit_x  <= '0';\r
-       rst_bit_x  <= '0';\r
-       load_cyc_x <= '0';\r
-       dec_cyc_x  <= '0';\r
-       load_sr_x  <= '0';\r
-       shift_o_x  <= '0';\r
-       shift_i_x  <= '0';\r
-       bdone_x    <= '0';\r
-       r_scl_x    <= '0';\r
-       s_scl_x    <= '0';\r
-       case CURRENT_STATE is\r
-               when SLEEP  =>  if( dobyte_in = '1' ) then\r
-                                                       NEXT_STATE <= LCL;\r
-                                                       inc_bit_x  <= '1';\r
-                                                       load_cyc_x <= '1';\r
-                                                       shift_o_x  <= '1';\r
-                                                       r_scl_x    <= '1';\r
-                                               else\r
-                                                       NEXT_STATE <= SLEEP;\r
-                                                       load_sr_x  <= '1';\r
-                                               end if;\r
-               when LCL    =>  NEXT_STATE <= WCL;\r
-                                               dec_cyc_x  <= '1';\r
-               when WCL    =>  if( cycdone = '1' ) then\r
-                                                       NEXT_STATE <= LCH;\r
-                                                       load_cyc_x <= '1';\r
-                                                       s_scl_x    <= '1';\r
-                                               else\r
-                                                       NEXT_STATE <= WCL;\r
-                                                       dec_cyc_x  <= '1';\r
-                                               end if;\r
-               when LCH    =>  NEXT_STATE <= WCH;\r
-                                               dec_cyc_x  <= '1';\r
-               when WCH    =>  if   ( (cycdone = '1') and (bytedone = '0') ) then\r
-                                                       NEXT_STATE <= LCL;\r
-                                                       inc_bit_x  <= '1';\r
-                                                       load_cyc_x <= '1';\r
-                                                       shift_o_x  <= '1';\r
-                                                       r_scl_x    <= '1';\r
-                                               elsif( (cycdone = '1') and (bytedone = '1') ) then\r
-                                                       NEXT_STATE <= FREE;\r
-                                                       shift_o_x  <= '1';\r
-                                                       shift_i_x  <= '1';\r
-                                                       r_scl_x    <= '1';\r
-                                               else\r
-                                                       NEXT_STATE <= WCH;\r
-                                                       dec_cyc_x  <= '1';\r
-                                               end if;\r
-               when FREE   =>  NEXT_STATE <= DONE;\r
-                                               rst_bit_x  <= '1';\r
-                                               bdone_x    <= '1';\r
-               when DONE   =>  if( dobyte_in = '0' ) then\r
-                                                       NEXT_STATE <= SLEEP;\r
-                                               else\r
-                                                       NEXT_STATE <= DONE;\r
-                                                       rst_bit_x  <= '1';\r
-                                                       bdone_x    <= '1';\r
-                                               end if;\r
-                               -- Just in case...\r
-               when others =>  NEXT_STATE <= SLEEP;\r
-       end case;\r
+  NEXT_STATE <= SLEEP;\r
+  inc_bit_x  <= '0';\r
+  rst_bit_x  <= '0';\r
+  load_cyc_x <= '0';\r
+  dec_cyc_x  <= '0';\r
+  load_sr_x  <= '0';\r
+  shift_o_x  <= '0';\r
+  shift_i_x  <= '0';\r
+  bdone_x    <= '0';\r
+  r_scl_x    <= '0';\r
+  s_scl_x    <= '0';\r
+  case CURRENT_STATE is\r
+    when SLEEP  =>  if( dobyte_in = '1' ) then\r
+              NEXT_STATE <= LCL;\r
+              inc_bit_x  <= '1';\r
+              load_cyc_x <= '1';\r
+              shift_o_x  <= '1';\r
+              r_scl_x    <= '1';\r
+            else\r
+              NEXT_STATE <= SLEEP;\r
+              load_sr_x  <= '1';\r
+            end if;\r
+    when LCL    =>  NEXT_STATE <= WCL;\r
+            dec_cyc_x  <= '1';\r
+    when WCL    =>  if( cycdone = '1' ) then\r
+              NEXT_STATE <= LCH;\r
+              load_cyc_x <= '1';\r
+              s_scl_x    <= '1';\r
+            else\r
+              NEXT_STATE <= WCL;\r
+              dec_cyc_x  <= '1';\r
+            end if;\r
+    when LCH    =>  NEXT_STATE <= WCH;\r
+            dec_cyc_x  <= '1';\r
+    when WCH    =>  if   ( (cycdone = '1') and (bytedone = '0') ) then\r
+              NEXT_STATE <= LCL;\r
+              inc_bit_x  <= '1';\r
+              load_cyc_x <= '1';\r
+              shift_o_x  <= '1';\r
+              r_scl_x    <= '1';\r
+            elsif( (cycdone = '1') and (bytedone = '1') ) then\r
+              NEXT_STATE <= FREE;\r
+              shift_o_x  <= '1';\r
+              shift_i_x  <= '1';\r
+              r_scl_x    <= '1';\r
+            else\r
+              NEXT_STATE <= WCH;\r
+              dec_cyc_x  <= '1';\r
+            end if;\r
+    when FREE   =>  NEXT_STATE <= DONE;\r
+            rst_bit_x  <= '1';\r
+            bdone_x    <= '1';\r
+    when DONE   =>  if( dobyte_in = '0' ) then\r
+              NEXT_STATE <= SLEEP;\r
+            else\r
+              NEXT_STATE <= DONE;\r
+              rst_bit_x  <= '1';\r
+              bdone_x    <= '1';\r
+            end if;\r
+        -- Just in case...\r
+    when others =>  NEXT_STATE <= SLEEP;\r
+  end case;\r
 end process TRANSFORM;\r
 \r
 -- Output decoding\r
 DECODE: process(CURRENT_STATE)\r
 begin\r
-       case CURRENT_STATE is\r
-               when SLEEP  =>  bsm <= x"0";\r
-               when LCL    =>  bsm <= x"1";\r
-               when WCL    =>  bsm <= x"2";\r
-               when LCH    =>  bsm <= x"3";\r
-               when WCH    =>  bsm <= x"4";\r
-               when FREE   =>  bsm <= x"5";\r
-               when DONE   =>  bsm <= x"6";\r
-               when others =>  bsm <= x"f";\r
-       end case;\r
+  case CURRENT_STATE is\r
+    when SLEEP  =>  bsm <= x"0";\r
+    when LCL    =>  bsm <= x"1";\r
+    when WCL    =>  bsm <= x"2";\r
+    when LCH    =>  bsm <= x"3";\r
+    when WCH    =>  bsm <= x"4";\r
+    when FREE   =>  bsm <= x"5";\r
+    when DONE   =>  bsm <= x"6";\r
+    when others =>  bsm <= x"f";\r
+  end case;\r
 end process DECODE;\r
 \r
 -- SCL and SDA output pulses\r
 THE_SDA_OUT_PROC: process( clk_in )\r
 begin\r
-       if( rising_edge(clk_in) ) then\r
-               if( reset_in = '1' ) then\r
-                       load  <= '0'; -- was a bug, found 081008\r
-                       r_sda <= '0';\r
-                       s_sda <= '0';\r
-               else\r
-                       load  <= shift_o;\r
-                       r_sda <= load and not i2c_d;\r
-                       s_sda <= load and     i2c_d;\r
-               end if;\r
-       end if;\r
+  if( rising_edge(clk_in) ) then\r
+    if( reset_in = '1' ) then\r
+      load  <= '0'; -- was a bug, found 081008\r
+      r_sda <= '0';\r
+      s_sda <= '0';\r
+    else\r
+      load  <= shift_o;\r
+      r_sda <= load and not i2c_d;\r
+      s_sda <= load and     i2c_d;\r
+    end if;\r
+  end if;\r
 end process THE_SDA_OUT_PROC;\r
 \r
 -- Outputs\r
index 249c35170f26874a51d50eb27e464e08f031d409..568b1aa36fe1c99b646f84b5b0502954885ed2c1 100644 (file)
@@ -11,6 +11,7 @@ port(
   I2C_GO_IN       : in  std_logic; -- startbit to trigger I2C actions\r
   ACTION_IN       : in  std_logic; -- '0' -> write, '1' -> read\r
   WORD_IN         : in  std_logic; -- '0' -> byte, '1' -> word\r
+  DIRECT_IN       : in  std_logic; -- '0' -> normal access, '1' -> direct read\r
   I2C_SPEED_IN    : in  std_logic_vector(5 downto 0); -- speed adjustment (to be defined)\r
   I2C_ADDR_IN     : in  std_logic_vector(7 downto 0); -- I2C address byte (R/W bit is ignored)\r
   I2C_CMD_IN      : in  std_logic_vector(7 downto 0); -- I2C command byte (sent after address byte)\r
@@ -26,7 +27,7 @@ port(
   SCL_IN          : in  std_logic;\r
   SCL_OUT         : out std_logic;\r
   -- Debug\r
-  BSM_OUT         : out std_logic_vector(4 downto 0)\r
+  BSM_OUT         : out std_logic_vector(3 downto 0)\r
 );\r
 end entity i2c_slim2;\r
 \r
@@ -37,7 +38,7 @@ type STATES is (SLEEP, LOADA, GSTART, SENDA, LOADC, SENDC, LOADD, SENDD,
                 GSTOP, INC, DONE, FAILED, LOADD2, SENDD2);\r
 signal CURRENT_STATE, NEXT_STATE: STATES;\r
 \r
-signal bsm          : std_logic_vector( 4 downto 0 );\r
+signal bsm          : std_logic_vector(3 downto 0);\r
 signal phase        : std_logic; -- '0' => first phase, '1' => second phase of read cycle\r
 \r
 signal start_x      : std_logic;\r
@@ -57,6 +58,8 @@ signal load_dh_x    : std_logic;
 signal load_dh      : std_logic;\r
 signal load_dl_x    : std_logic;\r
 signal load_dl      : std_logic;\r
+signal clr_data_x   : std_logic;\r
+signal clr_data     : std_logic;\r
 \r
 signal sdone        : std_logic; -- acknowledge signal from GenStart module\r
 signal sok          : std_logic; -- status signal from GenStart module\r
@@ -140,7 +143,7 @@ begin
 end process THE_SYNC_PROC;\r
 \r
 -- lower limit of speed\r
-i2c_speed <= i2c_speed_in & "000";\r
+i2c_speed <= i2c_speed_in & b"010";\r
 \r
 -- Read phase indicator\r
 THE_PHASE_PROC: process( CLOCK )\r
@@ -148,7 +151,7 @@ begin
   if( rising_edge(CLOCK) ) then\r
     if( RESET = '1' ) then\r
       phase <= '0';\r
-    elsif( CURRENT_STATE = INC ) then\r
+    elsif( (CURRENT_STATE = INC) ) then\r
       phase <= '1';\r
     elsif( (CURRENT_STATE = DONE) or (CURRENT_STATE = SLEEP) ) then\r
       phase <= '0';\r
@@ -166,44 +169,48 @@ begin
       start         <= '0';\r
       dostart       <= '0';\r
       dobyte        <= '0';\r
-      i2c_done      <= '0';\r
       running       <= '0';\r
       load_dh       <= '0';\r
       load_dl       <= '0';\r
+      clr_data      <= '1';\r
       valid         <= '0';\r
+      i2c_done      <= '0';\r
     else\r
       CURRENT_STATE <= NEXT_STATE;\r
       start         <= start_x;\r
       dostart       <= dostart_x;\r
       dobyte        <= dobyte_x;\r
-      i2c_done      <= i2c_done_x;\r
       running       <= running_x;\r
       load_dh       <= load_dh_x;\r
       load_dl       <= load_dl_x;\r
+      clr_data      <= clr_data_x;\r
       valid         <= valid_x;\r
+      i2c_done      <= i2c_done_x;\r
     end if;\r
   end if;\r
 end process STATE_MEM;\r
 \r
 -- Transition matrix\r
-TRANSFORM: process(CURRENT_STATE, i2c_go_in, sdone, sok, phase, bdone, bok, action_in, word_in)\r
+TRANSFORM: process(CURRENT_STATE, I2C_GO_IN, sdone, sok, phase, bdone, bok, ACTION_IN, WORD_IN)\r
 begin\r
   NEXT_STATE <= SLEEP;\r
   start_x    <= '0';\r
   dostart_x  <= '0';\r
   dobyte_x   <= '0';\r
-  i2c_done_x <= '0';\r
   running_x  <= '1';\r
   load_dh_x  <= '0';\r
   load_dl_x  <= '0';\r
+  clr_data_x <= '0';\r
   valid_x    <= '0';\r
+  i2c_done_x <= '0';\r
   errors_x   <= x"00";\r
   save_x     <= '0';\r
   case CURRENT_STATE is\r
     when SLEEP      =>  \r
-      if( i2c_go_in = '1' ) then\r
+      if( I2C_GO_IN = '1' ) then\r
         NEXT_STATE <= LOADA;\r
         save_x     <= '1';\r
+        clr_data_x <= '1';\r
       else\r
         NEXT_STATE <= SLEEP;\r
         running_x  <= '0';\r
@@ -232,12 +239,22 @@ begin
         dostart_x  <= '1';\r
       end if;\r
     when SENDA      =>  \r
-      if   ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then\r
-        NEXT_STATE <= LOADC; -- I2C write, send command\r
-      elsif( (bdone = '1') and (bok = '1') and (action_in = '1') and (phase = '0') ) then\r
-        NEXT_STATE <= LOADC; -- I2C read, send command\r
-      elsif( (bdone = '1') and (bok = '1') and (action_in = '1') and (phase = '1') ) then\r
-        NEXT_STATE <= LOADD; -- I2C read, send 0xff dummy byte\r
+      if   ( (bdone = '1') and (bok = '1') and (ACTION_IN = '0') and (DIRECT_IN = '0') ) then\r
+        NEXT_STATE <= LOADC; -- I2C normal write\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '1') and (DIRECT_IN = '0') and (phase = '0') ) then\r
+        NEXT_STATE <= LOADC; -- I2C normal read, address stage (same for byte and word)\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '1') and (phase = '1') and (WORD_IN = '0') ) then\r
+        NEXT_STATE <= LOADD2; -- I2C normal read (byte), data stage\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '1') and (phase = '1') and (WORD_IN = '1') ) then\r
+        NEXT_STATE <= LOADD; -- I2C normal read (word), data stage\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '0') and (DIRECT_IN = '1') and (WORD_IN = '0') ) then\r
+        NEXT_STATE <= LOADD2; -- I2C direct write (byte)\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '0') and (DIRECT_IN = '1') and (WORD_IN = '1') ) then\r
+        NEXT_STATE <= LOADD; -- I2C direct write (word)\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '1') and (DIRECT_IN = '1') and (WORD_IN = '0') ) then\r
+        NEXT_STATE <= LOADD2; -- I2C direct read (byte)\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '1') and (DIRECT_IN = '1') and (WORD_IN = '1') ) then\r
+        NEXT_STATE <= LOADD; -- I2C direct read (word)\r
       elsif( (bdone = '1') and (bok = '0') and (phase = '0') ) then\r
         NEXT_STATE <= FAILED; -- first address phase failed\r
         errors_x   <= x"20";\r
@@ -255,11 +272,11 @@ begin
     when LOADC      =>  \r
       NEXT_STATE <= SENDC;\r
     when SENDC      =>  \r
-      if   ( (bdone = '1') and (bok = '1') and (action_in = '0') and (word_in = '0') ) then\r
+      if   ( (bdone = '1') and (bok = '1') and (ACTION_IN = '0') and (WORD_IN = '0') ) then\r
         NEXT_STATE <= LOADD2; -- I2C byte write, prepare data\r
-      elsif( (bdone = '1') and (bok = '1') and (action_in = '0') and (word_in = '1') ) then\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '0') and (WORD_IN = '1') ) then\r
         NEXT_STATE <= LOADD; -- I2C word write, prepare data\r
-      elsif( (bdone = '1') and (bok = '1') and (action_in = '1') ) then\r
+      elsif( (bdone = '1') and (bok = '1') and (ACTION_IN = '1') ) then\r
         NEXT_STATE <= GSTOP; -- I2C read, first phase ends\r
         dostart_x  <= '1';\r
       elsif( (bdone = '1') and (bok = '0') ) then\r
@@ -274,19 +291,12 @@ begin
     when LOADD      =>  \r
       NEXT_STATE <= SENDD;\r
     when SENDD      =>  \r
-      if   ( (bdone = '1') and (bok = '1') and (action_in = '0') and (word_in = '0') ) then\r
-        NEXT_STATE <= GSTOP;    -- I2C write, byte access, done\r
-        dostart_x  <= '1';\r
-      elsif( (bdone = '1') and (bok = '1') and (action_in = '0') and (word_in = '1') ) then\r
-        NEXT_STATE <= LOADD2;    -- I2C write, word access, last byte to send\r
-      elsif( (bdone = '1') and                 (action_in = '1') and (word_in = '0') ) then\r
-        NEXT_STATE <= GSTOP; -- I2C read, byte access, data phase\r
-        dostart_x  <= '1';\r
-        load_dl_x  <= '1';\r
-      elsif( (bdone = '1') and                 (action_in = '1') and (word_in = '1') ) then\r
+      if   ( (bdone = '1') and (bok = '1') and (ACTION_IN = '0') ) then\r
+        NEXT_STATE <= LOADD2; -- I2C write, word access, last byte to send\r
+      elsif( (bdone = '1') and                 (ACTION_IN = '1') ) then\r
         NEXT_STATE <= LOADD2; -- I2C read, word access, last byte to receive\r
         load_dh_x  <= '1';\r
-      elsif( (bdone = '1') and (bok = '0') and (action_in = '0') ) then\r
+      elsif( (bdone = '1') and (bok = '0') and (ACTION_IN = '0') ) then\r
         NEXT_STATE <= FAILED; -- I2C write, first data phase failed\r
         errors_x   <= x"04";\r
         save_x     <= '1';\r
@@ -298,14 +308,14 @@ begin
     when LOADD2     =>  \r
       NEXT_STATE <= SENDD2;\r
     when SENDD2     =>  \r
-      if   ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then\r
+      if   ( (bdone = '1') and (bok = '1') and (ACTION_IN = '0') ) then\r
         NEXT_STATE <= GSTOP; -- I2C write, done\r
         dostart_x  <= '1';\r
-      elsif( (bdone = '1') and                 (action_in = '1') ) then\r
+      elsif( (bdone = '1') and                 (ACTION_IN = '1') ) then\r
         NEXT_STATE <= GSTOP; -- I2C read, data phase\r
         dostart_x  <= '1';\r
         load_dl_x  <= '1';\r
-      elsif( (bdone = '1') and (bok = '0') and (action_in = '0') ) then\r
+      elsif( (bdone = '1') and (bok = '0') and (ACTION_IN = '0') ) then\r
         NEXT_STATE <= FAILED; -- I2C write, data phase failed\r
         errors_x   <= x"02";\r
         save_x     <= '1';\r
@@ -315,16 +325,20 @@ begin
         dobyte_x   <= '1';\r
       end if;\r
     when GSTOP      =>  \r
-      if   ( (sdone = '1') and (action_in = '0') ) then\r
+      if   ( (sdone = '1') and (ACTION_IN = '0') ) then\r
         NEXT_STATE <= DONE;\r
         i2c_done_x <= '1';\r
         valid_x    <= '1';\r
-      elsif( (sdone = '1') and (action_in = '1') and (phase = '1') ) then\r
+      elsif( (sdone = '1') and (ACTION_IN = '1') and (phase = '1') ) then\r
         NEXT_STATE <= DONE;\r
         i2c_done_x <= '1';\r
         valid_x    <= '1';\r
-      elsif( (sdone = '1') and (action_in = '1') and (phase = '0') ) then\r
+      elsif( (sdone = '1') and (ACTION_IN = '1') and (phase = '0') and (DIRECT_IN = '0') ) then\r
         NEXT_STATE <= INC;\r
+      elsif( (sdone = '1') and (ACTION_IN = '1') and                   (DIRECT_IN = '1') ) then\r
+        NEXT_STATE <= DONE;\r
+        i2c_done_x <= '1';\r
+        valid_x    <= '1';\r
       else\r
         NEXT_STATE <= GSTOP;\r
         dostart_x  <= '1';\r
@@ -332,6 +346,7 @@ begin
     when INC        =>  \r
       NEXT_STATE <= LOADA;\r
     when FAILED     =>  \r
+      -- emergency STOP condition to correctly free the bus\r
       if( sdone = '1' ) then\r
         NEXT_STATE <= DONE;\r
         i2c_done_x <= '1';\r
@@ -365,50 +380,65 @@ begin
   end if;\r
 end process THE_ERROR_PROC;\r
 \r
+---- DONE bit: set by FSM completion, cleared by start of FSM\r
+--THE_DONE_PROC: process( CLOCK )\r
+--begin\r
+--  if( rising_edge(CLOCK) ) then\r
+--    if   ( RESET = '1' ) then\r
+--      i2c_done <= '0';\r
+--    elsif( CURRENT_STATE = LOADA ) then\r
+--      i2c_done <= '0';\r
+--    elsif( CURRENT_STATE = DONE ) then\r
+--      i2c_done <= '1';\r
+--    end if;\r
+--  end if;\r
+--end process THE_DONE_PROC;\r
+\r
 -- Output decoding\r
 DECODE: process(CURRENT_STATE)\r
 begin\r
   case CURRENT_STATE is\r
-    when SLEEP      =>  bsm <= b"00000"; -- 00\r
-    when LOADA      =>  bsm <= b"00001"; -- 01\r
-    when GSTART     =>  bsm <= b"00010"; -- 02\r
-    when SENDA      =>  bsm <= b"00011"; -- 03\r
-    when LOADC      =>  bsm <= b"00100"; -- 04\r
-    when SENDC      =>  bsm <= b"00101"; -- 05\r
-    when LOADD      =>  bsm <= b"00110"; -- 06\r
-    when SENDD      =>  bsm <= b"00111"; -- 07\r
-    when GSTOP      =>  bsm <= b"01000"; -- 08\r
-    when INC        =>  bsm <= b"01001"; -- 09\r
-    when FAILED     =>  bsm <= b"01010"; -- 0a\r
-    when DONE       =>  bsm <= b"01011"; -- 0b\r
-    when LOADD2                        =>      bsm <= b"01100"; -- 0c\r
-    when SENDD2                        =>      bsm <= b"01101"; -- 0d\r
-    when others     =>  bsm <= b"11111"; -- 1f\r
+    when SLEEP      =>  bsm <= b"0000"; -- 0\r
+    when LOADA      =>  bsm <= b"0001"; -- 1\r
+    when GSTART     =>  bsm <= b"0010"; -- 2\r
+    when SENDA      =>  bsm <= b"0011"; -- 3\r
+    when LOADC      =>  bsm <= b"0100"; -- 4\r
+    when SENDC      =>  bsm <= b"0101"; -- 5\r
+    when LOADD      =>  bsm <= b"0110"; -- 6\r
+    when SENDD      =>  bsm <= b"0111"; -- 7\r
+    when GSTOP      =>  bsm <= b"1000"; -- 8\r
+    when INC        =>  bsm <= b"1001"; -- 9\r
+    when FAILED     =>  bsm <= b"1010"; -- a\r
+    when DONE       =>  bsm <= b"1011"; -- b\r
+    when LOADD2                        =>      bsm <= b"1100"; -- c\r
+    when SENDD2                        =>      bsm <= b"1101"; -- d\r
+    when others     =>  bsm <= b"1111"; -- f\r
   end case;\r
 end process DECODE;\r
 \r
 -- We need to load different data sets\r
---LOAD_DATA_PROC: process( CLOCK, RESET, CURRENT_STATE, action_in, phase)\r
 LOAD_DATA_PROC: process( CLOCK )\r
 begin\r
   if( rising_edge(CLOCK) ) then\r
     if   ( RESET = '1' ) then\r
       i2c_byte <= (others => '1');\r
-    elsif( (CURRENT_STATE = LOADA) and (phase = '0') ) then\r
+    elsif( (CURRENT_STATE = LOADA) and (phase = '0') and (DIRECT_IN = '0') ) then\r
       i2c_byte <= i2c_addr_in(7 downto 1) & '0' & '1'; -- send write address, receive ACK\r
+    elsif( (CURRENT_STATE = LOADA) and (phase = '0') and (DIRECT_IN = '1') and (ACTION_IN = '0') ) then\r
+      i2c_byte <= i2c_addr_in(7 downto 1) & '0' & '1'; -- send write address, receive ACK\r
+    elsif( (CURRENT_STATE = LOADA) and (phase = '0') and (DIRECT_IN = '1') and (ACTION_IN = '1') ) then\r
+      i2c_byte <= i2c_addr_in(7 downto 1) & '1' & '1'; -- send read address, receive ACK\r
     elsif( (CURRENT_STATE = LOADA) and (phase = '1') ) then\r
       i2c_byte <= i2c_addr_in(7 downto 1) & '1' & '1'; -- send read address, receive ACK\r
-    elsif( (CURRENT_STATE = LOADC) and (action_in = '0') ) then\r
-      i2c_byte <= i2c_cmd_in(7 downto 0) & '1'; -- send command byte (WRITE), receive ACK\r
-    elsif( (CURRENT_STATE = LOADC) and (action_in = '1') ) then\r
-      i2c_byte <= i2c_cmd_in(7 downto 0) & '1'; -- send command byte (READ), receive ACK\r
-    elsif( (CURRENT_STATE = LOADD) and (action_in = '0') ) then\r
+    elsif( (CURRENT_STATE = LOADC) ) then\r
+      i2c_byte <= i2c_cmd_in(7 downto 0) & '1'; -- send command byte (read/write), receive ACK\r
+    elsif( (CURRENT_STATE = LOADD) and (ACTION_IN = '0') ) then\r
       i2c_byte <= i2c_dw_in(15 downto 8) & '1'; -- send data byte, receive ACK\r
-    elsif( (CURRENT_STATE = LOADD2) and (action_in = '0') ) then\r
+    elsif( (CURRENT_STATE = LOADD2) and (ACTION_IN = '0') ) then\r
       i2c_byte <= i2c_dw_in(7 downto 0) & '1'; -- send data byte, receive ACK\r
-    elsif( (CURRENT_STATE = LOADD) and (action_in = '1') ) then\r
+    elsif( (CURRENT_STATE = LOADD) and (ACTION_IN = '1') ) then\r
       i2c_byte <= x"ff" & '0'; -- send 0xff byte, send ACK\r
-    elsif( (CURRENT_STATE = LOADD2) and (action_in = '1') ) then\r
+    elsif( (CURRENT_STATE = LOADD2) and (ACTION_IN = '1') ) then\r
       i2c_byte <= x"ff" & '1'; -- send 0xff byte, send NACK\r
     end if;\r
   end if;\r
@@ -490,8 +520,8 @@ end process THE_SDA_PROC;
 THE_STORE_READ_H_PROC: process( CLOCK ) \r
 begin\r
   if( rising_edge(CLOCK) ) then\r
-    if   ( RESET = '1' ) then\r
-      i2c_drw(15 downto 8) <= (others => '0');\r
+    if   ( clr_data = '1' ) then\r
+      i2c_drw(15 downto 8) <= (others => '1');\r
     elsif( rising_edge(CLOCK) ) then\r
       if( load_dh = '1' ) then\r
         i2c_drw(15 downto 8) <= i2c_dr(8 downto 1);\r
@@ -504,8 +534,8 @@ end process THE_STORE_READ_H_PROC;
 THE_STORE_READ_L_PROC: process( CLOCK ) \r
 begin\r
   if( rising_edge(CLOCK) ) then\r
-    if   ( RESET = '1' ) then\r
-      i2c_drw(7 downto 0) <= (others => '0');\r
+    if   ( clr_data = '1' ) then\r
+      i2c_drw(7 downto 0) <= (others => '1');\r
     elsif( rising_edge(CLOCK) ) then\r
       if( load_dl = '1' ) then\r
         i2c_drw(7 downto 0) <= i2c_dr(8 downto 1);\r