Explorar o código

Merge branch 'refactor/improve_adc_power_maintanance' into 'master'

adc: improve adc power maintanance

Closes IDF-6114 and IDF-6318

See merge request espressif/esp-idf!21151
Armando (Dou Yiwen) %!s(int64=3) %!d(string=hai) anos
pai
achega
d1b8da74d8
Modificáronse 30 ficheiros con 785 adicións e 182 borrados
  1. 3 2
      components/driver/deprecated/adc_dma_legacy.c
  2. 13 12
      components/driver/deprecated/adc_legacy.c
  3. 2 2
      components/driver/deprecated/driver/adc.h
  4. 3 2
      components/driver/deprecated/i2s_legacy.c
  5. 3 2
      components/esp_adc/adc_continuous.c
  6. 3 2
      components/esp_adc/adc_oneshot.c
  7. 3 50
      components/esp_hw_support/adc_share_hw_ctrl.c
  8. 0 14
      components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h
  9. 39 1
      components/esp_hw_support/include/esp_private/sar_periph_ctrl.h
  10. 74 1
      components/esp_hw_support/port/esp32/sar_periph_ctrl.c
  11. 86 1
      components/esp_hw_support/port/esp32c2/sar_periph_ctrl.c
  12. 86 1
      components/esp_hw_support/port/esp32c3/sar_periph_ctrl.c
  13. 79 1
      components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c
  14. 77 2
      components/esp_hw_support/port/esp32h4/sar_periph_ctrl.c
  15. 60 1
      components/esp_hw_support/port/esp32s2/sar_periph_ctrl.c
  16. 76 2
      components/esp_hw_support/port/esp32s3/sar_periph_ctrl.c
  17. 12 3
      components/esp_phy/src/phy_override.c
  18. 0 25
      components/hal/esp32/include/hal/adc_ll.h
  19. 1 1
      components/hal/esp32c2/include/hal/adc_ll.h
  20. 23 1
      components/hal/esp32c2/include/hal/sar_ctrl_ll.h
  21. 1 1
      components/hal/esp32c3/include/hal/adc_ll.h
  22. 24 1
      components/hal/esp32c3/include/hal/sar_ctrl_ll.h
  23. 29 6
      components/hal/esp32c6/include/hal/sar_ctrl_ll.h
  24. 2 12
      components/hal/esp32h4/include/hal/adc_ll.h
  25. 18 6
      components/hal/esp32h4/include/hal/sar_ctrl_ll.h
  26. 7 9
      components/hal/esp32s2/include/hal/adc_ll.h
  27. 27 1
      components/hal/esp32s2/include/hal/sar_ctrl_ll.h
  28. 7 9
      components/hal/esp32s3/include/hal/adc_ll.h
  29. 27 1
      components/hal/esp32s3/include/hal/sar_ctrl_ll.h
  30. 0 10
      components/hal/include/hal/adc_hal.h

+ 3 - 2
components/driver/deprecated/adc_dma_legacy.c

@@ -20,6 +20,7 @@
 #include "freertos/ringbuf.h"
 #include "esp_private/periph_ctrl.h"
 #include "esp_private/adc_share_hw_ctrl.h"
+#include "esp_private/sar_periph_ctrl.h"
 #include "hal/adc_types.h"
 #include "hal/adc_hal.h"
 #include "hal/dma_types.h"
@@ -396,7 +397,7 @@ esp_err_t adc_digi_start(void)
         ESP_LOGE(ADC_TAG, "The driver is already started");
         return ESP_ERR_INVALID_STATE;
     }
-    adc_power_acquire();
+    sar_periph_ctrl_adc_continuous_power_acquire();
     //reset flags
     s_adc_digi_ctx->ringbuf_overflow_flag = 0;
     s_adc_digi_ctx->driver_start_flag = 1;
@@ -466,7 +467,7 @@ esp_err_t adc_digi_stop(void)
     if (s_adc_digi_ctx->use_adc1) {
         adc_lock_release(ADC_UNIT_1);
     }
-    adc_power_release();
+    sar_periph_ctrl_adc_continuous_power_release();
 
     return ESP_OK;
 }

+ 13 - 12
components/driver/deprecated/adc_legacy.c

@@ -20,6 +20,7 @@
 #include "sys/lock.h"
 #include "driver/gpio.h"
 #include "esp_private/adc_share_hw_ctrl.h"
+#include "esp_private/sar_periph_ctrl.h"
 #include "adc1_private.h"
 #include "hal/adc_types.h"
 #include "hal/adc_hal.h"
@@ -333,7 +334,7 @@ esp_err_t adc1_dma_mode_acquire(void)
     SARADC1_ACQUIRE();
     ESP_LOGD( ADC_TAG, "dma mode takes adc1 lock." );
 
-    adc_power_acquire();
+    sar_periph_ctrl_adc_continuous_power_acquire();
 
     SARADC1_ENTER();
     /* switch SARADC into DIG channel */
@@ -348,7 +349,7 @@ esp_err_t adc1_rtc_mode_acquire(void)
     /* Use locks to avoid digtal and RTC controller conflicts.
        for adc1, block until acquire the lock. */
     SARADC1_ACQUIRE();
-    adc_power_acquire();
+    sar_periph_ctrl_adc_oneshot_power_acquire();
 
     SARADC1_ENTER();
     /* switch SARADC into RTC channel. */
@@ -363,7 +364,7 @@ esp_err_t adc1_lock_release(void)
     ESP_RETURN_ON_FALSE((uint32_t *)adc1_dma_lock != NULL, ESP_ERR_INVALID_STATE, ADC_TAG, "adc1 lock release called before acquire");
     /* Use locks to avoid digtal and RTC controller conflicts. for adc1, block until acquire the lock. */
 
-    adc_power_release();
+    sar_periph_ctrl_adc_oneshot_power_release();
     SARADC1_RELEASE();
     return ESP_OK;
 }
@@ -404,7 +405,7 @@ int adc1_get_voltage(adc1_channel_t channel)    //Deprecated. Use adc1_get_raw()
 #if SOC_ULP_SUPPORTED
 void adc1_ulp_enable(void)
 {
-    adc_power_acquire();
+    sar_periph_ctrl_adc_oneshot_power_acquire();
 
     SARADC1_ENTER();
     adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_ULP);
