+++ /dev/null
-library IEEE;\r
-use IEEE.STD_LOGIC_1164.ALL;\r
-use IEEE.STD_LOGIC_ARITH.ALL;\r
-use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
-\r
-library work;\r
-use work.adcmv3_components.all;\r
-\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
- );\r
-end entity;\r
-\r
-architecture Behavioral of I2C_GSTART is\r
-\r
--- Signals\r
- type STATES is (SLEEP,\r
- P_SCL,\r
- WCTR0,\r
- P_SDA,\r
- WCTR1,\r
- P_CHK,\r
- S_CHK0,\r
- RS_SDA,\r
- S_CHK1,\r
- ERROR,\r
- DONE);\r
- signal CURRENT_STATE, NEXT_STATE: STATES;\r
-\r
- signal bsm : std_logic_vector(3 downto 0);\r
- signal cctr : unsigned(8 downto 0); -- counter for bit length\r
-\r
- signal cycdone_x : std_logic;\r
- signal cycdone : std_logic; -- one counter period done\r
-\r
- signal load_cyc_x : std_logic;\r
- signal load_cyc : std_logic;\r
- signal dec_cyc_x : std_logic;\r
- signal dec_cyc : std_logic;\r
- signal sdone_x : std_logic;\r
- signal sdone : std_logic; -- Start/Stop done\r
- signal sok_x : std_logic;\r
- signal sok : std_logic; -- Start/Stop OK\r
-\r
- signal r_scl : std_logic;\r
- signal s_scl : std_logic;\r
- signal r_sda : std_logic;\r
- signal s_sda : std_logic;\r
-\r
--- Moduls\r
-\r
-begin\r
-\r
--- 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
- end process THE_CYC_CTR_PROC;\r
-\r
--- end of cycle recognition\r
- cycdone_x <= '1' when (cctr = 0) else '0';\r
-\r
--- The main state machine\r
--- 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
- 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
- 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
- case CURRENT_STATE is\r
- when SLEEP => 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 <= P_SCL; -- generate a stop condition\r
- load_cyc_x <= '1';\r
- else\r
- NEXT_STATE <= SLEEP;\r
- end if;\r
- when P_SCL => NEXT_STATE <= WCTR0;\r
- dec_cyc_x <= '1';\r
- when S_CHK0 => if( (sda_in = '1') and (scl_in = '1') ) then\r
- NEXT_STATE <= RS_SDA;\r
- else\r
- NEXT_STATE <= ERROR;\r
- sok_x <= '0';\r
- end if;\r
- when RS_SDA => NEXT_STATE <= WCTR0;\r
- dec_cyc_x <= '1';\r
- when WCTR0 => 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
- else\r
- NEXT_STATE <= WCTR0;\r
- dec_cyc_x <= '1';\r
- end if;\r
- when S_CHK1 => 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 => NEXT_STATE <= WCTR1;\r
- dec_cyc_x <= '1';\r
- when WCTR1 => 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 => 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 => 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 => 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 => 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 ERROR => bsm <= x"e";\r
- when others => bsm <= x"f";\r
- end case;\r
- end process DECODE;\r
-\r
- S_R_GEN: process(CURRENT_STATE)\r
- begin\r
- if ( CURRENT_STATE = P_SCL ) then\r
- r_scl <= '0';\r
- s_scl <= '1';\r
- r_sda <= '0';\r
- s_sda <= '0';\r
- elsif( CURRENT_STATE = RS_SDA ) then\r
- r_scl <= '0';\r
- s_scl <= '0';\r
- r_sda <= '1';\r
- s_sda <= '0';\r
- elsif( CURRENT_STATE = P_SDA ) then\r
- r_scl <= '0';\r
- s_scl <= '0';\r
- r_sda <= '0';\r
- s_sda <= '1';\r
- else\r
- r_scl <= '0';\r
- s_scl <= '0';\r
- r_sda <= '0';\r
- s_sda <= '0';\r
- end if;\r
- end process S_R_GEN;\r
-\r
--- Outputs\r
- r_scl_out <= r_scl;\r
- s_scl_out <= s_scl;\r
- r_sda_out <= r_sda;\r
- s_sda_out <= s_sda;\r
- sdone_out <= sdone;\r
- sok_out <= sok;\r
-\r
--- Debug\r
- bsm_out <= bsm;\r
-\r
-end Behavioral;\r
+++ /dev/null
-library IEEE;\r
-use IEEE.STD_LOGIC_1164.ALL;\r
-use IEEE.STD_LOGIC_ARITH.ALL;\r
-use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
-\r
-library work;\r
-use work.adcmv3_components.all;\r
-\r
-entity i2c_master is\r
- port(\r
- CLK_IN : in std_logic;\r
- RESET_IN : in std_logic;\r
-\r
- -- Slave bus\r
- SLV_READ_IN : in std_logic;\r
- SLV_WRITE_IN : in std_logic;\r
- SLV_BUSY_OUT : out std_logic;\r
- SLV_ACK_OUT : out std_logic;\r
- SLV_DATA_IN : in std_logic_vector(31 downto 0);\r
- SLV_DATA_OUT : out std_logic_vector(31 downto 0);\r
-\r
- -- I2C connections\r
- SDA_IN : in std_logic;\r
- SDA_OUT : out std_logic;\r
- SCL_IN : in std_logic;\r
- SCL_OUT : out std_logic;\r
- -- Status lines\r
- STAT : out std_logic_vector(31 downto 0) -- DEBUG\r
- );\r
-end entity;\r
-\r
-architecture Behavioral of i2c_master is\r
-\r
--- Signals\r
- type STATES is (SLEEP,\r
- RD_BSY,\r
- WR_BSY,\r
- RD_RDY,\r
- WR_RDY,\r
- RD_ACK,\r
- WR_ACK,\r
- DONE);\r
- signal CURRENT_STATE, NEXT_STATE: STATES;\r
-\r
--- slave bus signals\r
- signal slv_busy_x : std_logic;\r
- signal slv_busy : std_logic;\r
- signal slv_ack_x : std_logic;\r
- signal slv_ack : std_logic;\r
- signal store_wr_x : std_logic;\r
- signal store_wr : std_logic;\r
- signal store_rd_x : std_logic;\r
- signal store_rd : std_logic;\r
-\r
- signal reg_slv_data_in : std_logic_vector(31 downto 0); -- registered data input\r
- signal reg_slv_data_out : std_logic_vector(31 downto 0); -- read back data\r
- signal reg_busy : std_logic;\r
-\r
- signal status_data : std_logic_vector(31 downto 0);\r
- signal i2c_debug : std_logic_vector(31 downto 0);\r
-\r
- signal i2c_speed_static : std_logic_vector(8 downto 0);\r
- \r
-begin\r
-\r
----------------------------------------------------------\r
--- I2C master --\r
----------------------------------------------------------\r
-\r
- THE_I2C_SLIM: i2c_slim\r
- port map(\r
- CLK_IN => clk_in,\r
- RESET_IN => reset_in,\r
- -- I2C command / setup\r
- I2C_GO_IN => reg_slv_data_in(31),\r
- ACTION_IN => reg_slv_data_in(30),\r
- I2C_SPEED_IN => i2c_speed_static,\r
- I2C_ADR_IN => reg_slv_data_in(23 downto 16),\r
- I2C_CMD_IN => reg_slv_data_in(15 downto 8),\r
- I2C_DW_IN => reg_slv_data_in(7 downto 0),\r
- I2C_DR_OUT => status_data(7 downto 0),\r
- STATUS_OUT => status_data(31 downto 24),\r
- I2C_BUSY_OUT => reg_busy,\r
- -- I2C connections\r
- SDA_IN => sda_in,\r
- SDA_OUT => sda_out,\r
- SCL_IN => scl_in,\r
- SCL_OUT => scl_out,\r
- -- Debug\r
- STAT => i2c_debug\r
- );\r
-\r
- status_data(23 downto 21) <= (others => '0');\r
- status_data(20 downto 16) <= i2c_debug(4 downto 0);\r
- status_data(15 downto 8) <= (others => '0');\r
- i2c_speed_static <= (others => '1');\r
- \r
--- Fake\r
- stat <= i2c_debug;\r
-\r
----------------------------------------------------------\r
--- Statemachine --\r
----------------------------------------------------------\r
--- 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
- slv_busy <= '0';\r
- slv_ack <= '0';\r
- store_wr <= '0';\r
- store_rd <= '0';\r
- else\r
- CURRENT_STATE <= NEXT_STATE;\r
- slv_busy <= slv_busy_x;\r
- slv_ack <= slv_ack_x;\r
- store_wr <= store_wr_x;\r
- store_rd <= store_rd_x;\r
- end if;\r
- end if;\r
- end process STATE_MEM;\r
-\r
--- Transition matrix\r
- TRANSFORM: process(CURRENT_STATE, slv_read_in, slv_write_in, reg_busy )\r
- begin\r
- NEXT_STATE <= SLEEP;\r
- slv_busy_x <= '0';\r
- slv_ack_x <= '0';\r
- store_wr_x <= '0';\r
- store_rd_x <= '0';\r
- case CURRENT_STATE is\r
- when SLEEP => if ( (reg_busy = '0') and (slv_read_in = '1') ) then\r
- NEXT_STATE <= RD_RDY;\r
- store_rd_x <= '1';\r
- elsif( (reg_busy = '0') and (slv_write_in = '1') ) then\r
- NEXT_STATE <= WR_RDY;\r
- store_wr_x <= '1';\r
- elsif( (reg_busy = '1') and (slv_read_in = '1') ) then\r
- NEXT_STATE <= RD_BSY;\r
- slv_busy_x <= '1';\r
- elsif( (reg_busy = '1') and (slv_write_in = '1') ) then\r
- NEXT_STATE <= WR_BSY;\r
- slv_busy_x <= '1';\r
- else\r
- NEXT_STATE <= SLEEP;\r
- end if;\r
- when RD_RDY => NEXT_STATE <= RD_ACK;\r
- slv_ack_x <= '1';\r
- when WR_RDY => NEXT_STATE <= WR_ACK;\r
- slv_ack_x <= '1';\r
- when RD_ACK => if ( slv_read_in = '0' ) then\r
- NEXT_STATE <= DONE;\r
- else\r
- NEXT_STATE <= RD_ACK;\r
- slv_ack_x <= '1';\r
- end if;\r
- when WR_ACK => if ( slv_write_in = '0' ) then\r
- NEXT_STATE <= DONE;\r
- else\r
- NEXT_STATE <= WR_ACK;\r
- slv_ack_x <= '1';\r
- end if;\r
- when RD_BSY => if ( slv_read_in = '0' ) then\r
- NEXT_STATE <= DONE;\r
- else\r
- NEXT_STATE <= RD_BSY;\r
- slv_busy_x <= '1';\r
- end if;\r
- when WR_BSY => if ( slv_write_in = '0' ) then\r
- NEXT_STATE <= DONE;\r
- else\r
- NEXT_STATE <= WR_BSY;\r
- slv_busy_x <= '1';\r
- end if;\r
- when DONE => NEXT_STATE <= SLEEP;\r
-\r
- when others => NEXT_STATE <= SLEEP;\r
- end case;\r
- end process TRANSFORM;\r
-\r
----------------------------------------------------------\r
--- data handling --\r
----------------------------------------------------------\r
-\r
--- register write\r
- THE_WRITE_REG_PROC: process( clk_in )\r
- begin\r
- if( rising_edge(clk_in) ) then\r
- if ( reset_in = '1' ) then\r
- reg_slv_data_in <= (others => '0');\r
- elsif( store_wr = '1' ) then\r
- reg_slv_data_in <= slv_data_in;\r
- end if;\r
- end if;\r
- end process THE_WRITE_REG_PROC;\r
-\r
--- register read\r
- THE_READ_REG_PROC: process( clk_in )\r
- begin\r
- if( rising_edge(clk_in) ) then\r
- if ( reset_in = '1' ) then\r
- reg_slv_data_out <= (others => '0');\r
- elsif( store_rd = '1' ) then\r
- reg_slv_data_out <= status_data;\r
- end if;\r
- end if;\r
- end process THE_READ_REG_PROC;\r
-\r
--- output signals\r
- slv_ack_out <= slv_ack;\r
- slv_busy_out <= slv_busy;\r
- slv_data_out <= reg_slv_data_out;\r
-\r
-end Behavioral;\r
+++ /dev/null
-library IEEE;\r
-use IEEE.STD_LOGIC_1164.ALL;\r
-use IEEE.STD_LOGIC_ARITH.ALL;\r
-use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
-\r
-library work;\r
-use work.adcmv3_components.all;\r
-\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
- 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
-architecture Behavioral of i2c_sendb is\r
-\r
--- Signals\r
- type STATES is (SLEEP,\r
- LCL,\r
- WCL,\r
- LCH,\r
- WCH,\r
- FREE,\r
- DONE);\r
- signal CURRENT_STATE, NEXT_STATE: STATES;\r
-\r
- signal bsm : std_logic_vector( 3 downto 0 );\r
-\r
- signal inc_bit_x : std_logic;\r
- signal inc_bit : std_logic; -- increment bit counter for byte to send\r
- signal rst_bit_x : std_logic;\r
- signal rst_bit : std_logic; -- reset bit counter for byte to send\r
- signal load_cyc_x : std_logic;\r
- signal load_cyc : std_logic; -- load cycle counter (SCL length)\r
- signal dec_cyc_x : std_logic;\r
- signal dec_cyc : std_logic; -- decrement cycle counter (SCL length)\r
- signal load_sr_x : std_logic;\r
- signal load_sr : std_logic; -- load output shift register\r
- signal shift_o_x : std_logic;\r
- signal shift_o : std_logic; -- output shift register control\r
- signal shift_i_x : std_logic;\r
- signal shift_i : std_logic; -- input shift register control\r
- signal bdone_x : std_logic;\r
- signal bdone : std_logic;\r
- signal r_scl_x : std_logic;\r
- signal r_scl : std_logic; -- output for SCL\r
- signal s_scl_x : std_logic;\r
- signal s_scl : std_logic; -- output for SCL\r
-\r
- signal bctr : std_logic_vector( 3 downto 0 ); -- bit counter (1...9)\r
- signal cctr : unsigned(8 downto 0); -- counter for bit length\r
- signal bok : std_logic;\r
- signal cycdone : std_logic; -- one counter period done\r
- signal bytedone : std_logic; -- all bits sents\r
- signal in_sr : std_logic_vector( 8 downto 0 ); -- shift register for byte in\r
- signal out_sr : std_logic_vector( 8 downto 0 ); -- shift register for byte out\r
- signal i2c_back : std_logic_vector( 8 downto 0 ); -- shift register for byte in\r
- signal r_sda : std_logic; -- output for SDA\r
- signal s_sda : std_logic; -- output for SDA\r
- signal load : std_logic; -- delay register\r
- signal i2c_d : std_logic; -- auxiliary register\r
-\r
--- Moduls\r
-\r
-begin\r
-\r
--- 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
- end process THE_BIT_CTR_PROC;\r
-\r
--- end of byte recognition\r
- bytedone <= '1' when (bctr = x"a") else '0';\r
-\r
--- 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
- end process THE_CYC_CTR_PROC;\r
-\r
--- end of cycle recognition\r
- cycdone <= '1' when (cctr = 0) else '0';\r
-\r
--- 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
- 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
- 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
- end process THE_I2C_BACK_PROC;\r
-\r
--- ByteOK is the inverted ACK bit from readback data.\r
- bok <= not i2c_back(0); -- BUG\r
-\r
--- The main state machine\r
--- 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
- 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
- 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
- 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
- end process THE_SDA_OUT_PROC;\r
-\r
--- Outputs\r
- r_scl_out <= r_scl;\r
- s_scl_out <= s_scl;\r
- r_sda_out <= r_sda;\r
- s_sda_out <= s_sda;\r
-\r
- i2c_back_out <= i2c_back;\r
-\r
- bdone_out <= bdone;\r
- bok_out <= bok;\r
-\r
--- Debugging\r
- bsm_out <= bsm;\r
-\r
-end Behavioral;\r
+++ /dev/null
-library IEEE;\r
-use IEEE.STD_LOGIC_1164.ALL;\r
-use IEEE.STD_LOGIC_ARITH.ALL;\r
-use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
-\r
-library work;\r
-use work.adcmv3_components.all;\r
-\r
-entity i2c_slim is\r
- port (\r
- CLK_IN : in std_logic;\r
- RESET_IN : in std_logic;\r
-\r
- -- I2C command / setup\r
- I2C_GO_IN : in std_logic; -- startbit to trigger I2C actions\r
- ACTION_IN : in std_logic; -- '0' -> write, '1' -> read\r
- I2C_SPEED_IN : in std_logic_vector( 8 downto 0 ); -- speed adjustment\r
- I2C_ADR_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
- I2C_DW_IN : in std_logic_vector( 7 downto 0 ); -- data word for write command\r
- I2C_DR_OUT : out std_logic_vector( 7 downto 0 ); -- data word from read command\r
- STATUS_OUT : out std_logic_vector( 7 downto 0 ); -- status and error bits\r
- I2C_BUSY_OUT : out std_logic;\r
-\r
- -- I2C connections\r
- SDA_IN : in std_logic;\r
- SDA_OUT : out std_logic;\r
- SCL_IN : in std_logic;\r
- SCL_OUT : out std_logic;\r
-\r
- -- Debug\r
- STAT : out std_logic_vector(31 downto 0)\r
- );\r
-end i2c_slim;\r
-\r
-architecture Behavioral of i2c_slim is\r
-\r
--- Signals\r
- type STATES is (SLEEP,\r
- LOADA,\r
- GSTART,\r
- SENDA,\r
- LOADC,\r
- SENDC,\r
- LOADD,\r
- SENDD,\r
- GSTOP,\r
- INC,\r
- E_START,\r
- E_ADDR,\r
- E_CMD,\r
- E_WD,\r
- E_RSTART,\r
- E_RADDR,\r
- DONE,\r
- FAILED,\r
- CLRERR);\r
- signal CURRENT_STATE, NEXT_STATE: STATES;\r
-\r
- signal bsm : std_logic_vector( 4 downto 0 );\r
- signal phase : std_logic; -- '0' => first phase, '1' => second phase of read cycle\r
-\r
- signal start_x : std_logic;\r
- signal start : std_logic; -- '0' => generate STOP, '1' => generate START\r
- signal dostart_x : std_logic;\r
- signal dostart : std_logic; -- trigger the GenStart module\r
- signal dobyte_x : std_logic;\r
- signal dobyte : std_logic; -- trigger the ByteSend module\r
- signal i2c_done_x : std_logic;\r
- signal i2c_done : std_logic; -- acknowledge signal to the outside world\r
- signal running_x : std_logic;\r
- signal running : std_logic; -- legacy\r
-\r
- signal load_a_x : std_logic;\r
- signal load_a : std_logic;\r
- signal load_c_x : std_logic;\r
- signal load_c : std_logic;\r
- signal load_d_x : std_logic;\r
- signal load_d : std_logic;\r
-\r
- signal sdone : std_logic; -- acknowledge signal from GenStart module\r
- signal sok : std_logic; -- status signal from GenStart module\r
- signal bdone : std_logic; -- acknowledge signal from SendByte module\r
- signal bok : std_logic; -- status signal from SendByte module\r
- signal e_sf : std_logic; -- Start failed\r
- signal e_anak : std_logic; -- Adress byte NAK\r
- signal e_cnak : std_logic; -- Command byte NAK\r
- signal e_dnak : std_logic; -- Data byte NAK\r
- signal e_rsf : std_logic; -- Repeated Start failed\r
- signal e_ranak : std_logic; -- Repeated Adress NAK\r
- signal i2c_byte : std_logic_vector( 8 downto 0 );\r
- signal i2c_dr : std_logic_vector( 8 downto 0 );\r
-\r
- signal s_scl : std_logic;\r
- signal r_scl : std_logic;\r
- signal s_sda : std_logic;\r
- signal r_sda : std_logic;\r
- signal r_scl_gs : std_logic;\r
- signal s_scl_gs : std_logic;\r
- signal r_sda_gs : std_logic;\r
- signal s_sda_gs : std_logic;\r
- signal r_scl_sb : std_logic;\r
- signal s_scl_sb : std_logic;\r
- signal r_sda_sb : std_logic;\r
- signal s_sda_sb : std_logic;\r
-\r
- signal gs_debug : std_logic_vector(3 downto 0);\r
-\r
- signal i2c_speed : std_logic_vector(8 downto 0);\r
-\r
-begin\r
-\r
- i2c_speed <= I2C_SPEED_IN & "00";\r
-\r
--- Read phase indicator\r
- THE_PHASE_PROC: process( clk_in )\r
- begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
- phase <= '0';\r
- elsif( CURRENT_STATE = INC ) then\r
- phase <= '1';\r
- elsif( (CURRENT_STATE = DONE) or (CURRENT_STATE = SLEEP) ) then\r
- phase <= '0';\r
- end if;\r
- end if;\r
- end process THE_PHASE_PROC;\r
-\r
--- The main state machine\r
--- 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
- start <= '0';\r
- dostart <= '0';\r
- dobyte <= '0';\r
- i2c_done <= '0';\r
- running <= '0';\r
- load_a <= '0';\r
- load_c <= '0';\r
- load_d <= '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_a <= load_a_x;\r
- load_c <= load_c_x;\r
- load_d <= load_d_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)\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_a_x <= '0';\r
- load_c_x <= '0';\r
- load_d_x <= '0';\r
- case CURRENT_STATE is\r
- when SLEEP => if( i2c_go_in = '1' ) then\r
- NEXT_STATE <= CLRERR;\r
- else\r
- NEXT_STATE <= SLEEP;\r
- running_x <= '0';\r
- end if;\r
- when CLRERR => NEXT_STATE <= LOADA;\r
- load_a_x <= '1';\r
- when LOADA => NEXT_STATE <= GSTART;\r
- start_x <= '1';\r
- dostart_x <= '1';\r
- when GSTART => if ( (sdone = '1') and (sok = '1') ) then\r
- NEXT_STATE <= SENDA;\r
- dobyte_x <= '1';\r
- elsif( (sdone = '1') and (sok = '0') and (phase = '0') ) then\r
- NEXT_STATE <= E_START; -- first START condition failed\r
- elsif( (sdone = '1') and (sok = '0') and (phase = '1') ) then\r
- NEXT_STATE <= E_RSTART; -- second START condition failed\r
- else\r
- NEXT_STATE <= GSTART;\r
- start_x <= '1';\r
- dostart_x <= '1';\r
- end if;\r
- when E_START => NEXT_STATE <= FAILED;\r
- dostart_x <= '1';\r
- when E_RSTART => NEXT_STATE <= FAILED;\r
- dostart_x <= '1';\r
- when SENDA => if ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then\r
- NEXT_STATE <= LOADC; -- I2C write\r
- load_c_x <= '1';\r
- elsif( (bdone = '1') and (bok = '1') and (action_in = '1') and (phase = '0') ) then\r
- NEXT_STATE <= LOADC; -- I2C read, send register address\r
- load_c_x <= '1';\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
- load_d_x <= '1';\r
- elsif( (bdone = '1') and (bok = '0') and (phase = '0') ) then\r
- NEXT_STATE <= E_ADDR; -- first address phase failed\r
- elsif( (bdone = '1') and (bok = '0') and (phase = '1') ) then\r
- NEXT_STATE <= E_RADDR; -- second address phase failed\r
- else\r
- NEXT_STATE <= SENDA;\r
- dobyte_x <= '1';\r
- end if;\r
- when E_ADDR => NEXT_STATE <= FAILED;\r
- dostart_x <= '1';\r
- when E_RADDR => NEXT_STATE <= FAILED;\r
- dostart_x <= '1';\r
- when LOADC => NEXT_STATE <= SENDC;\r
--- dobyte_x <= '1';\r
- when SENDC => if ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then\r
- NEXT_STATE <= LOADD; -- I2C write, prepare data\r
- load_d_x <= '1';\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
- NEXT_STATE <= E_CMD; -- command phase failed\r
- else\r
- NEXT_STATE <= SENDC;\r
- dobyte_x <= '1';\r
- end if;\r
- when E_CMD => NEXT_STATE <= FAILED;\r
- dostart_x <= '1';\r
- when LOADD => NEXT_STATE <= SENDD;\r
- when SENDD => if ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then\r
- NEXT_STATE <= GSTOP; -- I2C write, data phase failed\r
- dostart_x <= '1';\r
- elsif( (bdone = '1') and (action_in = '1') ) then\r
- NEXT_STATE <= GSTOP; -- I2C read, data phase\r
- dostart_x <= '1';\r
- elsif( (bdone = '1') and (bok = '0') and (action_in = '0') ) then\r
- NEXT_STATE <= E_WD; -- I2C write, data phase failed\r
- else\r
- NEXT_STATE <= SENDD;\r
- dobyte_x <= '1';\r
- end if;\r
- when E_WD => NEXT_STATE <= FAILED;\r
- dostart_x <= '1';\r
- when GSTOP => if ( (sdone = '1') and (action_in = '0') ) then\r
- NEXT_STATE <= DONE;\r
- elsif( (sdone = '1') and (action_in = '1') and (phase = '1') ) then\r
- NEXT_STATE <= DONE;\r
- elsif( (sdone = '1') and (action_in = '1') and (phase = '0') ) then\r
- NEXT_STATE <= INC;\r
- else\r
- NEXT_STATE <= GSTOP;\r
- dostart_x <= '1';\r
- end if;\r
- when INC => NEXT_STATE <= LOADA;\r
- load_a_x <= '1';\r
- when FAILED => if( sdone = '1' ) then\r
- NEXT_STATE <= DONE;\r
- i2c_done_x <= '1';\r
- running_x <= '0';\r
- else\r
- NEXT_STATE <= FAILED;\r
- dostart_x <= '1';\r
- end if;\r
- when DONE => if( i2c_go_in = '1' ) then\r
- NEXT_STATE <= DONE;\r
- i2c_done_x <= '1';\r
- running_x <= '0';\r
- else\r
- NEXT_STATE <= SLEEP;\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 <= b"00000"; -- 00\r
- when CLRERR => bsm <= b"01100"; -- 0c\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 E_START => bsm <= b"10000"; -- 10\r
- when E_RSTART => bsm <= b"10001"; -- 11\r
- when E_ADDR => bsm <= b"10010"; -- 12\r
- when E_RADDR => bsm <= b"10011"; -- 13\r
- when E_CMD => bsm <= b"10100"; -- 14\r
- when E_WD => bsm <= b"10101"; -- 15\r
- when others => bsm <= b"11111"; -- 1f\r
- end case;\r
- end process DECODE;\r
-\r
--- We need to load different data sets\r
- LOAD_DATA_PROC: process( clk_in )\r
- begin\r
- if( rising_edge(clk_in) ) then\r
- if ( reset_in = '1' ) then\r
- i2c_byte <= (others => '1');\r
- elsif( (CURRENT_STATE = LOADA) and (phase = '0') ) then\r
- i2c_byte <= i2c_adr_in(6 downto 0) & '0' & '1'; -- send write address, receive ACK\r
- elsif( (CURRENT_STATE = LOADA) and (phase = '1') ) then\r
- i2c_byte <= i2c_adr_in(6 downto 0) & '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, 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, receive ACK\r
- elsif( (CURRENT_STATE = LOADD) and (action_in = '0') ) then\r
- i2c_byte <= i2c_dw_in & '1'; -- send data byte, receive ACK\r
- elsif( (CURRENT_STATE = LOADD) and (action_in = '1') ) then\r
- i2c_byte <= x"ff" & '1'; -- send 0xff byte, send NACK\r
- end if;\r
- end if;\r
- end process LOAD_DATA_PROC;\r
-\r
--- The SendByte module\r
- THE_I2C_SENDB: I2C_SENDB\r
- port map(\r
- CLK_IN => clk_in,\r
- RESET_IN => reset_in,\r
- DOBYTE_IN => dobyte,\r
- I2C_SPEED_IN => i2c_speed,\r
- I2C_BYTE_IN => i2c_byte,\r
- I2C_BACK_OUT => i2c_dr,\r
- SDA_IN => sda_in,\r
- R_SDA_OUT => r_sda_sb,\r
- S_SDA_OUT => s_sda_sb,\r
- R_SCL_OUT => r_scl_sb,\r
- S_SCL_OUT => s_scl_sb,\r
- BDONE_OUT => bdone,\r
- BOK_OUT => bok,\r
- BSM_OUT => open\r
- );\r
-\r
--- The GenStart module\r
- THE_I2C_GSTART: I2C_GSTART\r
- port map(\r
- CLK_IN => clk_in,\r
- RESET_IN => reset_in,\r
- START_IN => start,\r
- DOSTART_IN => dostart,\r
- I2C_SPEED_IN => i2c_speed,\r
- SDONE_OUT => sdone,\r
- SOK_OUT => sok,\r
- SDA_IN => sda_in,\r
- SCL_IN => scl_in,\r
- R_SCL_OUT => r_scl_gs,\r
- S_SCL_OUT => s_scl_gs,\r
- R_SDA_OUT => r_sda_gs,\r
- S_SDA_OUT => s_sda_gs,\r
- BSM_OUT => gs_debug --open\r
- );\r
-\r
- r_scl <= r_scl_gs or r_scl_sb;\r
- s_scl <= s_scl_gs or s_scl_sb;\r
- r_sda <= r_sda_gs or r_sda_sb;\r
- s_sda <= s_sda_gs or s_sda_sb;\r
-\r
--- Output flipflops for SCL and SDA lines\r
- THE_SCL_SDA_PROC: process( clk_in )\r
- begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
- scl_out <= '1';\r
- sda_out <= '1';\r
- elsif( (r_scl = '1') and (s_scl = '0') ) then\r
- scl_out <= '0';\r
- elsif( (r_scl = '0') and (s_scl = '1') ) then\r
- scl_out <= '1';\r
- elsif( (r_sda = '1') and (s_sda = '0') ) then\r
- sda_out <= '0';\r
- elsif( (r_sda = '0') and (s_sda = '1') ) then\r
- sda_out <= '1';\r
- end if;\r
- end if;\r
- end process THE_SCL_SDA_PROC;\r
-\r
--- Error bits\r
- THE_ERR_REG_PROC: process( clk_in )\r
- begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
- e_sf <= '0';\r
- e_anak <= '0';\r
- e_cnak <= '0';\r
- e_dnak <= '0';\r
- e_rsf <= '0';\r
- e_ranak <= '0';\r
- elsif( CURRENT_STATE = CLRERR ) then\r
- e_sf <= '0';\r
- e_anak <= '0';\r
- e_cnak <= '0';\r
- e_dnak <= '0';\r
- e_rsf <= '0';\r
- e_ranak <= '0';\r
- elsif( CURRENT_STATE = E_START ) then\r
- e_sf <= '1';\r
- elsif( CURRENT_STATE = E_RSTART ) then\r
- e_rsf <= '1';\r
- elsif( CURRENT_STATE = E_ADDR ) then\r
- e_anak <= '1';\r
- elsif( CURRENT_STATE = E_RADDR ) then\r
- e_ranak <= '1';\r
- elsif( CURRENT_STATE = E_CMD ) then\r
- e_cnak <= '1';\r
- elsif( CURRENT_STATE = E_WD ) then\r
- e_dnak <= '1';\r
- end if;\r
- end if;\r
- end process THE_ERR_REG_PROC;\r
-\r
- status_out(7) <= running;\r
- status_out(6) <= i2c_done;\r
- status_out(5) <= e_ranak;\r
- status_out(4) <= e_rsf;\r
- status_out(3) <= e_dnak;\r
- status_out(2) <= e_cnak;\r
- status_out(1) <= e_anak;\r
- status_out(0) <= e_sf;\r
-\r
--- Outputs\r
- i2c_dr_out <= i2c_dr(8 downto 1);\r
- i2c_busy_out <= running;\r
-\r
--- Debug stuff\r
- stat(31 downto 28) <= (others => '0');\r
- stat(27) <= s_sda;\r
- stat(26) <= r_sda;\r
- stat(25) <= s_scl;\r
- stat(24) <= r_scl;\r
- stat(23) <= s_sda_sb;\r
- stat(22) <= r_sda_sb;\r
- stat(21) <= s_scl_sb;\r
- stat(20) <= r_scl_sb;\r
- stat(19) <= s_sda_gs;\r
- stat(18) <= r_sda_gs;\r
- stat(17) <= s_scl_gs;\r
- stat(16) <= r_scl_gs;\r
- stat(15 downto 12) <= gs_debug;\r
- stat(11) <= bok;\r
- stat(10) <= bdone;\r
- stat(9) <= dobyte;\r
- stat(8) <= sok;\r
- stat(7) <= dobyte;\r
- stat(6) <= s_sda_sb;\r
- stat(5) <= r_sda_sb;\r
- stat(4 downto 0) <= bsm;\r
-\r
-\r
-end Behavioral;\r
+++ /dev/null
-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
-entity nx_i2c_master 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
- -- I2C connections\r
- SDA_INOUT : inout std_logic;\r
- SCL_INOUT : inout std_logic;\r
-\r
- -- Slave bus \r
- SLV_READ_IN : in std_logic;\r
- SLV_WRITE_IN : in std_logic;\r
- SLV_DATA_OUT : out std_logic_vector(31 downto 0);\r
- SLV_DATA_IN : in std_logic_vector(31 downto 0);\r
- 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
- -- Debug Line\r
- DEBUG_OUT : out std_logic_vector(15 downto 0)\r
- );\r
-end entity;\r
-\r
-architecture Behavioral of nx_i2c_master is\r
-\r
- signal sda_i : std_logic;\r
- signal sda_x : std_logic;\r
- signal sda : std_logic;\r
-\r
- signal scl_i : std_logic;\r
- signal scl_x : std_logic;\r
- signal scl : std_logic;\r
-\r
- -- I2C Master \r
- signal sda_o : std_logic;\r
- signal scl_o : std_logic;\r
- signal i2c_start : std_logic;\r
-\r
- signal sda_startstop : std_logic;\r
- signal scl_startstop : std_logic;\r
- signal startstop_select : std_logic;\r
- signal startstop_seq_start : std_logic;\r
- signal startstop_done : std_logic;\r
-\r
- signal sda_sendbyte : std_logic;\r
- signal scl_sendbyte : std_logic;\r
- signal sendbyte_seq_start : std_logic;\r
- signal sendbyte_byte : std_logic_vector(7 downto 0);\r
- signal sendbyte_done : std_logic;\r
- signal sendbyte_ack : std_logic;\r
-\r
- signal i2c_byte : unsigned(7 downto 0);\r
- signal bit_ctr : unsigned(3 downto 0);\r
- signal i2c_ack : std_logic;\r
- signal i2c_error : std_logic_vector(3 downto 0);\r
-\r
- type STATES is (S_IDLE,\r
- S_START,\r
- S_START_WAIT,\r
- \r
- S_SEND_BYTE,\r
- S_SET_SDA,\r
- S_SET_SCL,\r
- S_UNSET_SCL,\r
- S_NEXT_BIT,\r
-\r
- S_GET_ACK,\r
- S_ACK_SET_SCL,\r
- S_STORE_ACK,\r
- S_ACK_UNSET_SCL,\r
- S_VERIFY_ACK,\r
- S_ACK_ERROR,\r
- \r
- S_STOP,\r
- S_STOP_WAIT\r
- );\r
- signal STATE : STATES;\r
-\r
- \r
- -- I2C Timer\r
- signal wait_timer_init : unsigned(11 downto 0);\r
- signal wait_timer_done : std_logic;\r
- \r
- -- TRBNet Slave Bus\r
- signal slv_data_out_o : std_logic_vector(31 downto 0);\r
- 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
-\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
- -- Start / Stop Sequence\r
- nx_i2c_startstop_1: nx_i2c_startstop\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 => startstop_seq_start,\r
- SELECT_IN => startstop_select,\r
- SEQUENCE_DONE_OUT => startstop_done,\r
- SDA_OUT => sda_startstop,\r
- SCL_OUT => scl_startstop\r
- );\r
-\r
- nx_i2c_sendbyte_1: nx_i2c_sendbyte\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 => sendbyte_seq_start,\r
- BYTE_IN => sendbyte_byte,\r
- SEQUENCE_DONE_OUT => sendbyte_done,\r
- SDA_OUT => sda_sendbyte,\r
- SCL_OUT => scl_sendbyte,\r
- SDA_IN => sda,\r
- ACK_OUT => sendbyte_ack\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) <= wait_timer_done;\r
- DEBUG_OUT(7 downto 4) <= i2c_error;\r
-\r
- DEBUG_OUT(15 downto 8) <= (others => '0');\r
- \r
- -- Sync I2C Lines\r
- sda_i <= SDA_INOUT;\r
- scl_i <= SCL_INOUT;\r
-\r
- PROC_I2C_LINES_SYNC: process(CLK_IN)\r
- begin\r
- if( rising_edge(CLK_IN) ) then\r
- if( RESET_IN = '1' ) then\r
- sda_x <= '1';\r
- sda <= '1';\r
-\r
- scl_x <= '1';\r
- scl <= '1';\r
- else\r
- sda_x <= sda_i;\r
- sda <= sda_x;\r
-\r
- scl_x <= scl_i;\r
- scl <= scl_x;\r
- end if;\r
- end if;\r
- end process PROC_I2C_LINES_SYNC;\r
-\r
- PROC_I2C_MASTER: process(CLK_IN)\r
- begin \r
- if( rising_edge(CLK_IN) ) then\r
- if( RESET_IN = '1' ) then\r
- sda_o <= '1';\r
- scl_o <= '1';\r
- wait_timer_init <= (others => '0');\r
- bit_ctr <= (others => '0');\r
- i2c_ack <= '0';\r
- i2c_error <= (others => '0');\r
- startstop_select <= '0';\r
- startstop_seq_start <= '0';\r
- STATE <= S_IDLE;\r
- else\r
- sda_o <= '1';\r
- scl_o <= '1';\r
- wait_timer_init <= (others => '0');\r
- startstop_select <= '0';\r
- startstop_seq_start <= '0';\r
- case STATE is\r
- when S_IDLE =>\r
- if (i2c_start = '1') then\r
- STATE <= S_START;\r
- else\r
- STATE <= S_IDLE;\r
- end if;\r
- \r
- -- I2C START Sequence \r
- when S_START =>\r
- i2c_ack <= '0';\r
- startstop_select <= '1';\r
- startstop_seq_start <= '1';\r
- STATE <= S_START_WAIT;\r
-\r
- when S_START_WAIT =>\r
- if (startstop_done = '0') then\r
- STATE <= S_START_WAIT;\r
- else\r
- STATE <= S_SEND_BYTE;\r
- end if;\r
- \r
- -- I2C Send byte\r
- when S_SEND_BYTE =>\r
- bit_ctr <= x"7";\r
- sda_o <= '0';\r
- scl_o <= '0';\r
- i2c_byte(7 downto 1) <= i2c_chipid;\r
- i2c_byte(0) <= i2c_rw_bit;\r
- wait_timer_init <= i2c_speed srl 2;\r
- STATE <= S_SET_SDA;\r
-\r
- when S_SET_SDA =>\r
- sda_o <= i2c_byte(7);\r
- scl_o <= '0';\r
- if (wait_timer_done = '0') then\r
- STATE <= S_SET_SDA;\r
- else\r
- wait_timer_init <= i2c_speed srl 1;\r
- STATE <= S_SET_SCL;\r
- end if;\r
-\r
- when S_SET_SCL =>\r
- sda_o <= i2c_byte(7);\r
- if (wait_timer_done = '0') then\r
- STATE <= S_SET_SCL;\r
- else\r
- wait_timer_init <= i2c_speed srl 2;\r
- STATE <= S_UNSET_SCL;\r
- end if;\r
-\r
- when S_UNSET_SCL =>\r
- sda_o <= i2c_byte(7);\r
- scl_o <= '0';\r
- if (wait_timer_done = '0') then\r
- STATE <= S_UNSET_SCL;\r
- else\r
- STATE <= S_NEXT_BIT;\r
- end if;\r
- \r
- when S_NEXT_BIT =>\r
- sda_o <= i2c_byte(7);\r
- scl_o <= '0';\r
- if (bit_ctr > 0) then\r
- bit_ctr <= bit_ctr - 1;\r
- i2c_byte <= i2c_byte sll 1;\r
- wait_timer_init <= i2c_speed srl 2;\r
- STATE <= S_SET_SDA;\r
- else\r
- wait_timer_init <= i2c_speed srl 2;\r
- STATE <= S_GET_ACK;\r
- end if;\r
-\r
- -- I2C Check ACK Sequence\r
- when S_GET_ACK =>\r
- scl_o <= '0';\r
- if (wait_timer_done = '0') then\r
- STATE <= S_GET_ACK;\r
- else\r
- wait_timer_init <= i2c_speed srl 2;\r
- STATE <= S_ACK_SET_SCL;\r
- end if;\r
-\r
- when S_ACK_SET_SCL =>\r
- if (wait_timer_done = '0') then\r
- STATE <= S_ACK_SET_SCL;\r
- else\r
- STATE <= S_STORE_ACK;\r
- end if; \r
-\r
- when S_STORE_ACK =>\r
- i2c_ack <= sda;\r
- wait_timer_init <= i2c_speed srl 2;\r
- STATE <= S_ACK_UNSET_SCL;\r
- \r
- when S_ACK_UNSET_SCL =>\r
- scl_o <= '0';\r
- if (wait_timer_done = '0') then\r
- STATE <= S_ACK_UNSET_SCL;\r
- else\r
- STATE <= S_VERIFY_ACK;\r
- end if;\r
-\r
- when S_VERIFY_ACK =>\r
- scl_o <= '0';\r
- if (i2c_ack = '0') then\r
- STATE <= S_STOP;\r
- else\r
- STATE <= S_ACK_ERROR;\r
- end if;\r
-\r
- when S_ACK_ERROR =>\r
- scl_o <= '0';\r
- i2c_error(1) <= '1';\r
- STATE <= S_STOP;\r
-\r
- -- I2C STOP Sequence \r
- when S_STOP =>\r
- startstop_select <= '0';\r
- startstop_seq_start <= '1';\r
- STATE <= S_STOP_WAIT;\r
-\r
- when S_STOP_WAIT =>\r
- if (startstop_done = '0') then\r
- STATE <= S_STOP_WAIT;\r
- else\r
- STATE <= S_IDLE;\r
- end if;\r
-\r
- end case;\r
-\r
- end if;\r
- end if;\r
- end process PROC_I2C_MASTER;\r
-\r
- -----------------------------------------------------------------------------\r
- -- TRBNet Slave Bus\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
- slv_ack_o <= '0';\r
- i2c_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
- i2c_start <= '0';\r
- \r
- if (SLV_WRITE_IN = '1') then\r
- i2c_chipid <= SLV_DATA_IN(6 downto 0);\r
- i2c_rw_bit <= SLV_DATA_IN(7);\r
- i2c_start <= '1';\r
- elsif (SLV_READ_IN = '1') then\r
- slv_data_out_o <= reg_data;\r
- \r
- else\r
- slv_ack_o <= '0';\r
- end if;\r
- end if;\r
- end if; \r
- end process PROC_SLAVE_BUS;\r
-\r
- -----------------------------------------------------------------------------\r
- -- Output Signals\r
- -----------------------------------------------------------------------------\r
-\r
- -- I2c Outputs\r
- SDA_INOUT <= '0' when (sda_o = '0' or sda_startstop = '0') else 'Z';\r
- SCL_INOUT <= '0' when (scl_o = '0' or scl_startstop = '0') else 'Z';\r
-\r
- -- Slave Bus\r
- SLV_DATA_OUT <= slv_data_out_o; \r
- SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; \r
- SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o;\r
- SLV_ACK_OUT <= slv_ack_o; \r
-\r
-end Behavioral;\r