diff --git a/components/driver/adc.c b/components/driver/adc.c index 5766483a8f..92ab6714ce 100644 --- a/components/driver/adc.c +++ b/components/driver/adc.c @@ -42,6 +42,7 @@ #include "soc/i2s_periph.h" #include "esp_private/i2s_platform.h" #endif +#include "esp_private/sar_periph_ctrl.h" static const char *ADC_TAG = "ADC"; @@ -365,7 +366,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; @@ -454,7 +455,7 @@ esp_err_t adc_digi_stop(void) if (s_adc_digi_ctx->use_adc2) { SAR_ADC2_LOCK_RELEASE(); } - adc_power_release(); + sar_periph_ctrl_adc_continuous_power_release(); } #if CONFIG_IDF_TARGET_ESP32S2 else { @@ -662,7 +663,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) { ADC_ENTER_CRITICAL(); adc_hal_vref_output(ADC_NUM_1, channel, true); @@ -707,7 +708,7 @@ int adc1_get_raw(adc1_channel_t channel) int raw_out = 0; periph_module_enable(PERIPH_SARADC_MODULE); - adc_power_acquire(); + sar_periph_ctrl_adc_oneshot_power_acquire(); SAR_ADC1_LOCK_ACQUIRE(); adc_ll_digi_clk_sel(0); @@ -723,7 +724,7 @@ int adc1_get_raw(adc1_channel_t channel) SAR_ADC1_LOCK_RELEASE(); - adc_power_release(); + sar_periph_ctrl_adc_oneshot_power_release(); periph_module_disable(PERIPH_SARADC_MODULE); return raw_out; @@ -758,7 +759,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * esp_err_t ret = ESP_OK; periph_module_enable(PERIPH_SARADC_MODULE); - adc_power_acquire(); + sar_periph_ctrl_adc_oneshot_power_acquire(); SAR_ADC2_LOCK_ACQUIRE(); adc_ll_digi_clk_sel(0); @@ -777,7 +778,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * SAR_ADC2_LOCK_RELEASE(); - adc_power_release(); + sar_periph_ctrl_adc_oneshot_power_release(); periph_module_disable(PERIPH_SARADC_MODULE); return ret; @@ -879,12 +880,12 @@ uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, a } else { ESP_LOGD(ADC_TAG, "Calibration eFuse is not configured, use self-calibration for ICode"); - adc_power_acquire(); + sar_periph_ctrl_adc_oneshot_power_acquire(); ADC_ENTER_CRITICAL(); const bool internal_gnd = true; init_code = adc_hal_self_calibration(adc_n, channel, atten, internal_gnd); ADC_EXIT_CRITICAL(); - adc_power_release(); + sar_periph_ctrl_adc_oneshot_power_release(); } s_adc_cali_param[adc_n][atten] = init_code; diff --git a/components/driver/adc_common.c b/components/driver/adc_common.c index 672f57feca..49de26316f 100644 --- a/components/driver/adc_common.c +++ b/components/driver/adc_common.c @@ -21,6 +21,7 @@ #include "hal/adc_types.h" #include "hal/adc_hal.h" #include "hal/adc_hal_conf.h" +#include "esp_private/sar_periph_ctrl.h" #if SOC_DAC_SUPPORTED #include "driver/dac.h" @@ -132,64 +133,28 @@ static esp_pm_lock_handle_t s_adc2_arbiter_lock; ADC Common ---------------------------------------------------------------*/ // 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) { - ADC_POWER_ENTER(); - s_adc_power_on_cnt++; - if (s_adc_power_on_cnt == 1) { - adc_power_on_internal(); - } - ADC_POWER_EXIT(); + sar_periph_ctrl_adc_oneshot_power_acquire(); + sar_periph_ctrl_adc_continuous_power_acquire(); } void adc_power_on(void) { - ADC_POWER_ENTER(); - adc_power_on_internal(); - ADC_POWER_EXIT(); -} - -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 + sar_periph_ctrl_adc_oneshot_power_acquire(); + sar_periph_ctrl_adc_continuous_power_acquire(); } void adc_power_release(void) { - ADC_POWER_ENTER(); - s_adc_power_on_cnt--; - /* Sanity check */ - if (s_adc_power_on_cnt < 0) { - ADC_POWER_EXIT(); - ESP_LOGE(ADC_TAG, "%s called, but s_adc_power_on_cnt == 0", __func__); - abort(); - } else if (s_adc_power_on_cnt == 0) { - adc_power_off_internal(); - } - ADC_POWER_EXIT(); + sar_periph_ctrl_adc_continuous_power_release(); + sar_periph_ctrl_adc_oneshot_power_release(); } void adc_power_off(void) { - ADC_POWER_ENTER(); - adc_power_off_internal(); - ADC_POWER_EXIT(); + sar_periph_ctrl_adc_continuous_power_release(); + sar_periph_ctrl_adc_oneshot_power_release(); } esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num) @@ -389,7 +354,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 */ @@ -404,7 +369,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. */ @@ -419,7 +384,7 @@ esp_err_t adc1_lock_release(void) ADC_CHECK((uint32_t *)adc1_dma_lock != NULL, "adc1 lock release called before acquire", ESP_ERR_INVALID_STATE ); /* 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; } @@ -460,7 +425,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_NUM_1, ADC_LL_CTRL_ULP); @@ -583,7 +548,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * //try the lock, return if failed (wifi using). return ESP_ERR_TIMEOUT; } - 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. @@ -628,7 +593,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(); SARADC2_RELEASE(); *raw_out = adc_value; @@ -659,7 +624,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_hal_vref_output(ADC_NUM_1, ch, true); diff --git a/components/driver/esp32/adc.c b/components/driver/esp32/adc.c index b6235a81ad..a7a14ddb22 100644 --- a/components/driver/esp32/adc.c +++ b/components/driver/esp32/adc.c @@ -21,6 +21,7 @@ #include "driver/rtc_cntl.h" #include "driver/gpio.h" #include "driver/adc.h" +#include "esp_private/sar_periph_ctrl.h" #ifndef NDEBUG // Enable built-in checks in queue.h in debug builds @@ -47,7 +48,7 @@ static int hall_sensor_get_value(void) //hall sensor without LNA { int hall_value; - adc_power_acquire(); + sar_periph_ctrl_adc_oneshot_power_acquire(); ADC_ENTER_CRITICAL(); /* disable other peripherals. */ @@ -59,7 +60,7 @@ static int hall_sensor_get_value(void) //hall sensor without LNA adc_ll_hall_disable(); ADC_EXIT_CRITICAL(); - adc_power_release(); + sar_periph_ctrl_adc_oneshot_power_release(); return hall_value; } diff --git a/components/driver/i2s.c b/components/driver/i2s.c index 6f80d068c3..9f4b0eb2cc 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s.c @@ -39,6 +39,7 @@ #include "esp_efuse.h" #include "esp_rom_gpio.h" #include "esp_private/i2s_platform.h" +#include "esp_private/sar_periph_ctrl.h" #include "sdkconfig.h" @@ -1995,7 +1996,7 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, #if SOC_I2S_SUPPORTS_ADC /* If using built-in ADC, we need to enable ADC power manerge*/ if (pre_alloc_i2s_obj->hal_cfg.mode & I2S_MODE_ADC_BUILT_IN) { - adc_power_acquire(); + sar_periph_ctrl_adc_continuous_power_acquire(); } #endif /* Enable module clock */ diff --git a/components/esp_hw_support/include/esp_private/sar_periph_ctrl.h b/components/esp_hw_support/include/esp_private/sar_periph_ctrl.h new file mode 100644 index 0000000000..3b15303af4 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sar_periph_ctrl.h @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * See target/sar_periph_ctrl.c to know involved peripherals + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialise SAR related peripheral register settings + * Should only be used when running into app stage + */ +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 diff --git a/components/esp_hw_support/port/esp32/CMakeLists.txt b/components/esp_hw_support/port/esp32/CMakeLists.txt index 9afa0cf418..7ed1ea62da 100644 --- a/components/esp_hw_support/port/esp32/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32/CMakeLists.txt @@ -16,7 +16,8 @@ if(NOT BOOTLOADER_BUILD) "dport_access.c" "esp_himem.c" "spiram.c" - "spiram_psram.c") + "spiram_psram.c" + "sar_periph_ctrl.c") endif() add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") diff --git a/components/esp_hw_support/port/esp32/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32/sar_periph_ctrl.c new file mode 100644 index 0000000000..90da25dd13 --- /dev/null +++ b/components/esp_hw_support/port/esp32/sar_periph_ctrl.c @@ -0,0 +1,110 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * Related peripherals are: + * - ADC + * - PWDET + */ + +#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 + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON); + + //Add other periph power control initialisation here +} + +void sar_periph_ctrl_power_disable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + 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(); +} diff --git a/components/esp_hw_support/port/esp32c2/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32c2/sar_periph_ctrl.c new file mode 100644 index 0000000000..1592c44341 --- /dev/null +++ b/components/esp_hw_support/port/esp32c2/sar_periph_ctrl.c @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * 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" +#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); + + //Add other periph power control initialisation here +} + +void sar_periph_ctrl_power_disable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + 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 +} diff --git a/components/esp_hw_support/port/esp32c3/CMakeLists.txt b/components/esp_hw_support/port/esp32c3/CMakeLists.txt index 1544faad47..f24471a646 100644 --- a/components/esp_hw_support/port/esp32c3/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c3/CMakeLists.txt @@ -13,7 +13,8 @@ if(NOT BOOTLOADER_BUILD) "esp_hmac.c" "esp_crypto_lock.c" "esp_ds.c" - "dport_access.c") + "dport_access.c" + "sar_periph_ctrl.c") if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE) list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c") diff --git a/components/esp_hw_support/port/esp32c3/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32c3/sar_periph_ctrl.c new file mode 100644 index 0000000000..f0624593f4 --- /dev/null +++ b/components/esp_hw_support/port/esp32c3/sar_periph_ctrl.c @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * 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" +#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); + + //Add other periph power control initialisation here +} + +void sar_periph_ctrl_power_disable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + 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(); +} diff --git a/components/esp_hw_support/port/esp32h2/CMakeLists.txt b/components/esp_hw_support/port/esp32h2/CMakeLists.txt index 2b723bcd9f..f801226d38 100644 --- a/components/esp_hw_support/port/esp32h2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32h2/CMakeLists.txt @@ -13,7 +13,8 @@ if(NOT BOOTLOADER_BUILD) "esp_hmac.c" "esp_crypto_lock.c" "esp_ds.c" - "dport_access.c") + "dport_access.c" + "sar_periph_ctrl.c") if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE) list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c") diff --git a/components/esp_hw_support/port/esp32h2/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32h2/sar_periph_ctrl.c new file mode 100644 index 0000000000..437af44dfa --- /dev/null +++ b/components/esp_hw_support/port/esp32h2/sar_periph_ctrl.c @@ -0,0 +1,105 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * Related peripherals are: + * - ADC + * - PWDET + */ + +#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) +{ + //TODO: IDF-6123 +} + +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(); +} diff --git a/components/esp_hw_support/port/esp32s2/CMakeLists.txt b/components/esp_hw_support/port/esp32s2/CMakeLists.txt index 5254de95a4..679036c615 100644 --- a/components/esp_hw_support/port/esp32s2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32s2/CMakeLists.txt @@ -21,7 +21,8 @@ if(NOT BOOTLOADER_BUILD) "esp_ds.c" "dport_access.c" "spiram.c" - "spiram_psram.c") + "spiram_psram.c" + "sar_periph_ctrl.c") endif() add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") diff --git a/components/esp_hw_support/port/esp32s2/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32s2/sar_periph_ctrl.c new file mode 100644 index 0000000000..33ae356d0d --- /dev/null +++ b/components/esp_hw_support/port/esp32s2/sar_periph_ctrl.c @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * 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" +#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); + + //Add other periph power control initialisation here +} + +void sar_periph_ctrl_power_disable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + 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); +} diff --git a/components/esp_hw_support/port/esp32s3/CMakeLists.txt b/components/esp_hw_support/port/esp32s3/CMakeLists.txt index c4b6b5f8f3..4dae387bb6 100644 --- a/components/esp_hw_support/port/esp32s3/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32s3/CMakeLists.txt @@ -18,7 +18,8 @@ if(NOT BOOTLOADER_BUILD) "esp_hmac.c" "esp_ds.c" "esp_crypto_lock.c" - "spiram.c") + "spiram.c" + "sar_periph_ctrl.c") if(CONFIG_SPIRAM_MODE_QUAD) list(APPEND srcs "spiram_psram.c") diff --git a/components/esp_hw_support/port/esp32s3/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32s3/sar_periph_ctrl.c new file mode 100644 index 0000000000..b00236323f --- /dev/null +++ b/components/esp_hw_support/port/esp32s3/sar_periph_ctrl.c @@ -0,0 +1,112 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * 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" +#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_ON); + + //Add other periph power control initialisation here +} + +void sar_periph_ctrl_power_disable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + 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(); +} diff --git a/components/esp_phy/src/phy_override.c b/components/esp_phy/src/phy_override.c index 5c99078ae1..da13180e1a 100644 --- a/components/esp_phy/src/phy_override.c +++ b/components/esp_phy/src/phy_override.c @@ -5,8 +5,9 @@ */ #include +#include "esp_attr.h" #include "regi2c_ctrl.h" -#include "driver/adc.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. @@ -32,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(); } } @@ -48,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(); + } +} diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index 6e648733be..9d60dc0a7b 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -25,13 +25,6 @@ typedef enum { ADC_NUM_MAX, } adc_ll_num_t; -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; @@ -503,24 +496,6 @@ static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t cha /*--------------------------------------------------------------- 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: diff --git a/components/hal/esp32/include/hal/sar_ctrl_ll.h b/components/hal/esp32/include/hal/sar_ctrl_ll.h new file mode 100644 index 0000000000..703155e74a --- /dev/null +++ b/components/hal/esp32/include/hal/sar_ctrl_ll.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. + * Related peripherals are: + * - ADC + * - PWDET + * + * All of above peripherals require SAR to work correctly. + * As SAR has some registers that will influence above mentioned peripherals. + * This file gives an abstraction for such registers + */ + +#pragma once + +#include +#include "soc/sens_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef enum { + SAR_CTRL_LL_POWER_FSM, //SAR power controlled by FSM + SAR_CTRL_LL_POWER_ON, //SAR power on + SAR_CTRL_LL_POWER_OFF, //SAR power off +} sar_ctrl_ll_power_t; + +/*--------------------------------------------------------------- + SAR power control +---------------------------------------------------------------*/ +/** + * Set SAR power mode + * + * @param mode See `sar_ctrl_ll_power_t` + */ +static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode) +{ + if (mode == SAR_CTRL_LL_POWER_FSM) { + SENS.sar_meas_wait2.force_xpd_sar = 0x0; + } else if (mode == SAR_CTRL_LL_POWER_ON) { + SENS.sar_meas_wait2.force_xpd_sar = 0x3; + } else { + SENS.sar_meas_wait2.force_xpd_sar = 0x2; + } +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index 38bdae9fe9..77fe845ce2 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -510,7 +510,7 @@ static inline adc_ll_rtc_raw_data_t adc_ll_analysis_raw_data(adc_ll_num_t adc_n, * * @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 */ diff --git a/components/hal/esp32c3/include/hal/sar_ctrl_ll.h b/components/hal/esp32c3/include/hal/sar_ctrl_ll.h new file mode 100644 index 0000000000..c9e9a90332 --- /dev/null +++ b/components/hal/esp32c3/include/hal/sar_ctrl_ll.h @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. + * Related peripherals are: + * - ADC + * - PWDET + * - Temp Sensor + * + * All of above peripherals require SAR to work correctly. + * As SAR has some registers that will influence above mentioned peripherals. + * This file gives an abstraction for such registers + */ + +#pragma once + +#include +#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 + SAR_CTRL_LL_POWER_ON, //SAR power on + SAR_CTRL_LL_POWER_OFF, //SAR power off +} sar_ctrl_ll_power_t; + +/*--------------------------------------------------------------- + SAR power control +---------------------------------------------------------------*/ +/** + * Set SAR power mode + * + * @param mode See `sar_ctrl_ll_power_t` + */ +static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode) +{ + if (mode == SAR_CTRL_LL_POWER_FSM) { + RTCCNTL.sensor_ctrl.force_xpd_sar = 0x0; + } else if (mode == SAR_CTRL_LL_POWER_ON) { + RTCCNTL.sensor_ctrl.force_xpd_sar = 0x3; + } else { + RTCCNTL.sensor_ctrl.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 +} +#endif diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index 2221f441f3..9c5ffdf0dd 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -512,18 +512,8 @@ static inline adc_ll_rtc_raw_data_t adc_ll_analysis_raw_data(adc_ll_num_t adc_n, */ 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 } static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl) diff --git a/components/hal/esp32h2/include/hal/sar_ctrl_ll.h b/components/hal/esp32h2/include/hal/sar_ctrl_ll.h new file mode 100644 index 0000000000..072a6539b0 --- /dev/null +++ b/components/hal/esp32h2/include/hal/sar_ctrl_ll.h @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. + * Related peripherals are: + * - ADC + * - PWDET + * - Temp Sensor + * + * All of above peripherals require SAR to work correctly. + * As SAR has some registers that will influence above mentioned peripherals. + * This file gives an abstraction for such registers + */ + +#pragma once + +#include +#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 + SAR_CTRL_LL_POWER_ON, //SAR power on + SAR_CTRL_LL_POWER_OFF, //SAR power off +} sar_ctrl_ll_power_t; + +/*--------------------------------------------------------------- + SAR power control +---------------------------------------------------------------*/ +/** + * @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 +} +#endif diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index 5e53ab2191..c9445cb2aa 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -852,19 +852,17 @@ static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t cha * * @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; } } diff --git a/components/hal/esp32s2/include/hal/sar_ctrl_ll.h b/components/hal/esp32s2/include/hal/sar_ctrl_ll.h new file mode 100644 index 0000000000..e4e239731e --- /dev/null +++ b/components/hal/esp32s2/include/hal/sar_ctrl_ll.h @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. + * Related peripherals are: + * - ADC + * - PWDET + * - Temp Sensor + * + * All of above peripherals require SAR to work correctly. + * As SAR has some registers that will influence above mentioned peripherals. + * This file gives an abstraction for such registers + */ + +#pragma once + +#include +#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 + SAR_CTRL_LL_POWER_ON, //SAR power on + SAR_CTRL_LL_POWER_OFF, //SAR power off +} sar_ctrl_ll_power_t; + +/*--------------------------------------------------------------- + SAR power control +---------------------------------------------------------------*/ +/** + * Set SAR power mode + * + * @param mode See `sar_ctrl_ll_power_t` + */ +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 +} +#endif diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index 15e0b15de6..45c1ce1bec 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -530,19 +530,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; } } diff --git a/components/hal/esp32s3/include/hal/sar_ctrl_ll.h b/components/hal/esp32s3/include/hal/sar_ctrl_ll.h new file mode 100644 index 0000000000..ed31897e4e --- /dev/null +++ b/components/hal/esp32s3/include/hal/sar_ctrl_ll.h @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. + * Related peripherals are: + * - ADC + * - PWDET + * - Temp Sensor + * + * All of above peripherals require SAR to work correctly. + * As SAR has some registers that will influence above mentioned peripherals. + * This file gives an abstraction for such registers + */ + +#pragma once + +#include +#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 + SAR_CTRL_LL_POWER_ON, //SAR power on + SAR_CTRL_LL_POWER_OFF, //SAR power off +} sar_ctrl_ll_power_t; + +/*--------------------------------------------------------------- + SAR power control +---------------------------------------------------------------*/ +/** + * Set SAR power mode + * + * @param mode See `sar_ctrl_ll_power_t` + */ +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 +} +#endif diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index 787e50246e..19b60d0dc5 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -94,13 +94,6 @@ typedef struct 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) - void adc_hal_set_controller(adc_ll_num_t unit, adc_hal_work_mode_t work_mode); #if SOC_ADC_ARBITER_SUPPORTED