diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index 9097a7170e..d03bc67e24 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/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; } diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index 67d586efc5..af1a0a1c32 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -19,6 +19,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" @@ -348,7 +349,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 */ @@ -363,7 +364,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. */ @@ -378,7 +379,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; } @@ -419,7 +420,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); @@ -555,7 +556,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. @@ -601,7 +602,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 @@ -629,7 +630,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_UNIT_1, ch, true); @@ -718,7 +719,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_hal_vref_output(ADC_UNIT_1, channel, true); @@ -770,7 +771,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(0); adc_atten_t atten = s_atten1_single[channel]; @@ -783,7 +784,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); @@ -821,7 +822,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(0); adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); @@ -837,7 +838,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); diff --git a/components/driver/deprecated/driver/adc.h b/components/driver/deprecated/driver/adc.h index 269d5c390d..7389c65384 100644 --- a/components/driver/deprecated/driver/adc.h +++ b/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. * * diff --git a/components/driver/deprecated/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c index 165683e22b..ce18dfb3a3 100644 --- a/components/driver/deprecated/i2s_legacy.c +++ b/components/driver/deprecated/i2s_legacy.c @@ -28,6 +28,7 @@ #if SOC_I2S_SUPPORTS_DAC #include "driver/dac.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" @@ -1448,7 +1449,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); } @@ -1503,7 +1504,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 diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 8c091172da..b256075dae 100644 --- a/components/esp_adc/adc_continuous.c +++ b/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" @@ -367,7 +368,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); @@ -429,7 +430,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) { diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index 743b76cec9..9ecb491285 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/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 diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c index ca6645efe9..64e66e9f7e 100644 --- a/components/esp_hw_support/adc_share_hw_ctrl.c +++ b/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; diff --git a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h index 9d5f839e8d..3cb1b54680 100644 --- a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h +++ b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h @@ -12,7 +12,6 @@ * * However, usages of above components are different. * Therefore, we put the common used parts into `esp_hw_support`, including: - * - adc power maintainance * - adc hw calibration settings * - adc locks, to prevent concurrently using adc hw */ @@ -26,19 +25,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 /*--------------------------------------------------------------- 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 a5e40f7b0e..40ac8b9367 100644 --- a/components/esp_hw_support/port/esp32/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32/CMakeLists.txt @@ -11,7 +11,8 @@ set(srcs "chip_info.c") if(NOT BOOTLOADER_BUILD) - list(APPEND srcs "cache_sram_mmu.c") + list(APPEND srcs "cache_sram_mmu.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/CMakeLists.txt b/components/esp_hw_support/port/esp32c2/CMakeLists.txt index 315e233fc7..2e7456c11d 100644 --- a/components/esp_hw_support/port/esp32c2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c2/CMakeLists.txt @@ -7,6 +7,12 @@ set(srcs "rtc_clk_init.c" "chip_info.c" ) +if(NOT BOOTLOADER_BUILD) + + list(APPEND srcs "sar_periph_ctrl.c") + +endif() + add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") 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 3496747ded..12a8b2614d 100644 --- a/components/esp_hw_support/port/esp32c3/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c3/CMakeLists.txt @@ -10,7 +10,8 @@ set(srcs "rtc_clk_init.c" if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_hmac.c" "esp_crypto_lock.c" - "esp_ds.c") + "esp_ds.c" + "sar_periph_ctrl.c") # init constructor for wifi list(APPEND srcs "adc2_init_cal.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 74a4790747..690f8f97c2 100644 --- a/components/esp_hw_support/port/esp32h2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32h2/CMakeLists.txt @@ -10,7 +10,8 @@ set(srcs "rtc_clk_init.c" if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_hmac.c" "esp_crypto_lock.c" - "esp_ds.c") + "esp_ds.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 545c19bdca..2f3145e88d 100644 --- a/components/esp_hw_support/port/esp32s2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32s2/CMakeLists.txt @@ -15,7 +15,8 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "memprot.c" "esp_hmac.c" "esp_crypto_lock.c" - "esp_ds.c") + "esp_ds.c" + "sar_periph_ctrl.c") # init constructor for wifi list(APPEND srcs "adc2_init_cal.c") 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 0f42f03f2d..c645020f2c 100644 --- a/components/esp_hw_support/port/esp32s3/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32s3/CMakeLists.txt @@ -14,7 +14,8 @@ set(srcs if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_hmac.c" "esp_ds.c" - "esp_crypto_lock.c") + "esp_crypto_lock.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/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 9115abaa5e..9b9821d9f6 100644 --- a/components/esp_phy/src/phy_override.c +++ b/components/esp_phy/src/phy_override.c @@ -7,7 +7,7 @@ #include #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(); + } +} diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index d4dd029acf..468b207108 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -27,13 +27,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; @@ -551,24 +544,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: 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/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index e9d51a288e..5c99099c2d 100644 --- a/components/hal/esp32c2/include/hal/adc_ll.h +++ b/components/hal/esp32c2/include/hal/adc_ll.h @@ -286,7 +286,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 */ diff --git a/components/hal/esp32c2/include/hal/sar_ctrl_ll.h b/components/hal/esp32c2/include/hal/sar_ctrl_ll.h new file mode 100644 index 0000000000..447fca6dda --- /dev/null +++ b/components/hal/esp32c2/include/hal/sar_ctrl_ll.h @@ -0,0 +1,79 @@ +/* + * 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 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 + 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/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index 399044390d..59728fb053 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -475,7 +475,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 */ 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 bdc13d9f13..45bb7e1c15 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -507,18 +507,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)) 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 0120e427e0..764a2634a5 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -874,19 +874,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; } } 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 7dbd63f665..16b9cfce72 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -526,19 +526,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 a88b1e7669..eeb51e7c8d 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -90,13 +90,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) - /*--------------------------------------------------------------- PWDET(Power detect) controller setting ---------------------------------------------------------------*/