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);
// 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_disable_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
*/
@@ -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_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 {
I2C_SLAVE_FIFO = 0,
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
*/
@@ -654,6 +654,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
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
*
@@ -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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Init I2C slave
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
*
* @return None
* @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_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;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
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)
{
;// 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
*/
@@ -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;
}
/**
* @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
*
@@ -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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Enable or disable open-drain mode for I2C pins
*
* @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
*/
@@ -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;
}
/**
* @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
*
@@ -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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Init I2C slave
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
*
* @return None
* @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_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;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
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: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* 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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Init I2C slave
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
*
* @return None
* @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_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;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 0;
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val;
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: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* 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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Init I2C slave
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
*
* @return None
* @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_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;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 0;
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val;
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: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* 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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Init I2C slave
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
*
* @return None
* @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_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;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 0;
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val;
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: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* 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;
}
/**
* @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
*
@@ -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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Init I2C slave
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
*
* @return None
* @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_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;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 0;
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val;
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: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* 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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Init I2C slave
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
*
* @return None
* @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_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;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 0;
ctrl_reg.scl_force_out = 0;
hw->ctr.val = ctrl_reg.val;
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: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* 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
}
/**
* @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
*
@@ -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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Enable I2C internal open-drain mode
* 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.
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
* @param internal_od_ena Set true to enable internal open-drain, otherwise, set it false.
*
* @return None
* @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_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.scl_force_out = (internal_od_ena == false);
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
*/
@@ -826,6 +826,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
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
*
@@ -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
*
* @return None
* @param hw Pointer to the I2C hardware register structure.
* @param mode The desired I2C bus mode (Master or Slave).
*/
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;
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;
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
}
/**
* @brief Init I2C slave
* @brief Enable or disable open-drain mode for I2C pins
*
* @param hw Beginning address of the peripheral registers
*
* @return None
* @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_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;
ctrl_reg.val = 0;
ctrl_reg.sda_force_out = 1;
ctrl_reg.scl_force_out = 1;
hw->ctr.val = ctrl_reg.val;
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: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,7 +13,9 @@
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
i2c_ll_set_data_mode(hal->dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST);
//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)
{
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
i2c_ll_set_data_mode(hal->dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST);
//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
*/
@@ -103,6 +103,14 @@ typedef enum {
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
/**
* @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

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

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);
}
// 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)
i2c_ll_set_data_mode(dev, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST);
//Reset fifo