@@ -540,7 +541,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
         return ESP_ERR_TIMEOUT;
     }
 #endif
-    adc_power_acquire();         //in critical section with whole rtc module
+    sar_periph_ctrl_adc_oneshot_power_acquire();         //in critical section with whole rtc module
 
     //avoid collision with other tasks
     adc2_init();   // in critical section with whole rtc module. because the PWDET use the same registers, place it here.
@@ -586,7 +587,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
 #endif //CONFIG_IDF_TARGET_ESP32
     SARADC2_EXIT();
 
-    adc_power_release();
+    sar_periph_ctrl_adc_oneshot_power_release();
 #if CONFIG_IDF_TARGET_ESP32
     adc_lock_release(ADC_UNIT_2);
 #endif
@@ -614,7 +615,7 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
         return ESP_ERR_INVALID_ARG;
     }
 
-    adc_power_acquire();
+    sar_periph_ctrl_adc_oneshot_power_acquire();
     if (adc_unit == ADC_UNIT_1) {
         VREF_ENTER(1);
         adc_ll_vref_output(ADC_UNIT_1, ch, true);
@@ -703,7 +704,7 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
         }
     }
 
-    adc_power_acquire();
+    sar_periph_ctrl_adc_oneshot_power_acquire();
     if (adc_unit == ADC_UNIT_1) {
         RTC_ENTER_CRITICAL();
         adc_ll_vref_output(ADC_UNIT_1, channel, true);
@@ -755,7 +756,7 @@ int adc1_get_raw(adc1_channel_t channel)
     }
 
     periph_module_enable(PERIPH_SARADC_MODULE);
-    adc_power_acquire();
+    sar_periph_ctrl_adc_oneshot_power_acquire();
     adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
 
     adc_atten_t atten = s_atten1_single[channel];
@@ -768,7 +769,7 @@ int adc1_get_raw(adc1_channel_t channel)
     adc_hal_convert(ADC_UNIT_1, channel, &raw_out);
     ADC_REG_LOCK_EXIT();
 
-    adc_power_release();
+    sar_periph_ctrl_adc_oneshot_power_release();
     periph_module_disable(PERIPH_SARADC_MODULE);
     adc_lock_release(ADC_UNIT_1);
 
@@ -806,7 +807,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
     }
 
     periph_module_enable(PERIPH_SARADC_MODULE);
-    adc_power_acquire();
+    sar_periph_ctrl_adc_oneshot_power_acquire();
     adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
 
     adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
@@ -822,7 +823,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
     ret = adc_hal_convert(ADC_UNIT_2, channel, raw_out);
     ADC_REG_LOCK_EXIT();
 
-    adc_power_release();
+    sar_periph_ctrl_adc_oneshot_power_release();
     periph_module_disable(PERIPH_SARADC_MODULE);
     adc_lock_release(ADC_UNIT_2);
 

+ 2 - 2
components/driver/deprecated/driver/adc.h

@@ -105,7 +105,7 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit);
  *       the input of GPIO36 and GPIO39 will be pulled down for about 80ns.
  *       When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39.
  *       Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue.
- *       As a workaround, call adc_power_acquire() in the app. This will result in higher power consumption (by ~1mA),
+ *       As a workaround, call sar_periph_ctrl_adc_oneshot_power_acquire() in the app. This will result in higher power consumption (by ~1mA),
  *       but will remove the glitches on GPIO36 and GPIO39.
  *
  * @note Call ``adc1_config_width()`` before the first time this
@@ -236,7 +236,7 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten);
  *       the input of GPIO36 and GPIO39 will be pulled down for about 80ns.
  *       When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39.
  *       Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue.
- *       As a workaround, call adc_power_acquire() in the app. This will result in higher power consumption (by ~1mA),
+ *       As a workaround, call sar_periph_ctrl_adc_oneshot_power_acquire() in the app. This will result in higher power consumption (by ~1mA),
  *       but will remove the glitches on GPIO36 and GPIO39.
  *
  *

+ 3 - 2
components/driver/deprecated/i2s_legacy.c

@@ -29,6 +29,7 @@
 #include "hal/dac_ll.h"
 #include "hal/dac_types.h"
 #include "esp_private/adc_share_hw_ctrl.h"
+#include "esp_private/sar_periph_ctrl.h"
 #include "adc1_private.h"
 #include "driver/adc_i2s_legacy.h"
 #include "driver/adc_types_legacy.h"
@@ -1453,7 +1454,7 @@ static esp_err_t i2s_init_legacy(i2s_port_t i2s_num, int intr_alloc_flag)
 #if SOC_I2S_SUPPORTS_ADC_DAC
     if ((int)p_i2s[i2s_num]->mode == I2S_COMM_MODE_ADC_DAC) {
         if (p_i2s[i2s_num]->dir & I2S_DIR_RX) {
-            adc_power_acquire();
+            sar_periph_ctrl_adc_continuous_power_acquire();
             adc_set_i2s_data_source(ADC_I2S_DATA_SRC_ADC);
             i2s_ll_enable_builtin_adc(p_i2s[i2s_num]->hal.dev, true);
         }
@@ -1508,7 +1509,7 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
         if (obj->dir & I2S_DIR_RX) {
             // Deinit ADC
             adc_set_i2s_data_source(ADC_I2S_DATA_SRC_IO_SIG);
-            adc_power_release();
+            sar_periph_ctrl_adc_continuous_power_release();
         }
     }
 #endif

+ 3 - 2
components/esp_adc/adc_continuous.c

@@ -21,6 +21,7 @@
 #include "esp_private/periph_ctrl.h"
 #include "esp_private/adc_private.h"
 #include "esp_private/adc_share_hw_ctrl.h"
+#include "esp_private/sar_periph_ctrl.h"
 #include "driver/gpio.h"
 #include "esp_adc/adc_continuous.h"
 #include "hal/adc_types.h"
@@ -372,7 +373,7 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle)
     }
 
     handle->fsm = ADC_FSM_STARTED;
