mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
feat(i2c_master): Add parameter to config I2C scl await time
This commit is contained in:
@@ -92,8 +92,9 @@ static esp_err_t s_i2c_hw_fsm_reset(i2c_master_bus_handle_t i2c_master)
|
||||
|
||||
//to reset the I2C hw module, we need re-enable the hw
|
||||
s_i2c_master_clear_bus(i2c_master->base);
|
||||
periph_module_disable(i2c_periph_signal[i2c_master->base->port_num].module);
|
||||
periph_module_enable(i2c_periph_signal[i2c_master->base->port_num].module);
|
||||
I2C_RCC_ATOMIC() {
|
||||
i2c_ll_reset_register(i2c_master->base->port_num);
|
||||
}
|
||||
|
||||
i2c_hal_master_init(hal);
|
||||
i2c_ll_disable_intr_mask(hal->dev, I2C_LL_INTR_MASK);
|
||||
@@ -529,6 +530,7 @@ static esp_err_t s_i2c_transaction_start(i2c_master_dev_handle_t i2c_dev, int xf
|
||||
i2c_master->rx_cnt = 0;
|
||||
i2c_master->read_len_static = 0;
|
||||
|
||||
i2c_hal_master_set_scl_timeout_val(hal, i2c_dev->scl_wait_us, i2c_master->base->clk_src_freq_hz);
|
||||
I2C_CLOCK_SRC_ATOMIC() {
|
||||
i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src);
|
||||
i2c_hal_set_bus_timing(hal, i2c_dev->scl_speed_hz, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz);
|
||||
@@ -959,6 +961,7 @@ esp_err_t i2c_master_bus_add_device(i2c_master_bus_handle_t bus_handle, const i2
|
||||
i2c_dev->addr_10bits = dev_config->dev_addr_length;
|
||||
i2c_dev->master_bus = i2c_master;
|
||||
i2c_dev->ack_check_disable = dev_config->flags.disable_ack_check;
|
||||
i2c_dev->scl_wait_us = (dev_config->scl_wait_us == 0) ? I2C_LL_SCL_WAIT_US_VAL_DEFAULT : dev_config->scl_wait_us;
|
||||
|
||||
i2c_master_device_list_t *device_item = (i2c_master_device_list_t *)calloc(1, sizeof(i2c_master_device_list_t));
|
||||
ESP_GOTO_ON_FALSE((device_item != NULL), ESP_ERR_NO_MEM, err, TAG, "no memory for i2c device item`");
|
||||
|
||||
@@ -165,6 +165,7 @@ struct i2c_master_dev_t {
|
||||
i2c_master_bus_t *master_bus; // I2C master bus base class
|
||||
uint16_t device_address; // I2C device address
|
||||
uint32_t scl_speed_hz; // SCL clock frequency
|
||||
uint32_t scl_wait_us; // SCL await time (unit:us)
|
||||
i2c_addr_bit_len_t addr_10bits; // Whether I2C device is a 10-bits address device.
|
||||
bool ack_check_disable; // Disable ACK check
|
||||
i2c_master_callback_t on_trans_done; // I2C master transaction done callback.
|
||||
|
||||
@@ -38,6 +38,7 @@ typedef struct {
|
||||
i2c_addr_bit_len_t dev_addr_length; /*!< Select the address length of the slave device. */
|
||||
uint16_t device_address; /*!< I2C device raw address. (The 7/10 bit address without read/write bit) */
|
||||
uint32_t scl_speed_hz; /*!< I2C SCL line frequency. */
|
||||
uint32_t scl_wait_us; /*!< Timeout value. (unit: us). Please note this value should not be so small that it can handle stretch/disturbance properly. If 0 is set, that means use the default reg value*/
|
||||
struct {
|
||||
uint32_t disable_ack_check: 1; /*!< Disable ACK check. If this is set false, that means ack check is enabled, the transaction will be stoped and API returns error when nack is detected. */
|
||||
} flags; /*!< I2C device config flags */
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef enum {
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_EMPTY_INT_ENA_M|I2C_RX_REC_FULL_INT_ST_M)
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M|I2C_RX_REC_FULL_INT_ST_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_EMPTY_INT_ENA_M)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2000) // 2000 is not default value on esp32, but 0 is not good to be default
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@@ -809,6 +810,19 @@ static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx)
|
||||
return hw->command[cmd_idx].done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return clk_cycle_num_per_us * timeout_us;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -60,6 +60,7 @@ typedef enum {
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
#define I2C_LL_MASTER_EVENT_INTR (I2C_NACK_INT_ENA_M|I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2000) // Approximate value for SCL timeout regs (in us).
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@@ -745,6 +746,19 @@ static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx)
|
||||
return hw->command[cmd_idx].command_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return 31 - __builtin_clz(clk_cycle_num_per_us * timeout_us);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -74,6 +74,7 @@ typedef enum {
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_WM_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2000) // Approximate value for SCL timeout regs (in us).
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@@ -918,6 +919,19 @@ static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx)
|
||||
return hw->command[cmd_idx].command0_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return 31 - __builtin_clz(clk_cycle_num_per_us * timeout_us);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -75,6 +75,7 @@ typedef enum {
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_WM_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2500) // Approximate value for SCL timeout regs (in us).
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@@ -852,6 +853,19 @@ static inline void i2c_ll_slave_clear_stretch(i2c_dev_t *dev)
|
||||
dev->scl_stretch_conf.slave_scl_stretch_clr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return 31 - __builtin_clz(clk_cycle_num_per_us * timeout_us);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -75,6 +75,7 @@ typedef enum {
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_WM_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2000) // Approximate value for SCL timeout regs (in us).
|
||||
|
||||
// I2C sleep retention module
|
||||
#define I2C_SLEEP_RETENTION_MODULE(i2c_num) (SLEEP_RETENTION_MODULE_I2C0)
|
||||
@@ -953,6 +954,19 @@ static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx)
|
||||
return hw->command[cmd_idx].command_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return 31 - __builtin_clz(clk_cycle_num_per_us * timeout_us);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -74,6 +74,7 @@ typedef enum {
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_WM_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2500) // Approximate value for SCL timeout regs (in us).
|
||||
|
||||
// I2C sleep retention module
|
||||
#define I2C_SLEEP_RETENTION_MODULE(i2c_num) ((i2c_num == 0) ? SLEEP_RETENTION_MODULE_I2C0 : SLEEP_RETENTION_MODULE_I2C1)
|
||||
@@ -868,6 +869,19 @@ static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx)
|
||||
return hw->command[cmd_idx].command_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return 31 - __builtin_clz(clk_cycle_num_per_us * timeout_us);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -80,6 +80,7 @@ typedef enum {
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_WM_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2000) // Approximate value for SCL timeout regs (in us).
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@@ -965,6 +966,19 @@ static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx)
|
||||
return hw->command[cmd_idx].command_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return 31 - __builtin_clz(clk_cycle_num_per_us * timeout_us);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef enum {
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_WM_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2000) // 2000 is not default value on esp32s2, but 0 is not good to be default
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@@ -858,6 +859,19 @@ static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx)
|
||||
return hw->command[cmd_idx].done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return clk_cycle_num_per_us * timeout_us;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -74,6 +74,7 @@ typedef enum {
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_WM_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2000) // Approximate value for SCL timeout regs (in us).
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@@ -920,6 +921,19 @@ static inline bool i2c_ll_master_is_cmd_done(i2c_dev_t *hw, int cmd_idx)
|
||||
return hw->comd[cmd_idx].command_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate SCL timeout us to reg value
|
||||
*
|
||||
* @param timeout_us timeout value in us
|
||||
* @param src_clk_hz source clock frequency
|
||||
* @return uint32_t reg value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_calculate_timeout_us_to_reg_val(uint32_t src_clk_hz, uint32_t timeout_us)
|
||||
{
|
||||
uint32_t clk_cycle_num_per_us = src_clk_hz / (1 * 1000 * 1000);
|
||||
return 31 - __builtin_clz(clk_cycle_num_per_us * timeout_us);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
||||
@@ -58,6 +58,12 @@ void _i2c_hal_deinit(i2c_hal_context_t *hal)
|
||||
hal->dev = NULL;
|
||||
}
|
||||
|
||||
void i2c_hal_master_set_scl_timeout_val(i2c_hal_context_t *hal, uint32_t timeout_us, uint32_t sclk_clock_hz)
|
||||
{
|
||||
uint32_t reg_val = i2c_ll_calculate_timeout_us_to_reg_val(sclk_clock_hz, timeout_us);
|
||||
i2c_ll_set_tout(hal->dev, reg_val);
|
||||
}
|
||||
|
||||
#if !SOC_I2C_SUPPORT_HW_FSM_RST
|
||||
|
||||
void i2c_hal_get_timing_config(i2c_hal_context_t *hal, i2c_hal_timing_config_t *timing_config)
|
||||
|
||||
@@ -132,6 +132,15 @@ void i2c_hal_master_handle_tx_event(i2c_hal_context_t *hal, i2c_intr_event_t *ev
|
||||
*/
|
||||
void i2c_hal_master_handle_rx_event(i2c_hal_context_t *hal, i2c_intr_event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Set scl timeout reg value according to given timeout us and source clock frequency
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timeout_us timeout us
|
||||
* @param sclk_clock_hz source clock hz
|
||||
*/
|
||||
void i2c_hal_master_set_scl_timeout_val(i2c_hal_context_t *hal, uint32_t timeout_us, uint32_t sclk_clock_hz);
|
||||
|
||||
/**
|
||||
* @brief Init I2C hal layer
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user