fix(i2c): Fix that fsm reset cause i2c scl frequency changed on esp32s2

This commit is contained in:
C.S.M
2025-04-29 16:58:36 +08:00
parent 1adcce2520
commit 11216d293a
12 changed files with 301 additions and 185 deletions

View File

@ -125,6 +125,10 @@ static esp_err_t s_i2c_hw_fsm_reset(i2c_master_bus_handle_t i2c_master, bool cle
} }
i2c_hal_master_init(hal); i2c_hal_master_init(hal);
// Restore the clock source here.
I2C_CLOCK_SRC_ATOMIC() {
i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src);
}
i2c_ll_disable_intr_mask(hal->dev, I2C_LL_INTR_MASK); i2c_ll_disable_intr_mask(hal->dev, I2C_LL_INTR_MASK);
i2c_ll_clear_intr_mask(hal->dev, I2C_LL_INTR_MASK); i2c_ll_clear_intr_mask(hal->dev, I2C_LL_INTR_MASK);
i2c_hal_set_timing_config(hal, &timing_config); i2c_hal_set_timing_config(hal, &timing_config);

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -65,11 +65,6 @@ typedef struct i2c_bus_t *i2c_bus_handle_t;
typedef struct i2c_master_dev_t i2c_master_dev_t; typedef struct i2c_master_dev_t i2c_master_dev_t;
typedef struct i2c_slave_dev_t i2c_slave_dev_t; typedef struct i2c_slave_dev_t i2c_slave_dev_t;
typedef enum {
I2C_BUS_MODE_MASTER = 0,
I2C_BUS_MODE_SLAVE = 1,
} i2c_bus_mode_t;
typedef enum { typedef enum {
I2C_SLAVE_FIFO = 0, I2C_SLAVE_FIFO = 0,
I2C_SLAVE_NONFIFO = 1, I2C_SLAVE_NONFIFO = 1,

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -652,6 +652,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
return false; return false;
} }
/**
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
* ack_level: 1 (NACK)
* ack_level: 0 (ACK)
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
{
// Not supported on esp32
}
/** /**
* @brief Set I2C source clock * @brief Set I2C source clock
* *
@ -678,37 +692,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
} }
/** /**
* @brief Init I2C master * @brief Set the I2C bus mode (Master or Slave)
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param mode The desired I2C bus mode (Master or Slave).
* @return None
*/ */
static inline void i2c_ll_master_init(i2c_dev_t *hw) static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
ctrl_reg.val = 0;
ctrl_reg.ms_mode = 1;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
} }
/** /**
* @brief Init I2C slave * @brief Enable or disable open-drain mode for I2C pins
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param enable_od Boolean flag to enable or disable open-drain mode:
* @return None
*/ */
static inline void i2c_ll_slave_init(i2c_dev_t *hw) static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.sda_force_out = enable_od;
ctrl_reg.val = 0; hw->ctr.scl_force_out = enable_od;
ctrl_reg.sda_force_out = 1; }
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val; /**
hw->fifo_conf.fifo_addr_cfg_en = 0; * @brief Enable or disable arbitration for I2C communication.
*
* @param hw Pointer to the I2C hardware instance.
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
*/
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
{
;// ESP32 do not support
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -692,6 +692,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
return hw->scl_sp_conf.scl_rst_slv_en; return hw->scl_sp_conf.scl_rst_slv_en;
} }
/**
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
* ack_level: 1 (NACK)
* ack_level: 0 (ACK)
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
{
hw->ctr.rx_full_ack_level = ack_level;
}
/** /**
* @brief Set I2C source clock * @brief Set I2C source clock
* *
@ -718,21 +732,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
} }
/** /**
* @brief Init I2C master * @brief Set the I2C bus mode (Master or Slave)
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param mode The desired I2C bus mode (Master or Slave).
* @return None
*/ */
static inline void i2c_ll_master_init(i2c_dev_t *hw) static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
ctrl_reg.val = 0; }
ctrl_reg.ms_mode = 1;
ctrl_reg.clk_en = 1; /**
ctrl_reg.sda_force_out = 1; * @brief Enable or disable open-drain mode for I2C pins
ctrl_reg.scl_force_out = 1; *
hw->ctr.val = ctrl_reg.val; * @param hw Pointer to the I2C hardware register structure.
* @param enable_od Boolean flag to enable or disable open-drain mode:
*/
static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
{
hw->ctr.sda_force_out = enable_od;
hw->ctr.scl_force_out = enable_od;
}
/**
* @brief Enable or disable arbitration for I2C communication.
*
* @param hw Pointer to the I2C hardware instance.
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
*/
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
{
hw->ctr.arbitration_en = enable_arbi;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -815,6 +815,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
return hw->scl_sp_conf.scl_rst_slv_en; return hw->scl_sp_conf.scl_rst_slv_en;
} }
/**
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
* ack_level: 1 (NACK)
* ack_level: 0 (ACK)
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
{
hw->ctr.rx_full_ack_level = ack_level;
}
/** /**
* @brief Set I2C source clock * @brief Set I2C source clock
* *
@ -841,38 +855,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
} }
/** /**
* @brief Init I2C master * @brief Set the I2C bus mode (Master or Slave)
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param mode The desired I2C bus mode (Master or Slave).
* @return None
*/ */
static inline void i2c_ll_master_init(i2c_dev_t *hw) static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
ctrl_reg.val = 0;
ctrl_reg.ms_mode = 1;
ctrl_reg.clk_en = 1;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
} }
/** /**
* @brief Init I2C slave * @brief Enable or disable open-drain mode for I2C pins
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param enable_od Boolean flag to enable or disable open-drain mode:
* @return None
*/ */
static inline void i2c_ll_slave_init(i2c_dev_t *hw) static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.sda_force_out = enable_od;
ctrl_reg.val = 0; hw->ctr.scl_force_out = enable_od;
ctrl_reg.sda_force_out = 1; }
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val; /**
hw->fifo_conf.fifo_addr_cfg_en = 0; * @brief Enable or disable arbitration for I2C communication.
*
* @param hw Pointer to the I2C hardware instance.
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
*/
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
{
hw->ctr.arbitration_en = enable_arbi;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -874,37 +874,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
} }
/** /**
* @brief Init I2C master * @brief Set the I2C bus mode (Master or Slave)
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param mode The desired I2C bus mode (Master or Slave).
* @return None
*/ */
static inline void i2c_ll_master_init(i2c_dev_t *hw) static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
ctrl_reg.val = 0;
ctrl_reg.ms_mode = 1;
ctrl_reg.sda_force_out = 0;
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val;
} }
/** /**
* @brief Init I2C slave * @brief Enable or disable open-drain mode for I2C pins
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param enable_od Boolean flag to enable or disable open-drain mode:
* @return None
*/ */
static inline void i2c_ll_slave_init(i2c_dev_t *hw) static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.sda_force_out = !enable_od;
ctrl_reg.val = 0; hw->ctr.scl_force_out = !enable_od;
ctrl_reg.sda_force_out = 0; }
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val; /**
hw->fifo_conf.fifo_addr_cfg_en = 0; * @brief Enable or disable arbitration for I2C communication.
*
* @param hw Pointer to the I2C hardware instance.
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
*/
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
{
hw->ctr.arbitration_en = enable_arbi;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -762,6 +762,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
return hw->scl_sp_conf.scl_rst_slv_en; return hw->scl_sp_conf.scl_rst_slv_en;
} }
/**
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
* ack_level: 1 (NACK)
* ack_level: 0 (ACK)
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
{
hw->ctr.rx_full_ack_level = ack_level;
}
/** /**
* @brief Set I2C source clock * @brief Set I2C source clock
* *
@ -789,37 +803,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
} }
/** /**
* @brief Init I2C master * @brief Set the I2C bus mode (Master or Slave)
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param mode The desired I2C bus mode (Master or Slave).
* @return None
*/ */
static inline void i2c_ll_master_init(i2c_dev_t *hw) static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
ctrl_reg.val = 0;
ctrl_reg.ms_mode = 1;
ctrl_reg.sda_force_out = 0;
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val;
} }
/** /**
* @brief Init I2C slave * @brief Enable or disable open-drain mode for I2C pins
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param enable_od Boolean flag to enable or disable open-drain mode:
* @return None
*/ */
static inline void i2c_ll_slave_init(i2c_dev_t *hw) static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.sda_force_out = !enable_od;
ctrl_reg.val = 0; hw->ctr.scl_force_out = !enable_od;
ctrl_reg.sda_force_out = 0; }
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val; /**
hw->fifo_conf.fifo_addr_cfg_en = 0; * @brief Enable or disable arbitration for I2C communication.
*
* @param hw Pointer to the I2C hardware instance.
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
*/
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
{
hw->ctr.arbitration_en = enable_arbi;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -829,37 +829,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
} }
/** /**
* @brief Init I2C master * @brief Set the I2C bus mode (Master or Slave)
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param mode The desired I2C bus mode (Master or Slave).
* @return None
*/ */
static inline void i2c_ll_master_init(i2c_dev_t *hw) static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
ctrl_reg.val = 0;
ctrl_reg.ms_mode = 1;
ctrl_reg.sda_force_out = 0;
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val;
} }
/** /**
* @brief Init I2C slave * @brief Enable or disable open-drain mode for I2C pins
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param enable_od Boolean flag to enable or disable open-drain mode:
* @return None
*/ */
static inline void i2c_ll_slave_init(i2c_dev_t *hw) static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.sda_force_out = !enable_od;
ctrl_reg.val = 0; hw->ctr.scl_force_out = !enable_od;
ctrl_reg.sda_force_out = 0; }
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val; /**
hw->fifo_conf.fifo_addr_cfg_en = 0; * @brief Enable or disable arbitration for I2C communication.
*
* @param hw Pointer to the I2C hardware instance.
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
*/
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
{
hw->ctr.arbitration_en = enable_arbi;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -681,6 +681,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
return false; // not supported on esp32s2 return false; // not supported on esp32s2
} }
/**
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
* ack_level: 1 (NACK)
* ack_level: 0 (ACK)
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
{
hw->ctr.rx_full_ack_level = ack_level;
}
/** /**
* @brief Set I2C source clock * @brief Set I2C source clock
* *
@ -708,36 +722,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
} }
/** /**
* @brief Init I2C master * @brief Set the I2C bus mode (Master or Slave)
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param mode The desired I2C bus mode (Master or Slave).
* @return None
*/ */
static inline void i2c_ll_master_init(i2c_dev_t *hw) static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
ctrl_reg.val = 0;
ctrl_reg.ms_mode = 1;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
} }
/** /**
* @brief Enable I2C internal open-drain mode * @brief Enable or disable open-drain mode for I2C pins
* If internal open-drain of the I2C module is disabled, scl and sda gpio should be configured in open-drain mode.
* Otherwise it is not needed.
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* @param internal_od_ena Set true to enable internal open-drain, otherwise, set it false. * @param enable_od Boolean flag to enable or disable open-drain mode:
*
* @return None
*/ */
static inline void i2c_ll_internal_od_enable(i2c_dev_t *hw, bool internal_od_ena) static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
{ {
hw->ctr.sda_force_out = (internal_od_ena == false); hw->ctr.sda_force_out = enable_od;
hw->ctr.scl_force_out = (internal_od_ena == false); hw->ctr.scl_force_out = enable_od;
}
/**
* @brief Enable or disable arbitration for I2C communication.
*
* @param hw Pointer to the I2C hardware instance.
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
*/
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
{
hw->ctr.arbitration_en = enable_arbi;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -820,6 +820,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
return false; // not supported on esp32s3 return false; // not supported on esp32s3
} }
/**
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
* ack_level: 1 (NACK)
* ack_level: 0 (ACK)
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
{
hw->ctr.rx_full_ack_level = ack_level;
}
/** /**
* @brief Set I2C source clock * @brief Set I2C source clock
* *
@ -845,38 +859,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
} }
/** /**
* @brief Init I2C master * @brief Set the I2C bus mode (Master or Slave)
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param mode The desired I2C bus mode (Master or Slave).
* @return None
*/ */
static inline void i2c_ll_master_init(i2c_dev_t *hw) static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
ctrl_reg.val = 0;
ctrl_reg.ms_mode = 1;
ctrl_reg.clk_en = 1;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
} }
/** /**
* @brief Init I2C slave * @brief Enable or disable open-drain mode for I2C pins
* *
* @param hw Beginning address of the peripheral registers * @param hw Pointer to the I2C hardware register structure.
* * @param enable_od Boolean flag to enable or disable open-drain mode:
* @return None
*/ */
static inline void i2c_ll_slave_init(i2c_dev_t *hw) static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
{ {
typeof(hw->ctr) ctrl_reg; hw->ctr.sda_force_out = enable_od;
ctrl_reg.val = 0; hw->ctr.scl_force_out = enable_od;
ctrl_reg.sda_force_out = 1; }
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val; /**
hw->fifo_conf.fifo_addr_cfg_en = 0; * @brief Enable or disable arbitration for I2C communication.
*
* @param hw Pointer to the I2C hardware instance.
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
*/
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
{
hw->ctr.arbitration_en = enable_arbi;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -13,7 +13,9 @@
void i2c_hal_slave_init(i2c_hal_context_t *hal) void i2c_hal_slave_init(i2c_hal_context_t *hal)
{ {
i2c_ll_slave_init(hal->dev); i2c_ll_set_mode(hal->dev, I2C_BUS_MODE_SLAVE);
i2c_ll_enable_pins_open_drain(hal->dev, true);
i2c_ll_enable_arbitration(hal->dev, false);
//MSB //MSB
i2c_ll_set_data_mode(hal->dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST); i2c_ll_set_data_mode(hal->dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST);
//Reset fifo //Reset fifo
@ -36,7 +38,10 @@ void i2c_hal_master_fsm_rst(i2c_hal_context_t *hal)
void i2c_hal_master_init(i2c_hal_context_t *hal) void i2c_hal_master_init(i2c_hal_context_t *hal)
{ {
i2c_ll_master_init(hal->dev); i2c_ll_set_mode(hal->dev, I2C_BUS_MODE_MASTER);
i2c_ll_enable_pins_open_drain(hal->dev, true);
i2c_ll_enable_arbitration(hal->dev, false);
i2c_ll_master_rx_full_ack_level(hal->dev, false);
//MSB //MSB
i2c_ll_set_data_mode(hal->dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST); i2c_ll_set_data_mode(hal->dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST);
//Reset fifo //Reset fifo

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -98,6 +98,19 @@ typedef enum {
I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK = 3, /*!< Stretching SCL low when slave sending ACK */ I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK = 3, /*!< Stretching SCL low when slave sending ACK */
} i2c_slave_stretch_cause_t; } i2c_slave_stretch_cause_t;
typedef enum {
I2C_SLAVE_WRITE_BY_MASTER = 0,
I2C_SLAVE_READ_BY_MASTER = 1,
} i2c_slave_read_write_status_t;
/**
* @brief Enum for i2c working modes.
*/
typedef enum {
I2C_BUS_MODE_MASTER = 0, /*!< I2C works under master mode */
I2C_BUS_MODE_SLAVE = 1, /*!< I2C works under slave mode */
} i2c_bus_mode_t;
#if SOC_I2C_SUPPORTED #if SOC_I2C_SUPPORTED
/** /**
* @brief I2C group clock source * @brief I2C group clock source