-    adc_power_acquire();
+    sar_periph_ctrl_adc_continuous_power_acquire();
     //reset flags
     if (handle->use_adc1) {
         adc_lock_acquire(ADC_UNIT_1);
@@ -439,7 +440,7 @@ esp_err_t adc_continuous_stop(adc_continuous_handle_t handle)
     if (handle->use_adc1) {
         adc_lock_release(ADC_UNIT_1);
     }
-    adc_power_release();
+    sar_periph_ctrl_adc_continuous_power_release();
 
     //release power manager lock
     if (handle->pm_lock) {

+ 3 - 2
components/esp_adc/adc_oneshot.c

@@ -17,6 +17,7 @@
 #include "esp_adc/adc_oneshot.h"
 #include "esp_private/adc_private.h"
 #include "esp_private/adc_share_hw_ctrl.h"
+#include "esp_private/sar_periph_ctrl.h"
 #include "hal/adc_types.h"
 #include "hal/adc_oneshot_hal.h"
 #include "hal/adc_ll.h"
@@ -112,7 +113,7 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
     _lock_release(&s_ctx.mutex);
 #endif
 
-    adc_power_acquire();
+    sar_periph_ctrl_adc_oneshot_power_acquire();
 
     ESP_LOGD(TAG, "new adc unit%"PRId32" is created", unit->unit_id);
     *ret_unit = unit;
@@ -209,7 +210,7 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle)
     ESP_LOGD(TAG, "adc unit%"PRId32" is deleted", handle->unit_id);
     free(handle);
 
-    adc_power_release();
+    sar_periph_ctrl_adc_oneshot_power_release();
 
 #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
     //To free the APB_SARADC periph if needed

+ 3 - 50
components/esp_hw_support/adc_share_hw_ctrl.c

@@ -28,6 +28,7 @@
 #include "hal/adc_hal_common.h"
 #include "hal/adc_hal_conf.h"
 #include "esp_private/adc_share_hw_ctrl.h"
+#include "esp_private/sar_periph_ctrl.h"
 //For calibration
 #if CONFIG_IDF_TARGET_ESP32S2
 #include "esp_efuse_rtc_table.h"
@@ -39,54 +40,6 @@
 static const char *TAG = "adc_share_hw_ctrl";
 extern portMUX_TYPE rtc_spinlock;
 
-/*------------------------------------------------------------------------------
-* ADC Power
-*----------------------------------------------------------------------------*/
-// This gets incremented when adc_power_acquire() is called, and decremented when
-// adc_power_release() is called. ADC is powered down when the value reaches zero.
-// Should be modified within critical section (ADC_ENTER/EXIT_CRITICAL).
-static int s_adc_power_on_cnt;
-
-static void adc_power_on_internal(void)
-{
-    /* Set the power always on to increase precision. */
-    adc_hal_set_power_manage(ADC_POWER_SW_ON);
-}
-
-void adc_power_acquire(void)
-{
-    portENTER_CRITICAL(&rtc_spinlock);
-    s_adc_power_on_cnt++;
-    if (s_adc_power_on_cnt == 1) {
-        adc_power_on_internal();
-    }
-    portEXIT_CRITICAL(&rtc_spinlock);
-}
-
-static void adc_power_off_internal(void)
-{
-#if CONFIG_IDF_TARGET_ESP32
-    adc_hal_set_power_manage(ADC_POWER_SW_OFF);
-#else
-    adc_hal_set_power_manage(ADC_POWER_BY_FSM);
-#endif
-}
-
-void adc_power_release(void)
-{
-    portENTER_CRITICAL(&rtc_spinlock);
-    s_adc_power_on_cnt--;
-    /* Sanity check */
-    if (s_adc_power_on_cnt < 0) {
-        portEXIT_CRITICAL(&rtc_spinlock);
-        ESP_LOGE(TAG, "%s called, but s_adc_power_on_cnt == 0", __func__);
-        abort();
-    } else if (s_adc_power_on_cnt == 0) {
-        adc_power_off_internal();
-    }
-    portEXIT_CRITICAL(&rtc_spinlock);
-}
-
 
 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
 /*---------------------------------------------------------------
@@ -120,13 +73,13 @@ void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten)
         init_code = esp_efuse_rtc_calib_get_init_code(version, adc_n, atten);
     } else {
         ESP_EARLY_LOGD(TAG, "Calibration eFuse is not configured, use self-calibration for ICode");
-        adc_power_acquire();
+        sar_periph_ctrl_adc_oneshot_power_acquire();
         portENTER_CRITICAL(&rtc_spinlock);
         adc_ll_pwdet_set_cct(ADC_HAL_PWDET_CCT_DEFAULT);
         const bool internal_gnd = true;
         init_code = adc_hal_self_calibration(adc_n, atten, internal_gnd);
         portEXIT_CRITICAL(&rtc_spinlock);
-        adc_power_release();
+        sar_periph_ctrl_adc_oneshot_power_release();
     }
 
     s_adc_cali_param[adc_n][atten] = init_code;

+ 0 - 14
components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h

@@ -26,20 +26,6 @@
 extern "C" {
 #endif
 
-/*------------------------------------------------------------------------------
-* ADC Power
-*----------------------------------------------------------------------------*/
-/**
- * @brief Acquire the ADC Power
- */
-void adc_power_acquire(void);
-
-/**
- * @brief Release the ADC Power
- */
-void adc_power_release(void);
-
-
 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
 /*---------------------------------------------------------------
             ADC Hardware Calibration

+ 39 - 1
components/esp_hw_support/include/esp_private/sar_periph_ctrl.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -24,6 +24,44 @@ extern "C" {
  */
 void sar_periph_ctrl_init(void);
 
+
+/*------------------------------------------------------------------------------
+* ADC Power
+*----------------------------------------------------------------------------*/
+/**
+ * @brief Acquire the ADC oneshot mode power
+ */
+void sar_periph_ctrl_adc_oneshot_power_acquire(void);
+
+/**
+ * @brief Release the ADC oneshot mode power
+ */
+void sar_periph_ctrl_adc_oneshot_power_release(void);
+
+/**
+ * @brief Acquire the ADC continuous mode power
+ */
+void sar_periph_ctrl_adc_continuous_power_acquire(void);
+
+/**
+ * @brief Release the ADC ADC continuous mode power
+ */
+void sar_periph_ctrl_adc_continuous_power_release(void);
+
+
+/*------------------------------------------------------------------------------
+* PWDET Power
+*----------------------------------------------------------------------------*/
+/**
+ * @brief Acquire the PWDET Power
+ */
+void sar_periph_ctrl_pwdet_power_acquire(void);
+
+/**
+ * @brief Release the PWDET Power
+ */
+void sar_periph_ctrl_pwdet_power_release(void);
+
 #ifdef __cplusplus
 }
 #endif

