feat(i2c_master): Add parameter to config I2C scl await time

This commit is contained in:
Cao Sen Miao
2024-03-27 10:35:11 +08:00
parent 4505ddc8a9
commit ede1df51b0
15 changed files with 150 additions and 2 deletions
+5 -2
View File
@@ -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`");
+1
View File
@@ -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 */
+14
View File
@@ -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)//////////////////////////////
+6
View File
@@ -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)
+9
View File
@@ -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
*