From ede1df51b07f1e41898431fdb989595969e7a9be Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Tue, 19 Mar 2024 12:15:24 +0800 Subject: [PATCH] feat(i2c_master): Add parameter to config I2C scl await time --- components/esp_driver_i2c/i2c_master.c | 7 +++++-- components/esp_driver_i2c/i2c_private.h | 1 + .../esp_driver_i2c/include/driver/i2c_master.h | 1 + components/hal/esp32/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/esp32c2/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/esp32c3/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/esp32c5/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/esp32c6/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/esp32h2/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/esp32p4/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/esp32s2/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/esp32s3/include/hal/i2c_ll.h | 14 ++++++++++++++ components/hal/i2c_hal.c | 6 ++++++ components/hal/include/hal/i2c_hal.h | 9 +++++++++ docs/en/api-reference/peripherals/i2c.rst | 2 ++ 15 files changed, 150 insertions(+), 2 deletions(-) diff --git a/components/esp_driver_i2c/i2c_master.c b/components/esp_driver_i2c/i2c_master.c index 7b0a571101..ac88076b0b 100644 --- a/components/esp_driver_i2c/i2c_master.c +++ b/components/esp_driver_i2c/i2c_master.c @@ -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`"); diff --git a/components/esp_driver_i2c/i2c_private.h b/components/esp_driver_i2c/i2c_private.h index 911b881d3a..b489a984ed 100644 --- a/components/esp_driver_i2c/i2c_private.h +++ b/components/esp_driver_i2c/i2c_private.h @@ -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. diff --git a/components/esp_driver_i2c/include/driver/i2c_master.h b/components/esp_driver_i2c/include/driver/i2c_master.h index f4fc6acdb8..066cf872fa 100644 --- a/components/esp_driver_i2c/include/driver/i2c_master.h +++ b/components/esp_driver_i2c/include/driver/i2c_master.h @@ -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 */ diff --git a/components/hal/esp32/include/hal/i2c_ll.h b/components/hal/esp32/include/hal/i2c_ll.h index 640dea4c13..b56e9c0200 100644 --- a/components/hal/esp32/include/hal/i2c_ll.h +++ b/components/hal/esp32/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/esp32c2/include/hal/i2c_ll.h b/components/hal/esp32c2/include/hal/i2c_ll.h index 245f44fe87..bc6ae54802 100644 --- a/components/hal/esp32c2/include/hal/i2c_ll.h +++ b/components/hal/esp32c2/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/esp32c3/include/hal/i2c_ll.h b/components/hal/esp32c3/include/hal/i2c_ll.h index 97530cb9a1..9fd18c694f 100644 --- a/components/hal/esp32c3/include/hal/i2c_ll.h +++ b/components/hal/esp32c3/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/esp32c5/include/hal/i2c_ll.h b/components/hal/esp32c5/include/hal/i2c_ll.h index 6ee36083d8..5bff9a3302 100644 --- a/components/hal/esp32c5/include/hal/i2c_ll.h +++ b/components/hal/esp32c5/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h index eda67334a5..303f47bd7f 100644 --- a/components/hal/esp32c6/include/hal/i2c_ll.h +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/esp32h2/include/hal/i2c_ll.h b/components/hal/esp32h2/include/hal/i2c_ll.h index ae4ab688fd..9935228463 100644 --- a/components/hal/esp32h2/include/hal/i2c_ll.h +++ b/components/hal/esp32h2/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/esp32p4/include/hal/i2c_ll.h b/components/hal/esp32p4/include/hal/i2c_ll.h index a95aa8e302..e4fdb1622b 100644 --- a/components/hal/esp32p4/include/hal/i2c_ll.h +++ b/components/hal/esp32p4/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/esp32s2/include/hal/i2c_ll.h b/components/hal/esp32s2/include/hal/i2c_ll.h index f30193dee1..1061180e39 100644 --- a/components/hal/esp32s2/include/hal/i2c_ll.h +++ b/components/hal/esp32s2/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/esp32s3/include/hal/i2c_ll.h b/components/hal/esp32s3/include/hal/i2c_ll.h index d0bda86b50..d881c05416 100644 --- a/components/hal/esp32s3/include/hal/i2c_ll.h +++ b/components/hal/esp32s3/include/hal/i2c_ll.h @@ -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)////////////////////////////// diff --git a/components/hal/i2c_hal.c b/components/hal/i2c_hal.c index 89bd76a908..8a96c56586 100644 --- a/components/hal/i2c_hal.c +++ b/components/hal/i2c_hal.c @@ -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) diff --git a/components/hal/include/hal/i2c_hal.h b/components/hal/include/hal/i2c_hal.h index 7883be4821..b7f7518e1f 100644 --- a/components/hal/include/hal/i2c_hal.h +++ b/components/hal/include/hal/i2c_hal.h @@ -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 * diff --git a/docs/en/api-reference/peripherals/i2c.rst b/docs/en/api-reference/peripherals/i2c.rst index ff861008f5..647d504ad8 100644 --- a/docs/en/api-reference/peripherals/i2c.rst +++ b/docs/en/api-reference/peripherals/i2c.rst @@ -104,6 +104,8 @@ I2C master device requires the configuration that specified by :cpp:type:`i2c_de - :cpp:member:`i2c_device_config_t::dev_addr_length` configure the address bit length of the slave device. User can choose from enumerator :cpp:enumerator:`I2C_ADDR_BIT_LEN_7` or :cpp:enumerator:`I2C_ADDR_BIT_LEN_10` (if supported). - :cpp:member:`i2c_device_config_t::device_address` I2C device raw address. Please parse the device address to this member directly. For example, the device address is 0x28, then parse 0x28 to :cpp:member:`i2c_device_config_t::device_address`, don't carry a write/read bit. - :cpp:member:`i2c_device_config_t::scl_speed_hz` set the scl line frequency of this device. +- :cpp:member:`i2c_device_config_t::scl_wait_us`. SCL await time (in us). Usually this value should not be very small because slave stretch will happen in pretty long time. (It's possible even stretch for 12ms). Set 0 means use default reg value. + Once the :cpp:type:`i2c_device_config_t` structure is populated with mandatory parameters, users can call :cpp:func:`i2c_master_bus_add_device` to allocate an I2C device instance and mounted to the master bus then. This function will return an I2C device handle if it runs correctly. Specifically, when the I2C bus is not initialized properly, calling this function will result in a :c:macro:`ESP_ERR_INVALID_ARG` error.