+ 74 - 1
components/esp_hw_support/port/esp32/sar_periph_ctrl.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -15,12 +15,15 @@
  */
 
 #include "sdkconfig.h"
+#include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_private/sar_periph_ctrl.h"
 #include "hal/sar_ctrl_ll.h"
 
+static const char *TAG = "sar_periph_ctrl";
 extern portMUX_TYPE rtc_spinlock;
 
+
 void sar_periph_ctrl_init(void)
 {
     //Put SAR control mux to ON state
@@ -35,3 +38,73 @@ void sar_periph_ctrl_power_disable(void)
     sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
     portEXIT_CRITICAL_SAFE(&rtc_spinlock);
 }
+
+/**
+ * This gets incremented when s_sar_power_acquire() is called,
+ * and decremented when s_sar_power_release() is called.
+ * PWDET is powered down when the value reaches zero.
+ * Should be modified within critical section.
+ */
+static int s_sar_power_on_cnt;
+
+static void s_sar_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_sar_power_on_cnt++;
+    if (s_sar_power_on_cnt == 1) {
+        sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+static void s_sar_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_sar_power_on_cnt--;
+    if (s_sar_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_sar_power_on_cnt == 0) {
+        sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+
+/*------------------------------------------------------------------------------
+* PWDET Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_pwdet_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_pwdet_power_release(void)
+{
+    s_sar_power_release();
+}
+
+
+/*------------------------------------------------------------------------------
+* ADC Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_adc_oneshot_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_adc_oneshot_power_release(void)
+{
+    s_sar_power_release();
+}
+
+void sar_periph_ctrl_adc_continuous_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_adc_continuous_power_release(void)
+{
+    s_sar_power_release();
+}

+ 86 - 1
components/esp_hw_support/port/esp32c2/sar_periph_ctrl.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -16,12 +16,16 @@
  */
 
 #include "sdkconfig.h"
+#include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_private/sar_periph_ctrl.h"
 #include "hal/sar_ctrl_ll.h"
+#include "hal/adc_ll.h"
 
+static const char *TAG = "sar_periph_ctrl";
 extern portMUX_TYPE rtc_spinlock;
 
+
 void sar_periph_ctrl_init(void)
 {
     //Put SAR control mux to FSM state
@@ -36,3 +40,84 @@ void sar_periph_ctrl_power_disable(void)
     sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
     portEXIT_CRITICAL_SAFE(&rtc_spinlock);
 }
+
+
+/*------------------------------------------------------------------------------
+* PWDET Power
+*----------------------------------------------------------------------------*/
+static int s_pwdet_power_on_cnt;
+
+void sar_periph_ctrl_pwdet_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt++;
+    if (s_pwdet_power_on_cnt == 1) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+void sar_periph_ctrl_pwdet_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt--;
+    /* Sanity check */
+    if (s_pwdet_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_pwdet_power_on_cnt == 0) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+
+/*------------------------------------------------------------------------------
+* ADC Power
+*----------------------------------------------------------------------------*/
+static int s_saradc_power_on_cnt;
+
+static void s_sar_adc_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_saradc_power_on_cnt++;
+    if (s_saradc_power_on_cnt == 1) {
+        adc_ll_digi_set_power_manage(ADC_POWER_SW_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+static void s_sar_adc_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_saradc_power_on_cnt--;
+    if (s_saradc_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_saradc_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_saradc_power_on_cnt == 0) {
+        adc_ll_digi_set_power_manage(ADC_POWER_BY_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+void sar_periph_ctrl_adc_oneshot_power_acquire(void)
+{
+    s_sar_adc_power_acquire();
+}
+
+void sar_periph_ctrl_adc_oneshot_power_release(void)
+{
+    s_sar_adc_power_release();
+}
+
+void sar_periph_ctrl_adc_continuous_power_acquire(void)
+{
+    abort();  //c2 not supported, should never reach here
+}
+
+void sar_periph_ctrl_adc_continuous_power_release(void)
+{
+    abort();  //c2 not supported, should never reach here
+}

+ 86 - 1
components/esp_hw_support/port/esp32c3/sar_periph_ctrl.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -16,12 +16,16 @@
  */
 
 #include "sdkconfig.h"
+#include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_private/sar_periph_ctrl.h"
 #include "hal/sar_ctrl_ll.h"
+#include "hal/adc_ll.h"
 
+static const char *TAG = "sar_periph_ctrl";
 extern portMUX_TYPE rtc_spinlock;
 
+
 void sar_periph_ctrl_init(void)
 {
     //Put SAR control mux to FSM state
@@ -36,3 +40,84 @@ void sar_periph_ctrl_power_disable(void)
     sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
     portEXIT_CRITICAL_SAFE(&rtc_spinlock);
 }
+
+
+/*------------------------------------------------------------------------------
+* PWDET Power
+*----------------------------------------------------------------------------*/
+static int s_pwdet_power_on_cnt;
+
+void sar_periph_ctrl_pwdet_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt++;
+    if (s_pwdet_power_on_cnt == 1) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+void sar_periph_ctrl_pwdet_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt--;
+    /* Sanity check */
+    if (s_pwdet_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_pwdet_power_on_cnt == 0) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+
+/*------------------------------------------------------------------------------
+* ADC Power
+*----------------------------------------------------------------------------*/
+static int s_saradc_power_on_cnt;
+
+static void s_sar_adc_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_saradc_power_on_cnt++;
+    if (s_saradc_power_on_cnt == 1) {
+        adc_ll_digi_set_power_manage(ADC_POWER_SW_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+static void s_sar_adc_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_saradc_power_on_cnt--;
+    if (s_saradc_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_saradc_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_saradc_power_on_cnt == 0) {
+        adc_ll_digi_set_power_manage(ADC_POWER_BY_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+void sar_periph_ctrl_adc_oneshot_power_acquire(void)
+{
+    s_sar_adc_power_acquire();
+}
+
+void sar_periph_ctrl_adc_oneshot_power_release(void)
+{
+    s_sar_adc_power_release();
+}
+
+void sar_periph_ctrl_adc_continuous_power_acquire(void)
+{
+    s_sar_adc_power_acquire();
+}
+
+void sar_periph_ctrl_adc_continuous_power_release(void)
+{
+    s_sar_adc_power_release();
+}

+ 79 - 1
components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -15,11 +15,19 @@
  */
 
 #include "sdkconfig.h"
+#include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_private/sar_periph_ctrl.h"
+#include "hal/sar_ctrl_ll.h"
+
+static const char *TAG = "sar_periph_ctrl";
+extern portMUX_TYPE rtc_spinlock;
+
 
 void sar_periph_ctrl_init(void)
 {
+    sar_ctrl_ll_force_power_ctrl_from_pwdet(true);
+
     //TODO: IDF-6124
 }
 
@@ -27,3 +35,73 @@ void sar_periph_ctrl_power_disable(void)
 {
     //TODO: IDF-6124
 }
+
+/**
+ * This gets incremented when s_sar_power_acquire() is called,
+ * and decremented when s_sar_power_release() is called.
+ * PWDET is powered down when the value reaches zero.
+ * Should be modified within critical section.
+ */
+static int s_pwdet_power_on_cnt;
+
+static void s_sar_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt++;
+    if (s_pwdet_power_on_cnt == 1) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+static void s_sar_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt--;
+    if (s_pwdet_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_pwdet_power_on_cnt == 0) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+
+/*------------------------------------------------------------------------------
+* PWDET Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_pwdet_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_pwdet_power_release(void)
+{
+    s_sar_power_release();
+}
+
+
+/*------------------------------------------------------------------------------
+* ADC Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_adc_oneshot_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_adc_oneshot_power_release(void)
+{
+    s_sar_power_release();
+}
+
+void sar_periph_ctrl_adc_continuous_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_adc_continuous_power_release(void)
+{
+    s_sar_power_release();
+}

+ 77 - 2
components/esp_hw_support/port/esp32h4/sar_periph_ctrl.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -12,12 +12,17 @@
  * Related peripherals are:
  * - ADC
  * - PWDET
- * - Temp Sensor
  */
 
 #include "sdkconfig.h"
+#include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_private/sar_periph_ctrl.h"
+#include "hal/sar_ctrl_ll.h"
+
+static const char *TAG = "sar_periph_ctrl";
+extern portMUX_TYPE rtc_spinlock;
+
 
 void sar_periph_ctrl_init(void)
 {
@@ -28,3 +33,73 @@ void sar_periph_ctrl_power_disable(void)
 {
     //TODO: IDF-6123
 }
+
+/**
+ * This gets incremented when s_sar_power_acquire() is called,
+ * and decremented when s_sar_power_release() is called.
+ * PWDET is powered down when the value reaches zero.
+ * Should be modified within critical section.
+ */
+static int s_pwdet_power_on_cnt;
+
+static void s_sar_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt++;
+    if (s_pwdet_power_on_cnt == 1) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+static void s_sar_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt--;
+    if (s_pwdet_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_pwdet_power_on_cnt == 0) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+
+/*------------------------------------------------------------------------------
+* PWDET Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_pwdet_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_pwdet_power_release(void)
+{
+    s_sar_power_release();
+}
+
+
+/*------------------------------------------------------------------------------
+* ADC Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_adc_oneshot_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_adc_oneshot_power_release(void)
+{
+    s_sar_power_release();
+}
+
+void sar_periph_ctrl_adc_continuous_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_adc_continuous_power_release(void)
+{
+    s_sar_power_release();
+}

+ 60 - 1
components/esp_hw_support/port/esp32s2/sar_periph_ctrl.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -16,12 +16,16 @@
  */
 
 #include "sdkconfig.h"
+#include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_private/sar_periph_ctrl.h"
 #include "hal/sar_ctrl_ll.h"
+#include "hal/adc_ll.h"
 
+static const char *TAG = "sar_periph_ctrl";
 extern portMUX_TYPE rtc_spinlock;
 
+
 void sar_periph_ctrl_init(void)
 {
     //Put SAR control mux to FSM state
@@ -36,3 +40,58 @@ void sar_periph_ctrl_power_disable(void)
     sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
     portEXIT_CRITICAL_SAFE(&rtc_spinlock);
 }
+
+
+/*------------------------------------------------------------------------------
+* PWDET Power
+*----------------------------------------------------------------------------*/
+static int s_pwdet_power_on_cnt;
+
+void sar_periph_ctrl_pwdet_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt++;
+    if (s_pwdet_power_on_cnt == 1) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+void sar_periph_ctrl_pwdet_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_pwdet_power_on_cnt--;
+    /* Sanity check */
+    if (s_pwdet_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_pwdet_power_on_cnt == 0) {
+        sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+
+/*------------------------------------------------------------------------------
+* ADC Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_adc_oneshot_power_acquire(void)
+{
+    //Keep oneshot mode power controlled by HW, leave this function for compatibility
+}
+
+void sar_periph_ctrl_adc_oneshot_power_release(void)
+{
+    //Keep oneshot mode power controlled by HW, leave this function for compatibility
+}
+
+void sar_periph_ctrl_adc_continuous_power_acquire(void)
+{
+    adc_ll_digi_set_power_manage(ADC_POWER_SW_ON);
+}
+
+void sar_periph_ctrl_adc_continuous_power_release(void)
+{
+    adc_ll_digi_set_power_manage(ADC_POWER_BY_FSM);
+}

+ 76 - 2
components/esp_hw_support/port/esp32s3/sar_periph_ctrl.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -16,16 +16,20 @@
  */
 
 #include "sdkconfig.h"
+#include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_private/sar_periph_ctrl.h"
 #include "hal/sar_ctrl_ll.h"
+#include "hal/adc_ll.h"
 
+static const char *TAG = "sar_periph_ctrl";
 extern portMUX_TYPE rtc_spinlock;
 
+
 void sar_periph_ctrl_init(void)
 {
     //Put SAR control mux to FSM state
-    sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
+    sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
 
     //Add other periph power control initialisation here
 }
@@ -36,3 +40,73 @@ void sar_periph_ctrl_power_disable(void)
     sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF);
     portEXIT_CRITICAL_SAFE(&rtc_spinlock);
 }
+
+/**
+ * This gets incremented when s_sar_power_acquire() is called,
+ * and decremented when s_sar_power_release() is called.
+ * PWDET is powered down when the value reaches zero.
+ * Should be modified within critical section.
+ */
+static int s_sar_power_on_cnt;
+
+static void s_sar_power_acquire(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_sar_power_on_cnt++;
+    if (s_sar_power_on_cnt == 1) {
+        sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+static void s_sar_power_release(void)
+{
+    portENTER_CRITICAL_SAFE(&rtc_spinlock);
+    s_sar_power_on_cnt--;
+    if (s_sar_power_on_cnt < 0) {
+        portEXIT_CRITICAL(&rtc_spinlock);
+        ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__);
+        abort();
+    } else if (s_sar_power_on_cnt == 0) {
+        sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM);
+    }
+    portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+}
+
+
+/*------------------------------------------------------------------------------
+* PWDET Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_pwdet_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_pwdet_power_release(void)
+{
+    s_sar_power_release();
+}
+
+
+/*------------------------------------------------------------------------------
+* ADC Power
+*----------------------------------------------------------------------------*/
+void sar_periph_ctrl_adc_oneshot_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_adc_oneshot_power_release(void)
+{
+    s_sar_power_release();
+}
+
+void sar_periph_ctrl_adc_continuous_power_acquire(void)
+{
+    s_sar_power_acquire();
+}
+
+void sar_periph_ctrl_adc_continuous_power_release(void)
+{
+    s_sar_power_release();
+}

+ 12 - 3
components/esp_phy/src/phy_override.c

@@ -7,7 +7,7 @@
 #include <stdbool.h>
 #include "esp_attr.h"
 #include "esp_private/regi2c_ctrl.h"
-#include "esp_private/adc_share_hw_ctrl.h"
+#include "esp_private/sar_periph_ctrl.h"
 
 /*
  * This file is used to override the hooks provided by the PHY lib for some system features.
@@ -33,9 +33,9 @@ void set_xpd_sar(bool en)
 
     s_wifi_adc_xpd_flag = en;
     if (en) {
-        adc_power_acquire();
+        sar_periph_ctrl_pwdet_power_acquire();
     } else {
-        adc_power_release();
+        sar_periph_ctrl_pwdet_power_release();
     }
 }
 
@@ -49,3 +49,12 @@ IRAM_ATTR void phy_i2c_exit_critical(void)
 {
     regi2c_exit_critical();
 }
+
+void phy_set_pwdet_power(bool en)
+{
+    if (en) {
+        sar_periph_ctrl_pwdet_power_acquire();
+    } else {
+        sar_periph_ctrl_pwdet_power_release();
+    }
+}

+ 0 - 25
components/hal/esp32/include/hal/adc_ll.h

@@ -29,13 +29,6 @@ extern "C" {
 #define ADC_LL_DEFAULT_CONV_LIMIT_EN      1
 #define ADC_LL_DEFAULT_CONV_LIMIT_NUM     10
 
-typedef enum {
-    ADC_POWER_BY_FSM,   /*!< ADC XPD controlled by FSM. Used for polling mode */
-    ADC_POWER_SW_ON,    /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
-    ADC_POWER_SW_OFF,   /*!< ADC XPD controlled by SW. power off. */
-    ADC_POWER_MAX,      /*!< For parameter check. */
-} adc_ll_power_t;
-
 typedef enum {
     ADC_RTC_DATA_OK = 0,
 } adc_ll_rtc_raw_data_t;
@@ -553,24 +546,6 @@ static inline void adc_oneshot_ll_disable_all_unit(void)
 /*---------------------------------------------------------------
                     Common setting
 ---------------------------------------------------------------*/
-/**
- * Set ADC module power management.
- *
- * @param manage Set ADC power status.
- */
-static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
-{
-    /* Bit1  0:Fsm  1: SW mode
-       Bit0  0:SW mode power down  1: SW mode power on */
-    if (manage == ADC_POWER_SW_ON) {
-        SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_PU;
-    } else if (manage == ADC_POWER_BY_FSM) {
-        SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_FSM;
-    } else if (manage == ADC_POWER_SW_OFF) {
-        SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_PD;
-    }
-}
-
 /**
  * Set ADC module controller.
  * There are five SAR ADC controllers:

+ 1 - 1
components/hal/esp32c2/include/hal/adc_ll.h

@@ -283,7 +283,7 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
  *
  * @param manage Set ADC power status.
  */
-static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
+static inline void adc_ll_digi_set_power_manage(adc_ll_power_t manage)
 {
     /* Bit1  0:Fsm  1: SW mode
        Bit0  0:SW mode power down  1: SW mode power on */

+ 23 - 1
components/hal/esp32c2/include/hal/sar_ctrl_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -19,12 +19,16 @@
 #pragma once
 
 #include <stdlib.h>
+#include "soc/soc.h"
 #include "soc/rtc_cntl_struct.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define PWDET_CONF_REG        0x6004EB60
+#define PWDET_SAR_POWER_FORCE BIT(7)
+#define PWDET_SAR_POWER_CNTL  BIT(6)
 
 typedef enum {
     SAR_CTRL_LL_POWER_FSM,     //SAR power controlled by FSM
@@ -51,6 +55,24 @@ static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode)
     }
 }
 
+/**
+ * @brief Set SAR power mode when controlled by PWDET
+ *
+ * @param[in] mode  See `sar_ctrl_ll_power_t`
+ */
+static inline void sar_ctrl_ll_set_power_mode_from_pwdet(sar_ctrl_ll_power_t mode)
+{
+    if (mode == SAR_CTRL_LL_POWER_FSM) {
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+    } else if (mode == SAR_CTRL_LL_POWER_ON) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    } else if (mode == SAR_CTRL_LL_POWER_OFF) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    }
+}
+
 
 #ifdef __cplusplus
 }

+ 1 - 1
components/hal/esp32c3/include/hal/adc_ll.h

@@ -473,7 +473,7 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
  *
  * @param manage Set ADC power status.
  */
-static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
+static inline void adc_ll_digi_set_power_manage(adc_ll_power_t manage)
 {
     /* Bit1  0:Fsm  1: SW mode
        Bit0  0:SW mode power down  1: SW mode power on */

+ 24 - 1
components/hal/esp32c3/include/hal/sar_ctrl_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -19,12 +19,17 @@
 #pragma once
 
 #include <stdlib.h>
+#include "soc/soc.h"
 #include "soc/rtc_cntl_struct.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define PWDET_CONF_REG        0x6000E060
+#define PWDET_SAR_POWER_FORCE BIT(7)
+#define PWDET_SAR_POWER_CNTL  BIT(6)
+
 
 typedef enum {
     SAR_CTRL_LL_POWER_FSM,     //SAR power controlled by FSM
@@ -51,6 +56,24 @@ static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode)
     }
 }
 
+/**
+ * @brief Set SAR power mode when controlled by PWDET
+ *
+ * @param[in] mode  See `sar_ctrl_ll_power_t`
+ */
+static inline void sar_ctrl_ll_set_power_mode_from_pwdet(sar_ctrl_ll_power_t mode)
+{
+    if (mode == SAR_CTRL_LL_POWER_FSM) {
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+    } else if (mode == SAR_CTRL_LL_POWER_ON) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    } else if (mode == SAR_CTRL_LL_POWER_OFF) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    }
+}
+
 
 #ifdef __cplusplus
 }

+ 29 - 6
components/hal/esp32c6/include/hal/sar_ctrl_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -18,11 +18,18 @@
 #pragma once
 
 #include <stdlib.h>
+#include <stdbool.h>
+#include "soc/soc.h"
+#include "soc/apb_saradc_struct.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define PWDET_CONF_REG        0x600A8010
+#define PWDET_SAR_POWER_FORCE BIT(24)
+#define PWDET_SAR_POWER_CNTL  BIT(23)
+
 
 typedef enum {
     SAR_CTRL_LL_POWER_FSM,     //SAR power controlled by FSM
@@ -34,16 +41,32 @@ typedef enum {
                     SAR power control
 ---------------------------------------------------------------*/
 /**
- * Set SAR power mode
+ * @brief Set SAR power mode when controlled by PWDET
  *
- * @param mode  See `sar_ctrl_ll_power_t`
+ * @param[in] mode  See `sar_ctrl_ll_power_t`
  */
-static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode)
+static inline void sar_ctrl_ll_set_power_mode_from_pwdet(sar_ctrl_ll_power_t mode)
 {
-    //TODO: IDF-6124
-    abort();
+    if (mode == SAR_CTRL_LL_POWER_FSM) {
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+    } else if (mode == SAR_CTRL_LL_POWER_ON) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    } else if (mode == SAR_CTRL_LL_POWER_OFF) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    }
 }
 
