Преглед изворни кода

Add regi2c enable/disable reference count

Cao Sen Miao пре 3 година
родитељ
комит
2c0651a671

+ 2 - 8
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;

+ 2 - 8
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);

+ 7 - 0
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

+ 35 - 0
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

+ 22 - 0
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

+ 10 - 1
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

+ 10 - 1
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

+ 10 - 1
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

+ 9 - 3
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

+ 9 - 1
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
  */