From 76ca4853320b5f85b0c05fcd4a22389f79fd5d96 Mon Sep 17 00:00:00 2001 From: Aaron Hartwig Date: Tue, 28 Jan 2025 15:50:38 -0800 Subject: [PATCH] I2C: fix SCL rate, data endianness, and repeated start (#268) --- hdl/ip/vhd/i2c/common/sims/i2c_target_vc.vhd | 8 ++-- .../link_layer/i2c_ctrl_link_layer.vhd | 46 +++++++++---------- .../txn_layer/i2c_ctrl_txn_layer.vhd | 3 +- .../txn_layer/sims/i2c_ctrl_txn_layer_th.vhd | 4 +- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/hdl/ip/vhd/i2c/common/sims/i2c_target_vc.vhd b/hdl/ip/vhd/i2c/common/sims/i2c_target_vc.vhd index 16d3387b..43ab688b 100644 --- a/hdl/ip/vhd/i2c/common/sims/i2c_target_vc.vhd +++ b/hdl/ip/vhd/i2c/common/sims/i2c_target_vc.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this -- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- --- Copyright 2024 Oxide Computer Company +-- Copyright 2025 Oxide Computer Company library ieee; use ieee.std_logic_1164.all; @@ -182,7 +182,7 @@ begin rx_ackd <= TRUE when sda_if.i = '0' else FALSE; rx_bit_count <= to_unsigned(1, rx_bit_count'length); elsif state = GET_START_BYTE or state = GET_BYTE then - rx_data <= sda_if.i & rx_data(7 downto 1); + rx_data <= rx_data(rx_data'high-1 downto rx_data'low) & sda_if.i; rx_bit_count <= rx_bit_count + 1; end if; @@ -214,9 +214,9 @@ begin if tx_bit_count = 0 then txd := read_word(i2c_target_vc.p_buffer.p_memory_ref, natural(to_integer(reg_addr)), 1); else - txd := '1' & tx_data(7 downto 1); + txd := tx_data(tx_data'high-1 downto tx_data'low) & '1'; end if; - sda_oe <= not txd(0); + sda_oe <= not txd(7); tx_bit_count <= tx_bit_count + 1; else -- release the bus diff --git a/hdl/ip/vhd/i2c/controller/link_layer/i2c_ctrl_link_layer.vhd b/hdl/ip/vhd/i2c/controller/link_layer/i2c_ctrl_link_layer.vhd index 3a84dedc..2262bdbd 100644 --- a/hdl/ip/vhd/i2c/controller/link_layer/i2c_ctrl_link_layer.vhd +++ b/hdl/ip/vhd/i2c/controller/link_layer/i2c_ctrl_link_layer.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this -- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- --- Copyright 2024 Oxide Computer Company +-- Copyright 2025 Oxide Computer Company library ieee; use ieee.std_logic_1164.all; @@ -51,7 +51,7 @@ architecture rtl of i2c_ctrl_link_layer is -- fetch the settings for the desired I2C mode constant SETTINGS : settings_t := get_i2c_settings(MODE); constant SCL_HALF_PER_TICKS : positive := - to_integer(calc_ns(SETTINGS.fscl_period_ns, CLK_PER_NS, 10)); + to_integer(calc_ns(SETTINGS.fscl_period_ns / 2, CLK_PER_NS, 10)); -- The state machine's counter to enforce timing around various events constant SM_COUNTER_SIZE_BITS : positive := 8; @@ -90,17 +90,17 @@ architecture rtl of i2c_ctrl_link_layer is bits_shifted : natural range 0 to 8; -- control - ready : std_logic; - scl_start : std_logic; - scl_active : std_logic; - sda_hold : std_logic; - counter : std_logic_vector(SM_COUNTER_SIZE_BITS - 1 downto 0); - count_load : std_logic; - count_decr : std_logic; - count_clr : std_logic; - transition_sda_cntr_en : std_logic; - ack_sending : std_logic; - scl_fedge_seen : std_logic; + ready : std_logic; + scl_start : std_logic; + scl_active : std_logic; + sda_hold : std_logic; + counter : std_logic_vector(SM_COUNTER_SIZE_BITS - 1 downto 0); + count_load : std_logic; + count_decr : std_logic; + count_clr : std_logic; + transition_sda_cntr_en : std_logic; + ack_sending : std_logic; + sr_scl_fedge_seen : std_logic; -- interfaces rx_data : std_logic_vector(7 downto 0); @@ -124,7 +124,7 @@ architecture rtl of i2c_ctrl_link_layer is '0', -- count_clr '0', -- transition_sda_cntr_en '0', -- ack_sending - '0', -- scl_fedge_seen + '0', -- sr_scl_fedge_seen (others => '0'),-- rx_data '0', -- rx_data_valid (others => '0'),-- tx_data @@ -280,11 +280,12 @@ begin end if; when WAIT_REPEAT_START => - if not sm_reg.scl_fedge_seen then - v.scl_fedge_seen := scl_fedge; + if not sm_reg.sr_scl_fedge_seen then + v.sr_scl_fedge_seen := scl_fedge; elsif scl_redge then - v.state := START_SETUP; - v.scl_active := '0'; + v.state := START_SETUP; + v.scl_active := '0'; + v.sr_scl_fedge_seen := '0'; end if; -- In the event of a repeated START account for setup requirements @@ -335,8 +336,8 @@ begin v.state := ACK_RX; v.bits_shifted := 0; else - v.sda_oe := not sm_reg.tx_data(0); - v.tx_data := '1' & sm_reg.tx_data(7 downto 1); + v.sda_oe := not sm_reg.tx_data(7); + v.tx_data := sm_reg.tx_data(sm_reg.tx_data'high-1 downto sm_reg.tx_data'low) & '1'; v.bits_shifted := sm_reg.bits_shifted + 1; end if; end if; @@ -360,7 +361,7 @@ begin v.rx_data_valid := '1'; v.bits_shifted := 0; elsif scl_redge then - v.rx_data := sda_in_syncd & sm_reg.rx_data(7 downto 1); + v.rx_data := sm_reg.rx_data(sm_reg.rx_data'high-1 downto sm_reg.rx_data'low) & sda_in_syncd; v.bits_shifted := sm_reg.bits_shifted + 1; end if; @@ -404,8 +405,7 @@ begin end case; -- next state logic - v.ready := '1' when v.state = IDLE or v.state = HANDLE_NEXT or v.state = HANDLE_NEXT - else '0'; + v.ready := '1' when v.state = IDLE or v.state = HANDLE_NEXT else '0'; sm_reg_next <= v; end process; diff --git a/hdl/ip/vhd/i2c/controller/txn_layer/i2c_ctrl_txn_layer.vhd b/hdl/ip/vhd/i2c/controller/txn_layer/i2c_ctrl_txn_layer.vhd index 7306ccf6..a903d1c3 100644 --- a/hdl/ip/vhd/i2c/controller/txn_layer/i2c_ctrl_txn_layer.vhd +++ b/hdl/ip/vhd/i2c/controller/txn_layer/i2c_ctrl_txn_layer.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this -- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- --- Copyright 2024 Oxide Computer Company +-- Copyright 2025 Oxide Computer Company library ieee; use ieee.std_logic_1164.all; @@ -11,7 +11,6 @@ use ieee.numeric_std_unsigned.all; use work.stream8_pkg; use work.tristate_if_pkg.all; -use work.i2c_common_pkg.all; use work.i2c_common_pkg.all; entity i2c_txn_layer is diff --git a/hdl/ip/vhd/i2c/controller/txn_layer/sims/i2c_ctrl_txn_layer_th.vhd b/hdl/ip/vhd/i2c/controller/txn_layer/sims/i2c_ctrl_txn_layer_th.vhd index c770cdf3..e2760c75 100644 --- a/hdl/ip/vhd/i2c/controller/txn_layer/sims/i2c_ctrl_txn_layer_th.vhd +++ b/hdl/ip/vhd/i2c/controller/txn_layer/sims/i2c_ctrl_txn_layer_th.vhd @@ -2,7 +2,7 @@ -- License, v. 2.0. If a copy of the MPL was not distributed with this -- file, You can obtain one at https://mozilla.org/MPL/2.0/. -- --- Copyright 2024 Oxide Computer Company +-- Copyright 2025 Oxide Computer Company library ieee; use ieee.std_logic_1164.all; @@ -64,7 +64,7 @@ begin dut: entity work.i2c_txn_layer generic map ( CLK_PER_NS => 8, - MODE => STANDARD + MODE => FAST_PLUS ) port map ( clk => clk,