+/**
+ * @brief Set SAR power ctrl source
+ *
+ * @param[in] force  set PWDET as SAR power ctrl source when force is true
+ */
+static inline void sar_ctrl_ll_force_power_ctrl_from_pwdet(bool force)
+{
+    APB_SARADC.saradc_ctrl.saradc_saradc2_pwdet_drv = force;
+}
 
 #ifdef __cplusplus
 }

+ 2 - 12
components/hal/esp32h4/include/hal/adc_ll.h

@@ -505,18 +505,8 @@ static inline adc_ll_rtc_raw_data_t adc_ll_analysis_raw_data(adc_unit_t adc_n, i
  */
 static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
 {
-    /* Bit1  0:Fsm  1: SW mode
-       Bit0  0:SW mode power down  1: SW mode power on */
-    if (manage == ADC_POWER_SW_ON) {
-        APB_SARADC.ctrl.sar_clk_gated = 1;
-        APB_SARADC.ctrl.xpd_sar_force = 3;
-    } else if (manage == ADC_POWER_BY_FSM) {
-        APB_SARADC.ctrl.sar_clk_gated = 1;
-        APB_SARADC.ctrl.xpd_sar_force = 0;
-    } else if (manage == ADC_POWER_SW_OFF) {
-        APB_SARADC.ctrl.sar_clk_gated = 0;
-        APB_SARADC.ctrl.xpd_sar_force = 2;
-    }
+    //HW bug, use `sar_ctrl_ll_set_power_mode_from_pwdet` instead, `APB_SARADC.ctrl.xpd_sar_force` doesn not effect
+    //Leave here for a record
 }
 
 __attribute__((always_inline))

+ 18 - 6
components/hal/esp32h4/include/hal/sar_ctrl_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -19,11 +19,16 @@
 #pragma once
 
 #include <stdlib.h>
+#include "soc/soc.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define PWDET_CONF_REG        0x600A8010
+#define PWDET_SAR_POWER_FORCE BIT(24)
+#define PWDET_SAR_POWER_CNTL  BIT(23)
+
 
 typedef enum {
     SAR_CTRL_LL_POWER_FSM,     //SAR power controlled by FSM
@@ -35,14 +40,21 @@ typedef enum {
                     SAR power control
 ---------------------------------------------------------------*/
 /**
- * Set SAR power mode
+ * @brief Set SAR power mode when controlled by PWDET
  *
- * @param mode  See `sar_ctrl_ll_power_t`
+ * @param[in] mode  See `sar_ctrl_ll_power_t`
  */
-static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode)
+static inline void sar_ctrl_ll_set_power_mode_from_pwdet(sar_ctrl_ll_power_t mode)
 {
-    //TODO: IDF-6123
-    abort();
+    if (mode == SAR_CTRL_LL_POWER_FSM) {
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+    } else if (mode == SAR_CTRL_LL_POWER_ON) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    } else if (mode == SAR_CTRL_LL_POWER_OFF) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    }
 }
 
 

