diff --git a/components/driver/deprecated/rtc_temperature_legacy.c b/components/driver/deprecated/rtc_temperature_legacy.c index 30e59bc6e3..eb69c7604e 100644 --- a/components/driver/deprecated/rtc_temperature_legacy.c +++ b/components/driver/deprecated/rtc_temperature_legacy.c @@ -18,7 +18,6 @@ #include "esp_log.h" #include "esp_efuse_rtc_calib.h" #include "hal/temperature_sensor_ll.h" -#include "hal/regi2c_ctrl_ll.h" #include "driver/temp_sensor_types_legacy.h" #include "esp_private/periph_ctrl.h" @@ -28,10 +27,6 @@ static const char *TAG = "tsens"; #define TSENS_DAC_FACTOR (27.88) #define TSENS_SYS_OFFSET (20.52) -extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. -#define RTC_TEMP_SENSOR_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) -#define RTC_TEMP_SENSOR_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) - typedef struct { int index; int offset; @@ -68,11 +63,8 @@ esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens) err = ESP_ERR_INVALID_STATE; } temperature_sensor_ll_set_clk_div(tsens.clk_div); - RTC_TEMP_SENSOR_ENTER_CRITICAL(); - regi2c_ctrl_ll_i2c_saradc_enable(); temperature_sensor_ll_set_range(dac_offset[tsens.dac_offset].reg_val); temperature_sensor_ll_enable(true); - RTC_TEMP_SENSOR_EXIT_CRITICAL(); ESP_LOGI(TAG, "Config range [%d°C ~ %d°C], error < %d°C", dac_offset[tsens.dac_offset].range_min, dac_offset[tsens.dac_offset].range_max, @@ -102,6 +94,7 @@ esp_err_t temp_sensor_start(void) ESP_LOGE(TAG, "Is already running or not be configured"); err = ESP_ERR_INVALID_STATE; } + regi2c_saradc_enable(); periph_module_enable(PERIPH_TEMPSENSOR_MODULE); temperature_sensor_ll_enable(true); temperature_sensor_ll_clk_enable(true); @@ -112,6 +105,7 @@ esp_err_t temp_sensor_start(void) esp_err_t temp_sensor_stop(void) { + regi2c_saradc_disable(); temperature_sensor_ll_enable(false); tsens_hw_state = TSENS_HW_STATE_CONFIGURED; return ESP_OK; diff --git a/components/driver/temperature_sensor.c b/components/driver/temperature_sensor.c index 87653814a8..bb11e3148e 100644 --- a/components/driver/temperature_sensor.c +++ b/components/driver/temperature_sensor.c @@ -25,15 +25,10 @@ #include "esp_efuse_rtc_calib.h" #include "esp_private/periph_ctrl.h" #include "hal/temperature_sensor_ll.h" -#include "hal/regi2c_ctrl_ll.h" #include "soc/temperature_sensor_periph.h" static const char *TAG = "temperature_sensor"; -extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. -#define TEMPERATURE_SENSOR_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) -#define TEMPERATURE_SENSOR_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) - typedef enum { TEMP_SENSOR_FSM_INIT, TEMP_SENSOR_FSM_ENABLE, @@ -103,11 +98,9 @@ esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_co tsens->tsens_attribute->range_max, tsens->tsens_attribute->error_max); - TEMPERATURE_SENSOR_ENTER_CRITICAL(); - regi2c_ctrl_ll_i2c_saradc_enable(); + regi2c_saradc_enable(); temperature_sensor_ll_set_range(tsens->tsens_attribute->reg_val); temperature_sensor_ll_enable(false); // disable the sensor by default - TEMPERATURE_SENSOR_EXIT_CRITICAL(); tsens->fsm = TEMP_SENSOR_FSM_INIT; *ret_tsens = tsens; @@ -126,6 +119,7 @@ esp_err_t temperature_sensor_uninstall(temperature_sensor_handle_t tsens) free(s_tsens_attribute_copy); } s_tsens_attribute_copy = NULL; + regi2c_saradc_disable(); periph_module_disable(PERIPH_TEMPSENSOR_MODULE); free(tsens); diff --git a/components/esp_hw_support/include/esp_private/regi2c_ctrl.h b/components/esp_hw_support/include/esp_private/regi2c_ctrl.h index a43097cfb3..def755d815 100644 --- a/components/esp_hw_support/include/esp_private/regi2c_ctrl.h +++ b/components/esp_hw_support/include/esp_private/regi2c_ctrl.h @@ -70,6 +70,13 @@ void regi2c_analog_cali_reg_read(void); void regi2c_analog_cali_reg_write(void); #endif //#if ADC_CALI_PD_WORKAROUND +/* Enable/Disable regi2c_saradc with calling these two functions. + With reference count protection inside. + Internal use only. +*/ +void regi2c_saradc_enable(void); +void regi2c_saradc_disable(void); + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/regi2c_ctrl.c b/components/esp_hw_support/regi2c_ctrl.c index 97dcdb3523..8681c91aae 100644 --- a/components/esp_hw_support/regi2c_ctrl.c +++ b/components/esp_hw_support/regi2c_ctrl.c @@ -10,9 +10,13 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "hal/regi2c_ctrl.h" +#include "hal/regi2c_ctrl_ll.h" +#include "esp_hw_log.h" static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; +static DRAM_ATTR __attribute__((unused)) const char *TAG = "REGI2C"; + uint8_t IRAM_ATTR regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add) { portENTER_CRITICAL_SAFE(&mux); @@ -76,4 +80,35 @@ void IRAM_ATTR regi2c_analog_cali_reg_write(void) } } + +/** + * REGI2C_SARADC reference count + */ +static int s_i2c_saradc_enable_cnt; + +void regi2c_saradc_enable(void) +{ + regi2c_enter_critical(); + s_i2c_saradc_enable_cnt++; + if (s_i2c_saradc_enable_cnt == 1) { + regi2c_ctrl_ll_i2c_saradc_enable(); + } + regi2c_exit_critical(); +} + +void regi2c_saradc_disable(void) +{ + regi2c_enter_critical(); + s_i2c_saradc_enable_cnt--; + if (s_i2c_saradc_enable_cnt < 0){ + regi2c_exit_critical(); + ESP_HW_LOGE(TAG, "REGI2C_SARADC is already disabled"); + } else if (s_i2c_saradc_enable_cnt == 0) { + regi2c_ctrl_ll_i2c_saradc_disable(); + } + regi2c_exit_critical(); + +} + + #endif //#if ADC_CALI_PD_WORKAROUND diff --git a/components/hal/esp32/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32/include/hal/regi2c_ctrl_ll.h index aa0e449607..136db16528 100644 --- a/components/hal/esp32/include/hal/regi2c_ctrl_ll.h +++ b/components/hal/esp32/include/hal/regi2c_ctrl_ll.h @@ -38,6 +38,28 @@ static inline void regi2c_ctrl_ll_i2c_apll_enable(void) CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_APLL_M); } +/** + * @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) +{ + // Not used on ESP32, but leave a blank function here. + // I2C_SARADC is only used for enabling some analog features. However, + // ESP32 does not use it to support those features. + // In order to make it convenient for compiling other targets, left a blank function here. +} + +/** + * @brief Disable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_disable(void) +{ + // Not used on ESP32, but leave a blank function here. + // I2C_SARADC is only used for enabling some analog features. However, + // ESP32 does not use it to support those features. + // In order to make it convenient for compiling other targets, left a blank function here. +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c2/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32c2/include/hal/regi2c_ctrl_ll.h index 6e853f2ab0..53c0a9c8e3 100644 --- a/components/hal/esp32c2/include/hal/regi2c_ctrl_ll.h +++ b/components/hal/esp32c2/include/hal/regi2c_ctrl_ll.h @@ -40,7 +40,7 @@ static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibrati } /** - * @brief Enable I2C_SAR + * @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register */ static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) { @@ -48,6 +48,15 @@ static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU); } +/** + * @brief Disable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_disable(void) +{ + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PU); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PD); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c3/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32c3/include/hal/regi2c_ctrl_ll.h index 6e853f2ab0..53c0a9c8e3 100644 --- a/components/hal/esp32c3/include/hal/regi2c_ctrl_ll.h +++ b/components/hal/esp32c3/include/hal/regi2c_ctrl_ll.h @@ -40,7 +40,7 @@ static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibrati } /** - * @brief Enable I2C_SAR + * @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register */ static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) { @@ -48,6 +48,15 @@ static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU); } +/** + * @brief Disable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_disable(void) +{ + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PU); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PD); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32h2/include/hal/regi2c_ctrl_ll.h index 27eaf05e5d..c389577144 100644 --- a/components/hal/esp32h2/include/hal/regi2c_ctrl_ll.h +++ b/components/hal/esp32h2/include/hal/regi2c_ctrl_ll.h @@ -65,7 +65,7 @@ static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibrati } /** - * @brief Enable I2C_SAR + * @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register */ static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) { @@ -73,6 +73,15 @@ static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU); } +/** + * @brief Disable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_disable(void) +{ + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PU); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PD); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h index 4d390fb28f..4f41a3c238 100644 --- a/components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h +++ b/components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h @@ -39,16 +39,22 @@ static inline void regi2c_ctrl_ll_i2c_apll_enable(void) } /** - * @brief Enable I2C_SAR + * @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register */ static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) { - CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M); - SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M); SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M); } +/** + * @brief Disable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_disable(void) +{ + CLEAR_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32s3/include/hal/regi2c_ctrl_ll.h index 8c1cce5d35..f194bedfc4 100644 --- a/components/hal/esp32s3/include/hal/regi2c_ctrl_ll.h +++ b/components/hal/esp32s3/include/hal/regi2c_ctrl_ll.h @@ -35,11 +35,19 @@ static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void) */ static inline void regi2c_ctrl_ll_i2c_saradc_enable(void) { - SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU); CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M); SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M); } +/** + * @brief Disable the I2C internal bus to do I2C read/write operation to the SAR_ADC register + */ +static inline void regi2c_ctrl_ll_i2c_saradc_disable(void) +{ + CLEAR_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M); +} + + /** * @brief Start BBPLL self-calibration */