From 6d82c324bb743bd64a00712142f016f5ccd121c3 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Thu, 28 Mar 2024 15:19:45 +0800 Subject: [PATCH] feat(adc): move adc periph enable/reset functions to ll layer --- components/driver/deprecated/adc_dma_legacy.c | 5 +- components/esp_adc/adc_continuous.c | 4 +- components/esp_adc/adc_oneshot.c | 7 --- .../test_apps/adc/main/test_adc_performance.c | 3 ++ components/esp_hw_support/adc_share_hw_ctrl.c | 14 +++--- .../include/esp_private/adc_share_hw_ctrl.h | 8 +++- components/hal/esp32/include/hal/adc_ll.h | 22 ++++++++- components/hal/esp32c2/include/hal/adc_ll.h | 26 +++++++++- components/hal/esp32c3/include/hal/adc_ll.h | 24 ++++++++++ components/hal/esp32c6/include/hal/adc_ll.h | 21 ++++++++- components/hal/esp32h2/include/hal/adc_ll.h | 20 +++++++- components/hal/esp32p4/include/hal/adc_ll.h | 47 +++++++++---------- components/hal/esp32s2/include/hal/adc_ll.h | 30 +++++++++++- components/hal/esp32s3/include/hal/adc_ll.h | 24 ++++++++++ 14 files changed, 209 insertions(+), 46 deletions(-) diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index dd3e9f3a72..ca95596cd0 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -434,7 +434,10 @@ esp_err_t adc_digi_start(void) return ESP_ERR_INVALID_STATE; } //reset ADC digital part to reset ADC sampling EOF counter - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_reset_register(); + } + sar_periph_ctrl_adc_continuous_power_acquire(); //reset flags s_adc_digi_ctx->ringbuf_overflow_flag = 0; diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 6a13fb2911..fd748b8e24 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -245,7 +245,9 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle) ESP_RETURN_ON_FALSE(handle->fsm == ADC_FSM_INIT, ESP_ERR_INVALID_STATE, ADC_TAG, "ADC continuous mode isn't in the init state, it's started already"); //reset ADC digital part to reset ADC sampling EOF counter - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_reset_register(); + } if (handle->pm_lock) { ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(handle->pm_lock), ADC_TAG, "acquire pm_lock failed"); diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index d2929ea405..0691e22f1a 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -115,7 +115,6 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a }; adc_oneshot_hal_init(&(unit->hal), &config); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED //To enable the APB_SARADC periph if needed _lock_acquire(&s_ctx.mutex); s_ctx.apb_periph_ref_cnts++; @@ -123,12 +122,6 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a adc_apb_periph_claim(); } _lock_release(&s_ctx.mutex); -#endif - -//TODO: refactor clock enable/reset functions, add adc_digi_clk_enable/reset and adc_rtc_clk_enable/reset -#if CONFIG_IDF_TARGET_ESP32P4 - adc_ll_rtc_reset(); -#endif if (init_config->ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_acquire(); diff --git a/components/esp_adc/test_apps/adc/main/test_adc_performance.c b/components/esp_adc/test_apps/adc/main/test_adc_performance.c index 82ef8dde07..f6f15e6dbc 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_performance.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_performance.c @@ -28,6 +28,7 @@ __attribute__((unused)) static const char *TAG = "TEST_ADC"; #define TEST_STD_ADC1_CHANNEL0 ADC_CHANNEL_2 #endif +#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-6497 static int s_adc_count_size; static int *s_p_adc_count; static int s_adc_offset = -1; @@ -131,6 +132,8 @@ static float s_print_summary(bool figure) return sqrt(variation_square / count); } +#endif + #if SOC_ADC_DMA_SUPPORTED /*--------------------------------------------------------------- ADC Continuous Average / STD_Deviation Test diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c index 86d3738d5e..32f3c67b79 100644 --- a/components/esp_hw_support/adc_share_hw_ctrl.c +++ b/components/esp_hw_support/adc_share_hw_ctrl.c @@ -12,7 +12,7 @@ * * However, usages of above components are different. * Therefore, we put the common used parts into `esp_hw_support`, including: - * - adc power maintainance + * - adc power maintenance * - adc hw calibration settings * - adc locks, to prevent concurrently using adc hw */ @@ -205,10 +205,10 @@ void adc_apb_periph_claim(void) portENTER_CRITICAL(&s_spinlock); s_adc_digi_ctrlr_cnt++; if (s_adc_digi_ctrlr_cnt == 1) { - //enable ADC digital part - periph_module_enable(PERIPH_SARADC_MODULE); - //reset ADC digital part - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_enable_bus_clock(true); + adc_ll_reset_register(); + } } portEXIT_CRITICAL(&s_spinlock); @@ -219,7 +219,9 @@ void adc_apb_periph_free(void) portENTER_CRITICAL(&s_spinlock); s_adc_digi_ctrlr_cnt--; if (s_adc_digi_ctrlr_cnt == 0) { - periph_module_disable(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_enable_bus_clock(false); + } } else if (s_adc_digi_ctrlr_cnt < 0) { portEXIT_CRITICAL(&s_spinlock); ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__); 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 5bf1084730..a0c82e394b 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,7 @@ * * However, usages of above components are different. * Therefore, we put the common used parts into `esp_hw_support`, including: - * - adc power maintainance + * - adc power maintenance * - adc hw calibration settings * - adc locks, to prevent concurrently using adc hw */ @@ -26,6 +26,12 @@ extern "C" { #endif +#if SOC_RCC_IS_INDEPENDENT || CONFIG_IDF_TARGET_ESP32 +#define ADC_BUS_CLK_ATOMIC() +#else +#define ADC_BUS_CLK_ATOMIC() PERIPH_RCC_ATOMIC() +#endif + #if SOC_ADC_CALIBRATION_V1_SUPPORTED /*--------------------------------------------------------------- ADC Hardware Calibration diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index ea9f8ef8bb..2f50ea6e5a 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,7 @@ #include "soc/syscon_struct.h" #include "soc/rtc_cntl_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/dport_reg.h" #ifdef __cplusplus extern "C" { @@ -565,6 +566,25 @@ static inline void adc_oneshot_ll_disable_all_unit(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + (void)enable; + //For compatibility +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + //For compatibility +} + /** * Set ADC module controller. * There are five SAR ADC controllers: diff --git a/components/hal/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index 9427b0e4c4..2e234d740c 100644 --- a/components/hal/esp32c2/include/hal/adc_ll.h +++ b/components/hal/esp32c2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/misc.h" #include "hal/assert.h" #include "hal/adc_types.h" @@ -286,6 +287,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index b780bcebd5..779312f4fa 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -15,6 +15,7 @@ #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/misc.h" #include "hal/assert.h" #include "hal/adc_types.h" @@ -560,6 +561,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.reg_apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.reg_apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.reg_apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h index d7d689e74a..1761021322 100644 --- a/components/hal/esp32c6/include/hal/adc_ll.h +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -554,6 +554,25 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + PCR.saradc_conf.saradc_reg_clk_en = enable; +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + PCR.saradc_conf.saradc_reg_rst_en = 1; + PCR.saradc_conf.saradc_reg_rst_en = 0; +} + /** * Set ADC module power management. * diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index dd9c811379..315b77de15 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -555,6 +555,24 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + PCR.saradc_conf.saradc_reg_clk_en = enable; +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + PCR.saradc_conf.saradc_reg_rst_en = 1; + PCR.saradc_conf.saradc_reg_rst_en = 0; +} /** * Set ADC module power management. * diff --git a/components/hal/esp32p4/include/hal/adc_ll.h b/components/hal/esp32p4/include/hal/adc_ll.h index 8d3ed7318e..ca81a3dad4 100644 --- a/components/hal/esp32p4/include/hal/adc_ll.h +++ b/components/hal/esp32p4/include/hal/adc_ll.h @@ -199,6 +199,28 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) Common setting ---------------------------------------------------------------*/ +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + HP_SYS_CLKRST.soc_clk_ctrl2.reg_adc_apb_clk_en = enable; +} +// HP_SYS_CLKRST.soc_clk_ctrl2 are shared registers, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_adc = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_adc = 0; +} +// HP_SYS_CLKRST.hp_rst_en2 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module controller. * There are five SAR ADC controllers: @@ -255,31 +277,6 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c } } -// /** -// * Set ADC2 module arbiter work mode. -// * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, -// * the low priority controller will read the invalid ADC data, and the validity of the data can be judged by the flag bit in the data. -// * -// * @note Only ADC2 support arbiter. -// * @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. -// * -// * @param mode Refer to ``adc_arbiter_mode_t``. -// */ -// __attribute__((always_inline)) -// static inline void adc_ll_set_arbiter_work_mode(adc_arbiter_mode_t mode) -// { -// LP_ADC.meas2_mux.sar2_rtc_force = 0; // Enable arbiter in wakeup mode -// if (mode == ADC_ARB_MODE_FIX) { -// ADC.arb_ctrl.arb_grant_force = 0; -// ADC.arb_ctrl.arb_fix_priority = 1; -// } else if (mode == ADC_ARB_MODE_LOOP) { -// ADC.arb_ctrl.arb_grant_force = 0; -// ADC.arb_ctrl.arb_fix_priority = 0; -// } else { -// ADC.arb_ctrl.arb_grant_force = 1; // Shield arbiter. -// } -// } - /** * Set ADC2 module controller priority in arbiter. * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index ef6712a53f..f68a85dc38 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,8 @@ #include "soc/clk_tree_defs.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" +#include "soc/system_reg.h" +#include "soc/dport_reg.h" #ifdef __cplusplus extern "C" { @@ -918,6 +920,32 @@ static inline void adc_oneshot_ll_disable_all_unit(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); + reg_val = reg_val & (~DPORT_APB_SARADC_CLK_EN); + reg_val = reg_val | (enable << DPORT_APB_SARADC_CLK_EN_S); + WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_val); +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_APB_SARADC_RST); + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_APB_SARADC_RST); +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index 7c5e3b4121..ec8180c048 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -20,6 +20,7 @@ #include "soc/rtc_cntl_reg.h" #include "soc/regi2c_defs.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" @@ -612,6 +613,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. *