+ 7 - 9
components/hal/esp32s2/include/hal/adc_ll.h

@@ -872,19 +872,17 @@ static inline void adc_oneshot_ll_disable_all_unit(void)
  *
  * @param manage Set ADC power status.
  */
-static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
+static inline void adc_ll_digi_set_power_manage(adc_ll_power_t manage)
 {
-    /* Bit1  0:Fsm  1: SW mode
-       Bit0  0:SW mode power down  1: SW mode power on */
     if (manage == ADC_POWER_SW_ON) {
-        SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1;
-        SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_PU;
+        APB_SARADC.ctrl.sar_clk_gated = 1;
+        APB_SARADC.ctrl.xpd_sar_force = 0x3;
     } else if (manage == ADC_POWER_BY_FSM) {
-        SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1;
-        SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_FSM;
+        APB_SARADC.ctrl.sar_clk_gated = 1;
+        APB_SARADC.ctrl.xpd_sar_force = 0x0;
     } else if (manage == ADC_POWER_SW_OFF) {
-        SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_PD;
-        SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 0;
+        APB_SARADC.ctrl.sar_clk_gated = 0;
+        APB_SARADC.ctrl.xpd_sar_force = 0x2;
     }
 }
 

+ 27 - 1
components/hal/esp32s2/include/hal/sar_ctrl_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -19,12 +19,17 @@
 #pragma once
 
 #include <stdlib.h>
