From 8ac7ed21bda69313fd70661ee230075bdb2d9a51 Mon Sep 17 00:00:00 2001 From: hadaq Date: Sat, 10 Nov 2012 20:53:47 +0000 Subject: [PATCH] i2c seems to be working now --- nxyter/source/nx_i2c_master.vhd | 268 ++++++++++++++++++++-------- nxyter/source/nx_i2c_readbyte.vhd | 237 ++++++++++++++++++++++++ nxyter/source/nx_i2c_startstop.vhd | 1 - nxyter/source/nxyter.vhd | 70 +++----- nxyter/source/nxyter_components.vhd | 19 +- nxyter/source/nxyter_registers.vhd | 145 +++++++++++++-- 6 files changed, 604 insertions(+), 136 deletions(-) create mode 100644 nxyter/source/nx_i2c_readbyte.vhd diff --git a/nxyter/source/nx_i2c_master.vhd b/nxyter/source/nx_i2c_master.vhd index d092a06..2c74b9d 100644 --- a/nxyter/source/nx_i2c_master.vhd +++ b/nxyter/source/nx_i2c_master.vhd @@ -45,32 +45,43 @@ architecture Behavioral of nx_i2c_master is signal sda_o : std_logic; signal scl_o : std_logic; signal i2c_start : std_logic; - + + signal i2c_busy : std_logic; signal startstop_select : std_logic; signal startstop_seq_start : std_logic; signal sendbyte_seq_start : std_logic; + signal readbyte_seq_start : std_logic; signal sendbyte_byte : std_logic_vector(7 downto 0); + signal read_seq_ctr : std_logic; + signal reg_data : std_logic_vector(31 downto 0); + signal i2c_busy_x : std_logic; signal startstop_select_x : std_logic; signal startstop_seq_start_x : std_logic; signal wait_timer_init_x : std_logic_vector(11 downto 0); signal sendbyte_seq_start_x : std_logic; signal sendbyte_byte_x : std_logic_vector(7 downto 0); - signal i2c_ack_x : std_logic; + signal readbyte_seq_start_x : std_logic; + signal read_seq_ctr_x : std_logic; + signal reg_data_x : std_logic_vector(31 downto 0); signal sda_startstop : std_logic; signal scl_startstop : std_logic; - signal sda_sendbyte : std_logic; - signal scl_sendbyte : std_logic; + signal i2c_notready : std_logic; signal startstop_done : std_logic; - signal sendbyte_done : std_logic; + signal sda_sendbyte : std_logic; + signal scl_sendbyte : std_logic; signal sendbyte_ack : std_logic; - signal i2c_ack : std_logic; - signal i2c_notready : std_logic; - signal i2c_error : std_logic_vector(3 downto 0); - - type STATES is (S_IDLE, + signal sendbyte_done : std_logic; + + signal sda_readbyte : std_logic; + signal scl_readbyte : std_logic; + signal readbyte_byte : std_logic_vector(7 downto 0); + signal readbyte_done : std_logic; + + type STATES is (S_RESET, + S_IDLE, S_START, S_START_WAIT, @@ -78,6 +89,10 @@ architecture Behavioral of nx_i2c_master is S_SEND_CHIP_ID_WAIT, S_SEND_REGISTER, S_SEND_REGISTER_WAIT, + S_SEND_DATA, + S_SEND_DATA_WAIT, + S_GET_DATA, + S_GET_DATA_WAIT, S_STOP, S_STOP_WAIT @@ -94,7 +109,6 @@ architecture Behavioral of nx_i2c_master is signal slv_no_more_data_o : std_logic; signal slv_unknown_addr_o : std_logic; signal slv_ack_o : std_logic; - signal reg_data : std_logic_vector(31 downto 0); signal i2c_chipid : std_logic_vector(6 downto 0); signal i2c_rw_bit : std_logic; signal i2c_registerid : std_logic_vector(7 downto 0); @@ -143,25 +157,41 @@ begin SDA_IN => sda, ACK_OUT => sendbyte_ack ); + + nx_i2c_readbyte_1: nx_i2c_readbyte + generic map ( + i2c_speed => i2c_speed + ) + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + START_IN => readbyte_seq_start, + BYTE_OUT => readbyte_byte, + SEQUENCE_DONE_OUT => readbyte_done, + SDA_OUT => sda_readbyte, + SCL_OUT => scl_readbyte, + SDA_IN => sda + ); -- Debug Line - DEBUG_OUT(0) <= sda_o; - DEBUG_OUT(1) <= scl_o; - DEBUG_OUT(2) <= i2c_start; - DEBUG_OUT(3) <= startstop_done; - DEBUG_OUT(4) <= sda_startstop; - DEBUG_OUT(5) <= scl_startstop; - DEBUG_OUT(6) <= sda_sendbyte; - DEBUG_OUT(7) <= scl_sendbyte; + -- DEBUG_OUT(0) <= not sendbyte_ack; + -- DEBUG_OUT(1) <= sda_o; + -- DEBUG_OUT(2) <= scl_o; + -- DEBUG_OUT(3) <= sda_startstop; + -- DEBUG_OUT(4) <= scl_startstop; + -- DEBUG_OUT(5) <= sda_sendbyte; + -- DEBUG_OUT(6) <= scl_sendbyte; + -- DEBUG_OUT(7) <= sda_readbyte; + -- DEBUG_OUT(8) <= scl_readbyte; + -- DEBUG_OUT(9) <= i2c_start; --- DEBUG_OUT(11 downto 8) <= i2c_error; + -- DEBUG_OUT(8) <= i2c_start; + -- DEBUG_OUT(15 downto 10) <= (others => '0'); + DEBUG_OUT(0) <= i2c_start; + DEBUG_OUT(15 downto 14) <= (others => '0'); + DEBUG_OUT(13 downto 9) <= reg_data(28 downto 24); + DEBUG_OUT(8 downto 1) <= reg_data(7 downto 0); - DEBUG_OUT(15 downto 8) <= (others => '0'); - - i2c_error(0) <= i2c_notready; - i2c_error(1) <= not sendbyte_ack; - i2c_error(3 downto 2) <= (others => '0'); - -- Sync I2C Lines sda_i <= SDA_INOUT; scl_i <= SCL_INOUT; @@ -189,20 +219,26 @@ begin begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - i2c_ack <= '0'; + i2c_busy <= '1'; startstop_select <= '0'; startstop_seq_start <= '0'; sendbyte_seq_start <= '0'; + readbyte_seq_start <= '0'; sendbyte_byte <= (others => '0'); wait_timer_init <= (others => '0'); - STATE <= S_IDLE; + reg_data <= (others => '0'); + read_seq_ctr <= '0'; + STATE <= S_RESET; else - i2c_ack <= i2c_ack_x; + i2c_busy <= i2c_busy_x; startstop_select <= startstop_select_x; startstop_seq_start <= startstop_seq_start_x; sendbyte_seq_start <= sendbyte_seq_start_x; + readbyte_seq_start <= readbyte_seq_start_x; sendbyte_byte <= sendbyte_byte_x; wait_timer_init <= wait_timer_init_x; + reg_data <= reg_data_x; + read_seq_ctr <= read_seq_ctr_x; STATE <= NEXT_STATE; end if; end if; @@ -210,24 +246,36 @@ begin PROC_I2C_MASTER: process(STATE) + begin -- Defaults sda_o <= '1'; scl_o <= '1'; - i2c_ack_x <= '0'; + i2c_busy_x <= '1'; startstop_select_x <= '0'; startstop_seq_start_x <= '0'; sendbyte_seq_start_x <= '0'; sendbyte_byte_x <= (others => '0'); + readbyte_seq_start_x <= '0'; wait_timer_init_x <= (others => '0'); + reg_data_x <= reg_data; + read_seq_ctr_x <= read_seq_ctr; case STATE is + when S_RESET => + reg_data_x <= (others => '0'); + NEXT_STATE <= S_IDLE; + when S_IDLE => if (i2c_start = '1') then + reg_data_x <= x"8000_0000"; -- Set Running , clear all other bits NEXT_STATE <= S_START; else - NEXT_STATE <= S_IDLE; + i2c_busy_x <= '0'; + reg_data_x <= reg_data and x"7fff_ffff"; -- clear running bit; + read_seq_ctr_x <= '0'; + NEXT_STATE <= S_IDLE; end if; -- I2C START Sequence @@ -247,10 +295,13 @@ begin -- I2C SEND ChipId Sequence when S_SEND_CHIP_ID => - sda_o <= '0'; scl_o <= '0'; sendbyte_byte_x(7 downto 1) <= i2c_chipid; - sendbyte_byte_x(0) <= i2c_rw_bit; + if (read_seq_ctr = '0') then + sendbyte_byte_x(0) <= '0'; + else + sendbyte_byte_x(0) <= '1'; + end if; sendbyte_seq_start_x <= '1'; NEXT_STATE <= S_SEND_CHIP_ID_WAIT; @@ -258,29 +309,77 @@ begin if (sendbyte_done = '0') then NEXT_STATE <= S_SEND_CHIP_ID_WAIT; else - sda_o <= '0'; scl_o <= '0'; - NEXT_STATE <= S_SEND_REGISTER; + if (sendbyte_ack = '0') then + reg_data_x <= reg_data or x"0100_0000"; + NEXT_STATE <= S_STOP; + else + if (read_seq_ctr = '0') then + read_seq_ctr_x <= '1'; + NEXT_STATE <= S_SEND_REGISTER; + else + NEXT_STATE <= S_GET_DATA; + end if; + end if; end if; - - -- I2C SEND RegisterId Sequence - + + -- I2C SEND RegisterId when S_SEND_REGISTER => - sda_o <= '0'; scl_o <= '0'; - sendbyte_byte_x <= i2c_registerid; - sendbyte_seq_start_x <= '1'; - NEXT_STATE <= S_SEND_REGISTER_WAIT; + sendbyte_byte_x <= i2c_registerid; + sendbyte_seq_start_x <= '1'; + NEXT_STATE <= S_SEND_REGISTER_WAIT; when S_SEND_REGISTER_WAIT => if (sendbyte_done = '0') then NEXT_STATE <= S_SEND_REGISTER_WAIT; else - sda_o <= '0'; scl_o <= '0'; + if (sendbyte_ack = '0') then + reg_data_x <= reg_data or x"0200_0000"; + NEXT_STATE <= S_STOP; + else + if (i2c_rw_bit = '0') then + NEXT_STATE <= S_SEND_DATA; + else + NEXT_STATE <= S_START; + end if; + end if; + end if; + + -- I2C SEND DataWord + when S_SEND_DATA => + scl_o <= '0'; + sendbyte_byte_x <= i2c_register_data; + sendbyte_seq_start_x <= '1'; + NEXT_STATE <= S_SEND_DATA_WAIT; + + when S_SEND_DATA_WAIT => + if (sendbyte_done = '0') then + NEXT_STATE <= S_SEND_DATA_WAIT; + else + scl_o <= '0'; + if (sendbyte_ack = '0') then + reg_data_x <= reg_data or x"0400_0000"; + end if; NEXT_STATE <= S_STOP; end if; - + + -- I2C GET DataWord + when S_GET_DATA => + scl_o <= '0'; + readbyte_seq_start_x <= '1'; + NEXT_STATE <= S_GET_DATA_WAIT; + + when S_GET_DATA_WAIT => + if (readbyte_done = '0') then + NEXT_STATE <= S_GET_DATA_WAIT; + else + scl_o <= '0'; + reg_data_x(7 downto 0) <= readbyte_byte; + NEXT_STATE <= S_STOP; + end if; + -- I2C STOP Sequence when S_STOP => sda_o <= '0'; @@ -293,6 +392,7 @@ begin if (startstop_done = '0') then NEXT_STATE <= S_STOP_WAIT; else + reg_data_x <= reg_data or x"4000_0000"; -- Set DONE Bit NEXT_STATE <= S_IDLE; end if; @@ -302,12 +402,41 @@ begin ----------------------------------------------------------------------------- -- TRBNet Slave Bus ----------------------------------------------------------------------------- - + -- + -- Write bit definition + -- ==================== + -- + -- D[31] I2C_GO 0 => don't do anything on I2C, + -- 1 => start I2C access + -- D[30] I2C_ACTION 0 => write byte, 1 => read byte + -- D[29:24] I2C_SPEED set to all '1' + -- D[23:16] I2C_ADDRESS address of I2C chip + -- D[15:8] I2C_CMD command byte for access + -- D[7:0] I2C_DATA data to be written + -- + -- + -- Read bit definition + -- =================== + -- + -- D[31:24] status status information + -- D[31] RUNNING whatever + -- D[30] I2C_DONE whatever + -- D[29] ERROR_RADDACK no acknowledge for repeated address byte + -- D[28] ERROR_RSTART generation of repeated START condition failed + -- D[27] ERROR_DATACK no acknowledge for data byte + -- D[26] ERROR_CMDACK no acknowledge for command byte + -- D[25] ERROR_ADDACK no acknowledge for address byte + -- D[24] ERROR_START generation of START condition failed + -- D[23:21] reserved reserved + -- D[20:16] debug subject to change, don't use + -- D[15:8] reserved reserved + -- D[7:0] I2C_DATA result of I2C read operation + -- + PROC_SLAVE_BUS: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - reg_data <= x"affeaffe"; slv_data_out_o <= (others => '0'); slv_no_more_data_o <= '0'; slv_unknown_addr_o <= '0'; @@ -321,21 +450,30 @@ begin i2c_register_value_read <= (others => '0'); else - slv_ack_o <= '1'; + slv_ack_o <= '1'; slv_unknown_addr_o <= '0'; slv_no_more_data_o <= '0'; slv_data_out_o <= (others => '0'); i2c_start <= '0'; if (SLV_WRITE_IN = '1') then - i2c_chipid <= SLV_DATA_IN(30 downto 24); - i2c_registerid <= SLV_DATA_IN(23 downto 16); - i2c_rw_bit <= SLV_DATA_IN(8); - i2c_register_data <= SLV_DATA_IN(7 downto 0); - i2c_start <= '1'; + if (i2c_busy = '0' and SLV_DATA_IN(31) = '1') then + i2c_rw_bit <= SLV_DATA_IN(30); + i2c_chipid <= SLV_DATA_IN(22 downto 16); + i2c_registerid <= SLV_DATA_IN(15 downto 8); + i2c_register_data <= SLV_DATA_IN(7 downto 0); + i2c_start <= '1'; + end if; + elsif (SLV_READ_IN = '1') then - slv_data_out_o <= reg_data; - + if (i2c_busy = '1') then + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '1'; + slv_ack_o <= '0'; + else + slv_data_out_o <= reg_data; + end if; + else slv_ack_o <= '0'; end if; @@ -344,33 +482,21 @@ begin end process PROC_SLAVE_BUS; - --- Write bit definition OLD boehmer --- ==================== --- --- --- D[31] I2C_GO 0 => don't do anything on I2C, 1 => start I2C access --- D[30] I2C_ACTION 0 => write byte, 1 => read byte --- D[29:24] I2C_SPEED set to all '1' --- D[23:16] I2C_ADDRESS address of I2C chip --- D[15:8] I2C_CMD command byte for access --- D[7:0] I2C_DATA data to be written --- --- - ----------------------------------------------------------------------------- -- Output Signals ----------------------------------------------------------------------------- - -- I2c Outputs + -- I2C Outputs SDA_INOUT <= '0' when (sda_o = '0' or sda_startstop = '0' or - sda_sendbyte = '0') + sda_sendbyte = '0' or + sda_readbyte = '0') else 'Z'; SCL_INOUT <= '0' when (scl_o = '0' or scl_startstop = '0' or - scl_sendbyte = '0') + scl_sendbyte = '0' or + scl_readbyte = '0') else 'Z'; -- Slave Bus diff --git a/nxyter/source/nx_i2c_readbyte.vhd b/nxyter/source/nx_i2c_readbyte.vhd new file mode 100644 index 0000000..58a3197 --- /dev/null +++ b/nxyter/source/nx_i2c_readbyte.vhd @@ -0,0 +1,237 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.nxyter_components.all; + + +entity nx_i2c_readbyte is + generic ( + i2c_speed : unsigned(11 downto 0) := x"3e8" + ); + 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; + + -- I2C connections + SDA_OUT : out std_logic; + SCL_OUT : out std_logic; + SDA_IN : in std_logic + ); +end entity; + +architecture Behavioral of nx_i2c_readbyte is + + -- Send Byte + signal sda_o : std_logic; + signal scl_o : std_logic; + signal i2c_start : std_logic; + + signal sequence_done_o : std_logic; + signal i2c_byte : unsigned(7 downto 0); + signal bit_ctr : unsigned(3 downto 0); + signal i2c_ack_o : std_logic; + signal wait_timer_init : unsigned(11 downto 0); + + signal sequence_done_o_x : std_logic; + signal i2c_byte_x : unsigned(7 downto 0); + signal bit_ctr_x : unsigned(3 downto 0); + signal i2c_ack_o_x : std_logic; + signal wait_timer_init_x : unsigned(11 downto 0); + + type STATES is (S_IDLE, + S_INIT, + S_INIT_WAIT, + + S_READ_BYTE, + S_UNSET_SCL1, + S_SET_SCL1, + s_GET_BIT, + S_SET_SCL2, + S_UNSET_SCL2, + S_NEXT_BIT, + + S_SET_ACK, + S_ACK_SET_SCL, + S_ACK_UNSET_SCL + ); + signal STATE, NEXT_STATE : STATES; + + -- Wait Timer + signal wait_timer_done : std_logic; + +begin + + -- Timer + nx_i2c_timer_1: nx_i2c_timer + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + TIMER_START_IN => wait_timer_init, + TIMER_DONE_OUT => wait_timer_done + ); + + + PROC_READ_BYTE_TRANSFER: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + sequence_done_o <= '0'; + bit_ctr <= (others => '0'); + i2c_ack_o <= '0'; + wait_timer_init <= (others => '0'); + STATE <= S_IDLE; + else + sequence_done_o <= sequence_done_o_x; + i2c_byte <= i2c_byte_x; + bit_ctr <= bit_ctr_x; + i2c_ack_o <= i2c_ack_o_x; + wait_timer_init <= wait_timer_init_x; + STATE <= NEXT_STATE; + end if; + end if; + end process PROC_READ_BYTE_TRANSFER; + + PROC_READ_BYTE: process(STATE) + begin + sda_o <= '1'; + scl_o <= '1'; + sequence_done_o_x <= '0'; + i2c_byte_x <= i2c_byte; + bit_ctr_x <= bit_ctr; + i2c_ack_o_x <= i2c_ack_o; + wait_timer_init_x <= (others => '0'); + + case STATE is + when S_IDLE => + if (START_IN = '1') then + sda_o <= '0'; + scl_o <= '0'; + i2c_byte_x <= (others => '0'); + NEXT_STATE <= S_INIT; + else + NEXT_STATE <= S_IDLE; + end if; + + -- INIT + when S_INIT => + sda_o <= '0'; + scl_o <= '0'; + wait_timer_init_x <= i2c_speed srl 1; + NEXT_STATE <= S_INIT_WAIT; + + when S_INIT_WAIT => + sda_o <= '0'; + scl_o <= '0'; + if (wait_timer_done = '0') then + NEXT_STATE <= S_INIT_WAIT; + else + NEXT_STATE <= S_READ_BYTE; + end if; + + -- I2C Read byte + when S_READ_BYTE => + scl_o <= '0'; + bit_ctr_x <= x"7"; + wait_timer_init_x <= i2c_speed srl 2; + NEXT_STATE <= S_UNSET_SCL1; + + when S_UNSET_SCL1 => + scl_o <= '0'; + if (wait_timer_done = '0') then + NEXT_STATE <= S_UNSET_SCL1; + else + wait_timer_init_x <= i2c_speed srl 2; + NEXT_STATE <= S_SET_SCL1; + end if; + + when S_SET_SCL1 => + if (wait_timer_done = '0') then + NEXT_STATE <= S_SET_SCL1; + else + wait_timer_init_x <= i2c_speed srl 2; + NEXT_STATE <= S_GET_BIT; + end if; + + when S_GET_BIT => + i2c_byte_x(0) <= SDA_IN; + NEXT_STATE <= S_SET_SCL2; + + when S_SET_SCL2 => + if (wait_timer_done = '0') then + NEXT_STATE <= S_SET_SCL2; + else + wait_timer_init_x <= i2c_speed srl 2; + NEXT_STATE <= S_UNSET_SCL2; + end if; + + when S_UNSET_SCL2 => + scl_o <= '0'; + if (wait_timer_done = '0') then + NEXT_STATE <= S_UNSET_SCL2; + else + NEXT_STATE <= S_NEXT_BIT; + end if; + + when S_NEXT_BIT => + scl_o <= '0'; + if (bit_ctr > 0) then + bit_ctr_x <= bit_ctr - 1; + i2c_byte_x <= i2c_byte sll 1; + wait_timer_init_x <= i2c_speed srl 2; + NEXT_STATE <= S_UNSET_SCL1; + else + wait_timer_init_x <= i2c_speed srl 2; + NEXT_STATE <= S_SET_ACK; + end if; + + -- I2C Send ACK Sequence (doesn't work, so just send a clock) + when S_SET_ACK => + --sda_o <= '0'; + scl_o <= '0'; + if (wait_timer_done = '0') then + NEXT_STATE <= S_SET_ACK; + else + wait_timer_init_x <= i2c_speed srl 1; + NEXT_STATE <= S_ACK_SET_SCL; + end if; + + when S_ACK_SET_SCL => + -- sda_o <= '0'; + if (wait_timer_done = '0') then + NEXT_STATE <= S_ACK_SET_SCL; + else + wait_timer_init_x <= i2c_speed srl 2; + NEXT_STATE <= S_ACK_UNSET_SCL; + end if; + + when S_ACK_UNSET_SCL => + --sda_o <= '0'; + scl_o <= '0'; + if (wait_timer_done = '0') then + NEXT_STATE <= S_ACK_UNSET_SCL; + else + sequence_done_o_x <= '1'; + NEXT_STATE <= S_IDLE; + end if; + + end case; + end process PROC_READ_BYTE; + + ----------------------------------------------------------------------------- + -- Output Signals + ----------------------------------------------------------------------------- + + SEQUENCE_DONE_OUT <= sequence_done_o; + BYTE_OUT <= i2c_byte; + + -- I2c Outputs + SDA_OUT <= sda_o; + SCL_OUT <= scl_o; + +end Behavioral; diff --git a/nxyter/source/nx_i2c_startstop.vhd b/nxyter/source/nx_i2c_startstop.vhd index daba5fd..7b9c0fe 100644 --- a/nxyter/source/nx_i2c_startstop.vhd +++ b/nxyter/source/nx_i2c_startstop.vhd @@ -79,7 +79,6 @@ begin PROC_START_STOP: process(STATE) begin - sda_o <= '1'; scl_o <= '1'; wait_timer_init_x <= (others => '0'); diff --git a/nxyter/source/nxyter.vhd b/nxyter/source/nxyter.vhd index 69b9fa6..60f07c2 100644 --- a/nxyter/source/nxyter.vhd +++ b/nxyter/source/nxyter.vhd @@ -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 diff --git a/nxyter/source/nxyter_components.vhd b/nxyter/source/nxyter_components.vhd index cdb9ab5..5a56b94 100644 --- a/nxyter/source/nxyter_components.vhd +++ b/nxyter/source/nxyter_components.vhd @@ -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; diff --git a/nxyter/source/nxyter_registers.vhd b/nxyter/source/nxyter_registers.vhd index fc5290e..c287f7c 100644 --- a/nxyter/source/nxyter_registers.vhd +++ b/nxyter/source/nxyter_registers.vhd @@ -4,6 +4,7 @@ use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library work; +use work.nxyter_components.all; entity nxyter_registers is port( @@ -19,6 +20,11 @@ entity nxyter_registers is SLV_ACK_OUT : out std_logic; SLV_NO_MORE_DATA_OUT : out std_logic; SLV_UNKNOWN_ADDR_OUT : out std_logic; + + -- Signals + I2C_SM_RESET_OUT : out std_logic; + I2C_REG_RESET_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(15 downto 0) ); end entity; @@ -30,40 +36,140 @@ architecture Behavioral of nxyter_registers is signal slv_unknown_addr_o : std_logic; signal slv_ack_o : std_logic; + + -- I2C Reset + signal i2c_sm_reset_start : std_logic; + signal i2c_reg_reset_start : std_logic; + signal wait_timer_init_x : unsigned(7 downto 0); + signal i2c_sm_reset_o : std_logic; + signal i2c_reg_reset_o : std_logic; + + type STATES is (S_IDLE, + S_I2C_SM_RESET, + S_I2C_SM_RESET_WAIT, + S_I2C_REG_RESET, + S_I2C_REG_RESET_WAIT + ); + + signal STATE, NEXT_STATE : STATES; + + -- Wait Timer + signal wait_timer_init : unsigned(7 downto 0); + signal wait_timer_done : std_logic; + type reg_32bit_t is array (0 to 7) of std_logic_vector(31 downto 0); signal reg_data : reg_32bit_t; begin DEBUG_OUT <= reg_data(0)(15 downto 0); + + nx_i2c_timer_1: nx_i2c_timer + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + TIMER_START_IN(7 downto 0) => wait_timer_init, + TIMER_START_IN(11 downto 8) => open, + TIMER_DONE_OUT => wait_timer_done + ); + ----------------------------------------------------------------------------- + -- I2C SM Reset + ----------------------------------------------------------------------------- + + PROC_I2C_SM_RESET_TRANSFER: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + wait_timer_init <= (others => '0'); + STATE <= S_IDLE; + else + wait_timer_init <= wait_timer_init_x; + STATE <= NEXT_STATE; + end if; + end if; + end process PROC_I2C_SM_RESET_TRANSFER; + + PROC_I2C_SM_RESET: process(STATE) + begin + i2c_sm_reset_o <= '0'; + i2c_reg_reset_o <= '0'; + wait_timer_init_x <= (others => '0'); + + case STATE is + when S_IDLE => + if (i2c_sm_reset_start = '1') then + NEXT_STATE <= S_I2C_SM_RESET; + elsif (i2c_reg_reset_start = '1') then + NEXT_STATE <= S_I2C_REG_RESET; + else + NEXT_STATE <= S_IDLE; + end if; + + when S_I2C_SM_RESET => + i2c_sm_reset_o <= '1'; + wait_timer_init_x <= x"8f"; + NEXT_STATE <= S_I2C_SM_RESET_WAIT; + + when S_I2C_SM_RESET_WAIT => + i2c_sm_reset_o <= '1'; + if (wait_timer_done = '0') then + NEXT_STATE <= S_I2C_SM_RESET_WAIT; + else + NEXT_STATE <= S_IDLE; + end if; + + when S_I2C_REG_RESET => + i2c_reg_reset_o <= '1'; + wait_timer_init_x <= x"8f"; + NEXT_STATE <= S_I2C_REG_RESET_WAIT; + + when S_I2C_REG_RESET_WAIT => + i2c_reg_reset_o <= '1'; + if (wait_timer_done = '0') then + NEXT_STATE <= S_I2C_REG_RESET_WAIT; + else + NEXT_STATE <= S_IDLE; + end if; + + end case; + end process PROC_I2C_SM_RESET; + + ----------------------------------------------------------------------------- + -- Slave Bus + ----------------------------------------------------------------------------- PROC_NX_REGISTERS: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - reg_data(0) <= x"babe_0000"; - reg_data(1) <= x"babe_0001"; - reg_data(2) <= x"babe_0002"; - reg_data(3) <= x"babe_0003"; - reg_data(4) <= x"babe_0004"; - reg_data(5) <= x"babe_0005"; - reg_data(6) <= x"babe_0006"; - reg_data(7) <= x"babe_0007"; - - slv_data_out_o <= (others => '0'); - slv_no_more_data_o <= '0'; - slv_unknown_addr_o <= '0'; - slv_ack_o <= '0'; + reg_data(0) <= x"babe_0000"; + reg_data(1) <= x"babe_0001"; + reg_data(2) <= x"babe_0002"; + reg_data(3) <= x"babe_0003"; + reg_data(4) <= x"babe_0004"; + reg_data(5) <= x"babe_0005"; + reg_data(6) <= x"babe_0006"; + reg_data(7) <= x"babe_0007"; + + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_ack_o <= '0'; + + i2c_sm_reset_start <= '0'; + i2c_reg_reset_start <= '0'; else slv_ack_o <= '1'; - slv_unknown_addr_o <= '0'; - slv_no_more_data_o <= '0'; - slv_data_out_o <= (others => '0'); + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; + slv_data_out_o <= (others => '0'); + i2c_sm_reset_start <= '0'; + i2c_reg_reset_start <= '0'; if (SLV_WRITE_IN = '1') then case SLV_ADDR_IN is - when x"0000" => reg_data(0) <= SLV_DATA_IN; - when x"0001" => reg_data(1) <= SLV_DATA_IN; + when x"0000" => i2c_sm_reset_start <= '1'; + when x"0001" => i2c_reg_reset_start <= '1'; when x"0002" => reg_data(2) <= SLV_DATA_IN; when x"0003" => reg_data(3) <= SLV_DATA_IN; when x"0004" => reg_data(4) <= SLV_DATA_IN; @@ -101,4 +207,7 @@ begin SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o; SLV_ACK_OUT <= slv_ack_o; + I2C_SM_RESET_OUT <= i2c_sm_reset_o; + I2C_REG_RESET_OUT <= i2c_reg_reset_o; + end Behavioral; -- 2.43.0