mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-29 18:27:20 +02:00
Merge branch 'contrib/github_pr_15638_v5.4' into 'release/v5.4'
fix(i2c): Fix clear bus issue in legacy i2c driver, etc. (backport v5.4) See merge request espressif/esp-idf!38828
This commit is contained in:
@ -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
|
||||
*/
|
||||
@ -68,6 +68,7 @@ static const char *I2C_TAG = "i2c";
|
||||
#define I2C_CMD_USER_ALLOC_ERR_STR "i2c command link allocation error: the buffer provided is too small."
|
||||
#define I2C_TRANS_MODE_ERR_STR "i2c trans mode error"
|
||||
#define I2C_MODE_ERR_STR "i2c mode error"
|
||||
#define I2C_CLEAR_BUS_ERR_STR "clear bus error"
|
||||
#define I2C_SDA_IO_ERR_STR "sda gpio number error"
|
||||
#define I2C_SCL_IO_ERR_STR "scl gpio number error"
|
||||
#define I2C_SCL_SDA_EQUAL_ERR_STR "scl and sda gpio numbers are the same"
|
||||
@ -126,6 +127,8 @@ static const char *I2C_TAG = "i2c";
|
||||
#define I2C_RCC_ATOMIC()
|
||||
#endif
|
||||
|
||||
#define I2C_CLR_BUS_TIMEOUT_MS (50) // 50ms is sufficient for clearing the bus
|
||||
|
||||
/**
|
||||
* I2C bus are defined in the header files, let's check that the values are correct
|
||||
*/
|
||||
@ -657,6 +660,7 @@ esp_err_t i2c_get_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t *tx_trans_mode,
|
||||
**/
|
||||
static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
#if !SOC_I2C_SUPPORT_HW_CLR_BUS
|
||||
const int scl_half_period = I2C_CLR_BUS_HALF_PERIOD_US; // use standard 100kHz data rate
|
||||
int i = 0;
|
||||
@ -685,11 +689,22 @@ static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num)
|
||||
i2c_set_pin(i2c_num, sda_io, scl_io, 1, 1, I2C_MODE_MASTER);
|
||||
#else
|
||||
i2c_ll_master_clr_bus(i2c_context[i2c_num].hal.dev, I2C_CLR_BUS_SCL_NUM, true);
|
||||
// If the i2c master clear bus state machine got disturbed when working, it would go into error state.
|
||||
// The solution here is to use freertos tick counter to set a timeout threshold. If it doesn't return on time,
|
||||
// return invalid state and turn off the state machine as its always wrong.
|
||||
TickType_t start_tick = xTaskGetTickCount();
|
||||
const TickType_t timeout_ticks = pdMS_TO_TICKS(I2C_CLR_BUS_TIMEOUT_MS);
|
||||
while (i2c_ll_master_is_bus_clear_done(i2c_context[i2c_num].hal.dev)) {
|
||||
if ((xTaskGetTickCount() - start_tick) > timeout_ticks) {
|
||||
ESP_LOGE(I2C_TAG, I2C_CLEAR_BUS_ERR_STR);
|
||||
i2c_ll_master_clr_bus(i2c_context[i2c_num].hal.dev, 0, false);
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**if the power and SDA/SCL wires are in proper condition, everything works find with reading the slave.
|
||||
|
@ -112,7 +112,7 @@ static esp_err_t s_i2c_master_clear_bus(i2c_bus_handle_t handle)
|
||||
*
|
||||
* @param[in] i2c_master I2C master handle
|
||||
*/
|
||||
static esp_err_t s_i2c_hw_fsm_reset(i2c_master_bus_handle_t i2c_master)
|
||||
static esp_err_t s_i2c_hw_fsm_reset(i2c_master_bus_handle_t i2c_master, bool clear_bus)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
i2c_hal_context_t *hal = &i2c_master->base->hal;
|
||||
@ -124,12 +124,18 @@ static esp_err_t s_i2c_hw_fsm_reset(i2c_master_bus_handle_t i2c_master)
|
||||
i2c_ll_master_get_filter(hal->dev, &filter_cfg);
|
||||
|
||||
//to reset the I2C hw module, we need re-enable the hw
|
||||
ret = s_i2c_master_clear_bus(i2c_master->base);
|
||||
if (clear_bus) {
|
||||
ret = s_i2c_master_clear_bus(i2c_master->base);
|
||||
}
|
||||
I2C_RCC_ATOMIC() {
|
||||
i2c_ll_reset_register(i2c_master->base->port_num);
|
||||
}
|
||||
|
||||
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);
|
||||
@ -137,7 +143,9 @@ static esp_err_t s_i2c_hw_fsm_reset(i2c_master_bus_handle_t i2c_master)
|
||||
i2c_ll_master_set_filter(hal->dev, filter_cfg);
|
||||
#else
|
||||
i2c_ll_master_fsm_rst(hal->dev);
|
||||
ret = s_i2c_master_clear_bus(i2c_master->base);
|
||||
if (clear_bus) {
|
||||
ret = s_i2c_master_clear_bus(i2c_master->base);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@ -378,6 +386,8 @@ static void s_i2c_start_end_command(i2c_master_bus_handle_t i2c_master, i2c_oper
|
||||
}
|
||||
uint8_t addr_write[addr_byte];
|
||||
uint8_t addr_read[addr_byte];
|
||||
memset(addr_write, 0, sizeof(addr_write));
|
||||
memset(addr_read, 0, sizeof(addr_read));
|
||||
|
||||
if (addr_byte != 0) {
|
||||
addr_write[0] = I2C_ADDRESS_TRANS_WRITE(cmd_address);
|
||||
@ -488,7 +498,7 @@ static void s_i2c_send_commands(i2c_master_bus_handle_t i2c_master, TickType_t t
|
||||
}
|
||||
|
||||
if (atomic_load(&i2c_master->status) == I2C_STATUS_TIMEOUT) {
|
||||
s_i2c_hw_fsm_reset(i2c_master);
|
||||
s_i2c_hw_fsm_reset(i2c_master, true);
|
||||
i2c_master->cmd_idx = 0;
|
||||
i2c_master->trans_idx = 0;
|
||||
ESP_LOGE(TAG, "I2C hardware timeout detected");
|
||||
@ -604,7 +614,7 @@ static esp_err_t s_i2c_transaction_start(i2c_master_dev_handle_t i2c_dev, int xf
|
||||
// Sometimes when the FSM get stuck, the ACK_ERR interrupt will occur endlessly until we reset the FSM and clear bus.
|
||||
esp_err_t ret = ESP_OK;
|
||||
if (atomic_load(&i2c_master->status) == I2C_STATUS_TIMEOUT || i2c_ll_is_bus_busy(hal->dev)) {
|
||||
ESP_RETURN_ON_ERROR(s_i2c_hw_fsm_reset(i2c_master), TAG, "reset hardware failed");
|
||||
ESP_RETURN_ON_ERROR(s_i2c_hw_fsm_reset(i2c_master, true), TAG, "reset hardware failed");
|
||||
}
|
||||
|
||||
if (i2c_master->base->pm_lock) {
|
||||
@ -938,7 +948,7 @@ static esp_err_t s_i2c_synchronous_transaction(i2c_master_dev_handle_t i2c_dev,
|
||||
|
||||
err:
|
||||
// When error occurs, reset hardware fsm in case not influence following transactions.
|
||||
s_i2c_hw_fsm_reset(i2c_dev->master_bus);
|
||||
s_i2c_hw_fsm_reset(i2c_dev->master_bus, false);
|
||||
xSemaphoreGive(i2c_dev->master_bus->bus_lock_mux);
|
||||
return ret;
|
||||
}
|
||||
@ -1153,7 +1163,7 @@ esp_err_t i2c_master_bus_reset(i2c_master_bus_handle_t bus_handle)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE((bus_handle != NULL), ESP_ERR_INVALID_ARG, TAG, "This bus is not initialized");
|
||||
// Reset I2C master bus
|
||||
ESP_RETURN_ON_ERROR(s_i2c_hw_fsm_reset(bus_handle), TAG, "I2C master bus reset failed");
|
||||
ESP_RETURN_ON_ERROR(s_i2c_hw_fsm_reset(bus_handle, true), TAG, "I2C master bus reset failed");
|
||||
// Reset I2C status state
|
||||
atomic_store(&bus_handle->status, I2C_STATUS_IDLE);
|
||||
return ESP_OK;
|
||||
@ -1287,6 +1297,8 @@ esp_err_t i2c_master_probe(i2c_master_bus_handle_t bus_handle, uint16_t address,
|
||||
i2c_ll_set_source_clk(hal->dev, bus_handle->base->clk_src);
|
||||
i2c_hal_set_bus_timing(hal, 100000, bus_handle->base->clk_src, bus_handle->base->clk_src_freq_hz);
|
||||
}
|
||||
i2c_ll_txfifo_rst(hal->dev);
|
||||
i2c_ll_rxfifo_rst(hal->dev);
|
||||
i2c_ll_master_set_fractional_divider(hal->dev, 0, 0);
|
||||
i2c_ll_enable_intr_mask(hal->dev, I2C_LL_MASTER_EVENT_INTR);
|
||||
// 20ms is sufficient for stretch, since there is no device config on probe operation.
|
||||
@ -1315,7 +1327,8 @@ esp_err_t i2c_master_execute_defined_operations(i2c_master_dev_handle_t i2c_dev,
|
||||
ESP_RETURN_ON_FALSE(i2c_operation != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c operation pointer is invalid");
|
||||
ESP_RETURN_ON_FALSE(operation_list_num <= (SOC_I2C_CMD_REG_NUM), ESP_ERR_INVALID_ARG, TAG, "i2c command list cannot contain so many commands");
|
||||
|
||||
i2c_operation_t i2c_ops[operation_list_num] = {};
|
||||
i2c_operation_t i2c_ops[operation_list_num];
|
||||
memset(i2c_ops, 0, sizeof(i2c_ops));
|
||||
for (int i = 0; i < operation_list_num; i++) {
|
||||
switch (i2c_operation[i].command) {
|
||||
case I2C_MASTER_CMD_START:
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user