+#include "soc/soc.h"
 #include "soc/sens_struct.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define PWDET_CONF_REG        0x6000E060
+#define PWDET_SAR_POWER_FORCE BIT(7)
+#define PWDET_SAR_POWER_CNTL  BIT(6)
+
 
 typedef enum {
     SAR_CTRL_LL_POWER_FSM,     //SAR power controlled by FSM
@@ -43,14 +48,35 @@ typedef enum {
 static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode)
 {
     if (mode == SAR_CTRL_LL_POWER_FSM) {
+        SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1;
         SENS.sar_power_xpd_sar.force_xpd_sar = 0x0;
     } else if (mode == SAR_CTRL_LL_POWER_ON) {
+        SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1;
         SENS.sar_power_xpd_sar.force_xpd_sar = 0x3;
     } else {
+        SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 0;
         SENS.sar_power_xpd_sar.force_xpd_sar = 0x2;
     }
 }
 
+/**
+ * @brief Set SAR power mode when controlled by PWDET
+ *
+ * @param[in] mode  See `sar_ctrl_ll_power_t`
+ */
+static inline void sar_ctrl_ll_set_power_mode_from_pwdet(sar_ctrl_ll_power_t mode)
+{
+    if (mode == SAR_CTRL_LL_POWER_FSM) {
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+    } else if (mode == SAR_CTRL_LL_POWER_ON) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    } else if (mode == SAR_CTRL_LL_POWER_OFF) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    }
+}
+
 
 #ifdef __cplusplus
 }

