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 30f60557ec
commit 94cbc9bbac
18 changed files with 351 additions and 230 deletions

View File

@@ -132,6 +132,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_enable_fifo_mode(hal->dev, true); i2c_ll_enable_fifo_mode(hal->dev, true);
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);

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
*/ */
@@ -74,11 +74,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,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |

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
*/ */
@@ -654,6 +654,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
* *
@@ -680,36 +694,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; /**
* @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
*/ */
@@ -695,6 +695,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
* *
@@ -721,21 +735,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
*/ */
@@ -821,6 +821,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
* *
@@ -847,37 +861,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; /**
* @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: 2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -886,36 +886,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; /**
* @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
*/ */
@@ -888,36 +888,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; /**
* @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: 2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -812,36 +812,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; /**
* @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
*/ */
@@ -768,6 +768,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
* *
@@ -795,36 +809,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; /**
* @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
*/ */
@@ -919,36 +919,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; /**
* @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
*/ */
@@ -702,6 +702,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
* *
@@ -729,36 +743,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
*/ */
@@ -826,6 +826,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
* *
@@ -851,37 +865,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; /**
* @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
*/ */
@@ -103,6 +103,14 @@ typedef enum {
I2C_SLAVE_READ_BY_MASTER = 1, I2C_SLAVE_READ_BY_MASTER = 1,
} i2c_slave_read_write_status_t; } 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

View File

@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
## Crypto peripherals test ## Crypto peripherals test

View File

@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
# HAL I2C test # HAL I2C test

View File

@@ -117,7 +117,9 @@ esp_err_t hal_i2c_init(hal_i2c_config *cfg)
esp_rom_gpio_connect_in_signal(scl_io, i2c_periph_signal[cfg->i2c_port].scl_out_sig, 0); esp_rom_gpio_connect_in_signal(scl_io, i2c_periph_signal[cfg->i2c_port].scl_out_sig, 0);
} }
// Initialize I2C master bus. Including enable its clock, choose its mode, etc. // Initialize I2C master bus. Including enable its clock, choose its mode, etc.
i2c_ll_master_init(dev); i2c_ll_set_mode(dev, I2C_BUS_MODE_MASTER);
i2c_ll_enable_pins_open_drain(dev, true);
i2c_ll_enable_arbitration(dev, false);
//MSB (I2C standard require the data to be sent with most MSB) //MSB (I2C standard require the data to be sent with most MSB)
i2c_ll_set_data_mode(dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST); i2c_ll_set_data_mode(dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST);
//Reset fifo //Reset fifo