From 2f5c0355fea5a26c26a8469279444ae87955224f Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Tue, 10 Aug 2021 15:29:07 +0800 Subject: [PATCH 1/2] I2C: Fix i2c write fake timeout and WDT triggered --- components/hal/i2c_hal_iram.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/components/hal/i2c_hal_iram.c b/components/hal/i2c_hal_iram.c index 80c490009b..f40d4a3a0b 100644 --- a/components/hal/i2c_hal_iram.c +++ b/components/hal/i2c_hal_iram.c @@ -16,25 +16,30 @@ void i2c_hal_master_handle_tx_event(i2c_hal_context_t *hal, i2c_intr_event_t *event) { - i2c_ll_master_get_event(hal->dev, event); - if ((*event < I2C_INTR_EVENT_END_DET) || - (*event == I2C_INTR_EVENT_TRANS_DONE)) { - i2c_ll_master_disable_tx_it(hal->dev); - i2c_ll_master_clr_tx_it(hal->dev); - } else if (*event == I2C_INTR_EVENT_END_DET) { - i2c_ll_master_clr_tx_it(hal->dev); + if (i2c_ll_get_intsts_mask(hal->dev) != 0) { + // If intr status is 0, no need to handle it. + i2c_ll_master_get_event(hal->dev, event); + if ((*event < I2C_INTR_EVENT_END_DET) || + (*event == I2C_INTR_EVENT_TRANS_DONE)) { + i2c_ll_master_disable_tx_it(hal->dev); + i2c_ll_master_clr_tx_it(hal->dev); + } else if (*event == I2C_INTR_EVENT_END_DET) { + i2c_ll_master_clr_tx_it(hal->dev); + } } } void i2c_hal_master_handle_rx_event(i2c_hal_context_t *hal, i2c_intr_event_t *event) { - i2c_ll_master_get_event(hal->dev, event); - if ((*event < I2C_INTR_EVENT_END_DET) || - (*event == I2C_INTR_EVENT_TRANS_DONE)) { - i2c_ll_master_disable_rx_it(hal->dev); - i2c_ll_master_clr_rx_it(hal->dev); - } else if (*event == I2C_INTR_EVENT_END_DET) { - i2c_ll_master_clr_rx_it(hal->dev); + if (i2c_ll_get_intsts_mask(hal->dev) != 0) { + i2c_ll_master_get_event(hal->dev, event); + if ((*event < I2C_INTR_EVENT_END_DET) || + (*event == I2C_INTR_EVENT_TRANS_DONE)) { + i2c_ll_master_disable_rx_it(hal->dev); + i2c_ll_master_clr_rx_it(hal->dev); + } else if (*event == I2C_INTR_EVENT_END_DET) { + i2c_ll_master_clr_rx_it(hal->dev); + } } } From fbd25c38371f4985e0e749589c65c59a02a139fb Mon Sep 17 00:00:00 2001 From: Chen Yi Qun Date: Fri, 6 Aug 2021 15:47:12 +0800 Subject: [PATCH 2/2] I2C: add conf_update for esp32c3 i2c --- components/driver/i2c.c | 9 ++++++++- components/hal/esp32c3/include/hal/i2c_ll.h | 7 +++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/components/driver/i2c.c b/components/driver/i2c.c index 1ac074a299..438d1efc12 100644 --- a/components/driver/i2c.c +++ b/components/driver/i2c.c @@ -539,6 +539,7 @@ esp_err_t i2c_set_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t tx_trans_mode, ESP_RETURN_ON_FALSE(rx_trans_mode < I2C_DATA_MODE_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_TRANS_MODE_ERR_STR); I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_data_mode(&(i2c_context[i2c_num].hal), tx_trans_mode, rx_trans_mode); + i2c_hal_update_config(&(i2c_context[i2c_num].hal)); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); return ESP_OK; } @@ -690,13 +691,13 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) i2c_hal_set_sda_timing(&(i2c_context[i2c_num].hal), I2C_SLAVE_SDA_SAMPLE_DEFAULT, I2C_SLAVE_SDA_HOLD_DEFAULT); i2c_hal_set_tout(&(i2c_context[i2c_num].hal), I2C_SLAVE_TIMEOUT_DEFAULT); i2c_hal_enable_slave_rx_it(&(i2c_context[i2c_num].hal)); - i2c_hal_update_config(&(i2c_context[i2c_num].hal)); } else { i2c_hal_master_init(&(i2c_context[i2c_num].hal), i2c_num); //Default, we enable hardware filter i2c_hal_set_filter(&(i2c_context[i2c_num].hal), I2C_FILTER_CYC_NUM_DEF); i2c_hal_set_bus_timing(&(i2c_context[i2c_num].hal), i2c_conf->master.clk_speed, src_clk); } + i2c_hal_update_config(&(i2c_context[i2c_num].hal)); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); return ESP_OK; } @@ -709,6 +710,7 @@ esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period) I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_scl_timing(&(i2c_context[i2c_num].hal), high_period, low_period); + i2c_hal_update_config(&(i2c_context[i2c_num].hal)); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); return ESP_OK; } @@ -728,6 +730,7 @@ esp_err_t i2c_filter_enable(i2c_port_t i2c_num, uint8_t cyc_num) ESP_RETURN_ON_FALSE(p_i2c_obj[i2c_num] != NULL, ESP_FAIL, I2C_TAG, I2C_DRIVER_ERR_STR); I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_filter(&(i2c_context[i2c_num].hal), cyc_num); + i2c_hal_update_config(&(i2c_context[i2c_num].hal)); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); return ESP_OK; } @@ -737,6 +740,7 @@ esp_err_t i2c_filter_disable(i2c_port_t i2c_num) ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR); I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_filter(&(i2c_context[i2c_num].hal), 0); + i2c_hal_update_config(&(i2c_context[i2c_num].hal)); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); return ESP_OK; } @@ -749,6 +753,7 @@ esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_start_timing(&(i2c_context[i2c_num].hal), setup_time, hold_time); + i2c_hal_update_config(&(i2c_context[i2c_num].hal)); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); return ESP_OK; } @@ -770,6 +775,7 @@ esp_err_t i2c_set_stop_timing(i2c_port_t i2c_num, int setup_time, int hold_time) I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_stop_timing(&(i2c_context[i2c_num].hal), setup_time, hold_time); + i2c_hal_update_config(&(i2c_context[i2c_num].hal)); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); return ESP_OK; } @@ -791,6 +797,7 @@ esp_err_t i2c_set_data_timing(i2c_port_t i2c_num, int sample_time, int hold_time I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_set_sda_timing(&(i2c_context[i2c_num].hal), sample_time, hold_time); + i2c_hal_update_config(&(i2c_context[i2c_num].hal)); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); return ESP_OK; } diff --git a/components/hal/esp32c3/include/hal/i2c_ll.h b/components/hal/esp32c3/include/hal/i2c_ll.h index 85c946c23b..d8fbfd206c 100644 --- a/components/hal/esp32c3/include/hal/i2c_ll.h +++ b/components/hal/esp32c3/include/hal/i2c_ll.h @@ -801,9 +801,12 @@ static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw) static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw) { hw->scl_sp_conf.scl_rst_slv_num = 9; - hw->scl_sp_conf.scl_rst_slv_en = 0; - hw->ctr.conf_upgate = 1; hw->scl_sp_conf.scl_rst_slv_en = 1; + hw->ctr.conf_upgate = 1; + // hardward will clear scl_rst_slv_en after sending SCL pulses, + // and we should set conf_upgate bit to synchronize register value. + while (hw->scl_sp_conf.scl_rst_slv_en); + hw->ctr.conf_upgate = 1; } /**