+ 7 - 9
components/hal/esp32s3/include/hal/adc_ll.h

@@ -523,19 +523,17 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
  *
  * @param manage Set ADC power status.
  */
-static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
+static inline void adc_ll_digi_set_power_manage(adc_ll_power_t manage)
 {
-    /* Bit1  0:Fsm  1: SW mode
-       Bit0  0:SW mode power down  1: SW mode power on */
     if (manage == ADC_POWER_SW_ON) {
-        SENS.sar_peri_clk_gate_conf.saradc_clk_en = 1;
-        SENS.sar_power_xpd_sar.force_xpd_sar = 3; //SENS_FORCE_XPD_SAR_PU;
+        APB_SARADC.ctrl.sar_clk_gated = 1;
+        APB_SARADC.ctrl.xpd_sar_force = 0x3;
     } else if (manage == ADC_POWER_BY_FSM) {
-        SENS.sar_peri_clk_gate_conf.saradc_clk_en = 1;
-        SENS.sar_power_xpd_sar.force_xpd_sar = 0; //SENS_FORCE_XPD_SAR_FSM;
+        APB_SARADC.ctrl.sar_clk_gated = 1;
+        APB_SARADC.ctrl.xpd_sar_force = 0x0;
     } else if (manage == ADC_POWER_SW_OFF) {
-        SENS.sar_power_xpd_sar.force_xpd_sar = 2; //SENS_FORCE_XPD_SAR_PD;
-        SENS.sar_peri_clk_gate_conf.saradc_clk_en = 0;
+        APB_SARADC.ctrl.sar_clk_gated = 0;
+        APB_SARADC.ctrl.xpd_sar_force = 0x2;
     }
 }
 

+ 27 - 1
components/hal/esp32s3/include/hal/sar_ctrl_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -19,12 +19,17 @@
 #pragma once
 
 #include <stdlib.h>
+#include "soc/soc.h"
 #include "soc/sens_struct.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define PWDET_CONF_REG        0x6000E060
+#define PWDET_SAR_POWER_FORCE BIT(7)
+#define PWDET_SAR_POWER_CNTL  BIT(6)
+
 
 typedef enum {
     SAR_CTRL_LL_POWER_FSM,     //SAR power controlled by FSM
@@ -43,14 +48,35 @@ typedef enum {
 static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode)
 {
     if (mode == SAR_CTRL_LL_POWER_FSM) {
+        SENS.sar_peri_clk_gate_conf.saradc_clk_en = 1;
         SENS.sar_power_xpd_sar.force_xpd_sar = 0x0;
     } else if (mode == SAR_CTRL_LL_POWER_ON) {
+        SENS.sar_peri_clk_gate_conf.saradc_clk_en = 1;
         SENS.sar_power_xpd_sar.force_xpd_sar = 0x3;
     } else {
+        SENS.sar_peri_clk_gate_conf.saradc_clk_en = 0;
         SENS.sar_power_xpd_sar.force_xpd_sar = 0x2;
     }
 }
 
+/**
+ * @brief Set SAR power mode when controlled by PWDET
+ *
+ * @param[in] mode  See `sar_ctrl_ll_power_t`
+ */
+static inline void sar_ctrl_ll_set_power_mode_from_pwdet(sar_ctrl_ll_power_t mode)
+{
+    if (mode == SAR_CTRL_LL_POWER_FSM) {
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+    } else if (mode == SAR_CTRL_LL_POWER_ON) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    } else if (mode == SAR_CTRL_LL_POWER_OFF) {
+        REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
+        REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
+    }
+}
+
 
 #ifdef __cplusplus
 }

+ 0 - 10
components/hal/include/hal/adc_hal.h

@@ -87,16 +87,6 @@ typedef struct adc_hal_digi_ctrlr_cfg_t {
 } adc_hal_digi_ctrlr_cfg_t;
 
 
-/*---------------------------------------------------------------
-                    Common setting
----------------------------------------------------------------*/
-/**
- * Set ADC module power management.
- *
- * @prarm manage Set ADC power status.
- */
-#define adc_hal_set_power_manage(manage) adc_ll_set_power_manage(manage)
-
 /*---------------------------------------------------------------
                     PWDET(Power detect) controller setting
 ---------------------------------------------------------------*/