From c55a3ea80d22bc58b0b272bd04de6ee54e459e6d Mon Sep 17 00:00:00 2001 From: Jan Michel Date: Thu, 15 Dec 2022 12:11:39 +0100 Subject: [PATCH] add common_i2c interface --- code/common_i2c.vhd | 123 ++++++++++++++++++++++++++++++++++++++++++ code/trb3sc_tools.vhd | 43 ++++++++++++--- 2 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 code/common_i2c.vhd diff --git a/code/common_i2c.vhd b/code/common_i2c.vhd new file mode 100644 index 0000000..a68036f --- /dev/null +++ b/code/common_i2c.vhd @@ -0,0 +1,123 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; + + +entity common_i2c is + port( + CLOCK : in std_logic; + RESET : in std_logic; + SDA : inout std_logic; + SCL : inout std_logic; + BUS_RX : in CTRLBUS_RX; + BUS_TX : out CTRLBUS_TX + ); +end entity; + +architecture Behavioral of common_i2c is + + signal i2c_reg_0 : std_logic_vector(31 downto 0); + signal i2c_reg_1 : std_logic_vector(31 downto 0); + signal i2c_reg_2 : std_logic_vector(31 downto 0); + signal i2c_reg_4 : std_logic_vector(31 downto 0); + signal sda_out_drv : std_logic; + signal scl_out_drv : std_logic; + +begin + + THE_I2C_SLIM : i2c_slim2 + port map( + CLOCK => CLOCK, + RESET => RESET, + -- I2C command / setup + I2C_GO_IN => i2c_reg_2(7), + ACTION_IN => i2c_reg_1(8), -- '0' -> write, '1' -> read + WORD_IN => i2c_reg_1(0), -- '0' -> byte, '1' -> word + DIRECT_IN => i2c_reg_1(4), -- don't send command + I2C_SPEED_IN => i2c_reg_0(5 downto 0), -- speed adjustment (to be defined) + I2C_ADDR_IN(7 downto 1) => i2c_reg_2(6 downto 0), -- I2C address byte (R/W bit is ignored) + I2C_ADDR_IN(0) => '0', + I2C_CMD_IN => i2c_reg_2(15 downto 8), -- I2C command byte (sent after address byte) + I2C_DW_IN => i2c_reg_2(31 downto 16), -- data word for write command + I2C_DR_OUT => i2c_reg_4(15 downto 0), -- data word from read command + STATUS_OUT => i2c_reg_4(23 downto 16), + VALID_OUT => i2c_reg_4(31), + I2C_BUSY_OUT => i2c_reg_4(30), + I2C_DONE_OUT => i2c_reg_4(29), + -- I2C connections + SDA_IN => SDA, + SDA_OUT => sda_out_drv, + SCL_IN => SCL, + SCL_OUT => scl_out_drv, + -- Debug + BSM_OUT => i2c_reg_4(27 downto 24) + ); + + SDA <= '0' when (sda_out_drv = '0' or i2c_reg_1(31) = '1') else 'Z'; + SCL <= '0' when (scl_out_drv = '0' or i2c_reg_1(30) = '1') else 'Z'; + + PROC_I2C_REGS : process + begin + wait until rising_edge(CLOCK); + BUS_TX.ack <= '0'; + BUS_TX.unknown <= '0'; + BUS_TX.nack <= '0'; + BUS_TX.data <= (others => '0'); + i2c_reg_2(7) <= '0'; + + if BUS_RX.write = '1' then + BUS_TX.ack <= '1'; + + if BUS_RX.addr(3 downto 0) = x"0" then + i2c_reg_0 <= BUS_RX.data; + + elsif BUS_RX.addr(3 downto 0) = x"1" then + i2c_reg_1 <= BUS_RX.data; + + elsif BUS_RX.addr(3 downto 0) = x"2" then + i2c_reg_2 <= BUS_RX.data; + + -- elsif BUS_RX.addr(3 downto 0) = x"3" then + -- i2c_go_100 <= BUS_RX.data(0); + + -- elsif BUS_RX.addr(3 downto 0) = x"5" then + -- i2c_reg_5 <= BUS_RX.data; + + else + BUS_TX.ack <= '0'; + BUS_TX.unknown <= '1'; + end if; + + elsif BUS_RX.read = '1' then + BUS_TX.ack <= '1'; + + if BUS_RX.addr(3 downto 0) = x"0" then + BUS_TX.data <= i2c_reg_0; + + elsif BUS_RX.addr(3 downto 0) = x"1" then + BUS_TX.data <= i2c_reg_1; + + elsif BUS_RX.addr(3 downto 0) = x"2" then + BUS_TX.data <= i2c_reg_2; + + elsif BUS_RX.addr(3 downto 0) = x"3" then + BUS_TX.data <= (others => '0'); + + elsif BUS_RX.addr(3 downto 0) = x"4" then + BUS_TX.data <= i2c_reg_4; + + -- elsif BUS_RX.addr(3 downto 0) = x"5" then + -- BUS_TX.data <= i2c_reg_5; + + else + BUS_TX.ack <= '0'; + BUS_TX.unknown <= '1'; + end if; + end if; + end process; + +end Behavioral; diff --git a/code/trb3sc_tools.vhd b/code/trb3sc_tools.vhd index 8a97338..f5b3e4a 100644 --- a/code/trb3sc_tools.vhd +++ b/code/trb3sc_tools.vhd @@ -71,9 +71,9 @@ end entity; architecture trb3sc_tools_arch of trb3sc_tools is -signal bus_debug_rx_out, bus_flash_rx_out, busflash_rx, busspi_rx, busadc_rx, bussed_rx, +signal bus_debug_rx_out, bus_flash_rx_out, busflash_rx, busspi_rx, busadc_rx, bussed_rx, busi2c_rx, busuart_rx, busflashset_rx, busmon_rx, bustrig_rx, busctrl_rx : CTRLBUS_RX; -signal bus_debug_tx_in, bus_flash_tx_in, busflash_tx, busspi_tx, busadc_tx, bussed_tx, +signal bus_debug_tx_in, bus_flash_tx_in, busflash_tx, busspi_tx, busadc_tx, bussed_tx, busi2c_tx, busuart_tx, busflashset_tx, busmon_tx, bustrig_tx, busctrl_tx : CTRLBUS_TX; signal spi_sdi, spi_sdo, spi_sck : std_logic_vector(15 downto 0); @@ -97,11 +97,11 @@ begin --------------------------------------------------------------------------- THE_BUS_HANDLER : entity work.trb_net16_regio_bus_handler_record generic map( - PORT_NUMBER => 9, + PORT_NUMBER => 10, PORT_ADDRESSES => (0 => x"0000", 1 => x"0400", 2 => x"0480", 3 => x"0500", 4 => x"0600", - 5 => x"0180", 6 => x"0f00", 7 => x"0f80", 8 => x"0580", others => x"0000"), + 5 => x"0180", 6 => x"0f00", 7 => x"0f80", 8 => x"0580", 9 => x"0680", others => x"0000"), PORT_ADDR_MASK => (0 => 9, 1 => 5, 2 => 5, 3 => 2, 4 => 2, - 5 => 4, 6 => 7, 7 => 7, 8 => 1, others => 0), + 5 => 4, 6 => 7, 7 => 7, 8 => 1, 9 => 4, others => 0), PORT_MASK_ENABLE => 1 ) port map( @@ -120,6 +120,7 @@ begin BUS_RX(6) => bustrig_rx, BUS_RX(7) => busmon_rx, BUS_RX(8) => busctrl_rx, + BUS_RX(9) => busi2c_rx, BUS_TX(0) => busflash_tx, BUS_TX(1) => busspi_tx, BUS_TX(2) => busadc_tx, @@ -129,6 +130,7 @@ begin BUS_TX(6) => bustrig_tx, BUS_TX(7) => busmon_tx, BUS_TX(8) => busctrl_tx, + BUS_TX(9) => busi2c_tx, STAT_DEBUG => open ); @@ -325,6 +327,33 @@ end generate; busuart_tx.data <= (others => '0'); end generate; +--------------------------------------------------------------------------- +-- I2C +--------------------------------------------------------------------------- + gen_i2c : if INCLUDE_I2C = 1 generate + --signal common_i2c_sda : std_logic; + --signal common_i2c_scl : std_logic; + begin + THE_I2C : common_i2c + port map( + CLOCK => CLK, + RESET => RESET, + SDA => HEADER_IO(7), + SCL => HEADER_IO(8), + BUS_RX => busi2c_rx, + BUS_TX => busi2c_tx + ); + + --<= common_i2c_sda; + --HEADER_IO(8) <= common_i2c_scl; + end generate; + gen_noi2c : if INCLUDE_I2C = 0 generate + busi2c_tx.unknown <= '1'; + busi2c_tx.nack <= '0'; + busi2c_tx.ack <= '0'; + busi2c_tx.data <= (others => '0'); + end generate; + --------------------------------------------------------------------------- -- Debug Connection --------------------------------------------------------------------------- @@ -452,8 +481,8 @@ end process; -- 4 SPI MISO -- 5 SPI CLK -- 6 SPI CS --- 7 lcd_dc --- 8 lcd_rst +-- 7 I2C_SDA +-- 8 I2C_SCL -- 9 Debug RX -- 10 Debug TX -- 11 3.3V -- 2.43.0