diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index 4054cc1039..31b4777eae 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -176,7 +176,7 @@ esp_err_t adc_digi_deinitialize(void) free(s_adc_digi_ctx); s_adc_digi_ctx = NULL; - periph_module_disable(PERIPH_SARADC_MODULE); + adc_apb_periph_free(); return ESP_OK; } @@ -319,10 +319,7 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) }; adc_hal_dma_ctx_config(&s_adc_digi_ctx->hal, &config); - //enable ADC digital part - periph_module_enable(PERIPH_SARADC_MODULE); - //reset ADC digital part - periph_module_reset(PERIPH_SARADC_MODULE); + adc_apb_periph_claim(); #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_hal_calibration_init(ADC_UNIT_1); diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index 7ffd58f37c..c72aa0a8bf 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -776,7 +776,7 @@ int adc1_get_raw(adc1_channel_t channel) return ESP_ERR_TIMEOUT; } - periph_module_enable(PERIPH_SARADC_MODULE); + adc_apb_periph_claim(); sar_periph_ctrl_adc_oneshot_power_acquire(); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); @@ -791,7 +791,7 @@ int adc1_get_raw(adc1_channel_t channel) ADC_REG_LOCK_EXIT(); sar_periph_ctrl_adc_oneshot_power_release(); - periph_module_disable(PERIPH_SARADC_MODULE); + adc_apb_periph_free(); adc_lock_release(ADC_UNIT_1); return raw_out; @@ -833,7 +833,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * return ESP_ERR_TIMEOUT; } - periph_module_enable(PERIPH_SARADC_MODULE); + adc_apb_periph_claim(); sar_periph_ctrl_adc_oneshot_power_acquire(); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); @@ -851,7 +851,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * ADC_REG_LOCK_EXIT(); sar_periph_ctrl_adc_oneshot_power_release(); - periph_module_disable(PERIPH_SARADC_MODULE); + adc_apb_periph_free(); adc_lock_release(ADC_UNIT_2); return ret; diff --git a/components/esp_adc/adc_common.c b/components/esp_adc/adc_common.c index 19087aeab5..4f3087abf4 100644 --- a/components/esp_adc/adc_common.c +++ b/components/esp_adc/adc_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,42 +19,6 @@ static const char *TAG = "adc_common"; -static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED; -extern portMUX_TYPE rtc_spinlock; - -/*------------------------------------------------------------------------------ -* For those who use APB_SARADC periph -*----------------------------------------------------------------------------*/ -static int s_adc_digi_ctrlr_cnt; - -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); - } - - portEXIT_CRITICAL(&s_spinlock); -} - -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); - } 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__); - abort(); - } - - portEXIT_CRITICAL(&s_spinlock); -} /*--------------------------------------------------------------- ADC IOs diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 12af5c05c3..5c9cfb7859 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -236,10 +236,7 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi adc_ctx->fsm = ADC_FSM_INIT; *ret_handle = adc_ctx; - //enable ADC digital part - periph_module_enable(PERIPH_SARADC_MODULE); - //reset ADC digital part - periph_module_reset(PERIPH_SARADC_MODULE); + adc_apb_periph_claim(); #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_hal_calibration_init(ADC_UNIT_1); @@ -475,7 +472,7 @@ esp_err_t adc_continuous_deinit(adc_continuous_handle_t handle) free(handle); handle = NULL; - periph_module_disable(PERIPH_SARADC_MODULE); + adc_apb_periph_free(); return ESP_OK; } diff --git a/components/esp_adc/include/esp_private/adc_private.h b/components/esp_adc/include/esp_private/adc_private.h index 03aa22298c..6ebe244bb6 100644 --- a/components/esp_adc/include/esp_private/adc_private.h +++ b/components/esp_adc/include/esp_private/adc_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,23 +16,6 @@ extern "C" { #endif -/*------------------------------------------------------------------------------ -* For those who use APB_SARADC periph -*----------------------------------------------------------------------------*/ -/** - * @brief Claim the usage of the APB_SARADC periph - * - * Reference count inside - */ -void adc_apb_periph_claim(void); - -/** - * @brief Free the usage of the APB_SARADC periph - * - * Reference count inside - */ -void adc_apb_periph_free(void); - /*--------------------------------------------------------------- ADC IOs diff --git a/components/esp_adc/test_apps/adc/main/CMakeLists.txt b/components/esp_adc/test_apps/adc/main/CMakeLists.txt index 7251400011..b24c85a904 100644 --- a/components/esp_adc/test_apps/adc/main/CMakeLists.txt +++ b/components/esp_adc/test_apps/adc/main/CMakeLists.txt @@ -4,9 +4,11 @@ set(srcs "test_app_main.c" "test_adc_driver.c" "test_adc_driver_iram.c" "test_adc_wifi.c" + "test_adc_tsens.c" "test_common_adc.c") # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} + esp_driver_tsens WHOLE_ARCHIVE) diff --git a/components/esp_adc/test_apps/adc/main/test_adc_tsens.c b/components/esp_adc/test_apps/adc/main/test_adc_tsens.c new file mode 100644 index 0000000000..159fa1b7ef --- /dev/null +++ b/components/esp_adc/test_apps/adc/main/test_adc_tsens.c @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "esp_log.h" +#include "soc/adc_periph.h" +#include "esp_adc/adc_oneshot.h" +#include "driver/gpio.h" +#include "driver/rtc_io.h" +#include "driver/temperature_sensor.h" +#include "nvs_flash.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "test_common_adc.h" +#include "test_utils.h" + +#if SOC_TEMP_SENSOR_SUPPORTED && SOC_ADC_SUPPORTED + +static const char *TAG = "adc_tsens"; + +#define EXAMPLE_ADC1_CHAN0 ADC_CHANNEL_2 +#define EXAMPLE_ADC1_CHAN1 ADC_CHANNEL_4 +#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12 + +static int adc_raw[2][10]; + +TEST_CASE("Test temperature sensor cannot be influenced by ADC", "[adc]") +{ + ESP_LOGI(TAG, "Install temperature sensor, expected temp ranger range: 10~50 ℃"); + temperature_sensor_handle_t temp_sensor = NULL; + temperature_sensor_config_t temp_sensor_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(-10, 80); + TEST_ESP_OK(temperature_sensor_install(&temp_sensor_config, &temp_sensor)); + int cnt = 2; + float tsens_value; + while (cnt--) { + temperature_sensor_enable(temp_sensor); + TEST_ESP_OK(temperature_sensor_get_celsius(temp_sensor, &tsens_value)); + ESP_LOGI(TAG, "Temperature value %.02f ℃", tsens_value); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ESP_OK(temperature_sensor_disable(temp_sensor)); + } + + adc_oneshot_unit_handle_t adc1_handle; + adc_oneshot_unit_init_cfg_t init_config1 = { + .unit_id = ADC_UNIT_1, + }; + TEST_ESP_OK(adc_oneshot_new_unit(&init_config1, &adc1_handle)); + + //-------------ADC1 Config---------------// + adc_oneshot_chan_cfg_t config = { + .bitwidth = ADC_BITWIDTH_DEFAULT, + .atten = EXAMPLE_ADC_ATTEN, + }; + TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN0, &config)); + TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config)); + + cnt = 2; + while (cnt--) { + TEST_ESP_OK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0])); + ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw[0][0]); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + TEST_ESP_OK(adc_oneshot_del_unit(adc1_handle)); + + cnt = 2; + while (cnt--) { + temperature_sensor_enable(temp_sensor); + TEST_ESP_OK(temperature_sensor_get_celsius(temp_sensor, &tsens_value)); + ESP_LOGI(TAG, "Temperature value %.02f ℃", tsens_value); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ESP_OK(temperature_sensor_disable(temp_sensor)); + } + + TEST_ESP_OK(temperature_sensor_uninstall(temp_sensor)); +} + +#endif diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c index 57325e8aad..ead87963ea 100644 --- a/components/esp_hw_support/adc_share_hw_ctrl.c +++ b/components/esp_hw_support/adc_share_hw_ctrl.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +28,8 @@ #include "hal/adc_hal_common.h" #include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/sar_periph_ctrl.h" +#include "esp_private/periph_ctrl.h" +#include "soc/periph_defs.h" //For calibration #if CONFIG_IDF_TARGET_ESP32S2 #include "esp_efuse_rtc_table.h" @@ -190,3 +192,39 @@ esp_err_t adc2_wifi_release(void) return ESP_OK; } + +static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED; + +/*------------------------------------------------------------------------------ +* For those who use APB_SARADC periph +*----------------------------------------------------------------------------*/ +static int s_adc_digi_ctrlr_cnt; + +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); + } + + portEXIT_CRITICAL(&s_spinlock); +} + +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); + } 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__); + abort(); + } + + portEXIT_CRITICAL(&s_spinlock); +} 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 4d9de5270c..5bf1084730 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -156,6 +156,24 @@ void adc2_cal_include(void); #define adc2_cal_include() #endif //CONFIG_IDF_TARGET_* +/*------------------------------------------------------------------------------ +* For those who use APB_SARADC periph +*----------------------------------------------------------------------------*/ +/** + * @brief Claim the usage of the APB_SARADC periph + * + * Reference count inside + */ +void adc_apb_periph_claim(void); + +/** + * @brief Free the usage of the APB_SARADC periph + * + * Reference count inside + */ +void adc_apb_periph_free(void); + + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/sar_periph_ctrl_common.c b/components/esp_hw_support/sar_periph_ctrl_common.c index 2d016c4c1b..97c4ccdd69 100644 --- a/components/esp_hw_support/sar_periph_ctrl_common.c +++ b/components/esp_hw_support/sar_periph_ctrl_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "soc/temperature_sensor_periph.h" #include "soc/periph_defs.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/adc_share_hw_ctrl.h" extern __attribute__((unused)) portMUX_TYPE rtc_spinlock; @@ -41,6 +42,9 @@ void temperature_sensor_power_acquire(void) periph_module_reset(PERIPH_TEMPSENSOR_MODULE); regi2c_saradc_enable(); temperature_sensor_ll_clk_enable(true); +#if !SOC_TEMPERATURE_SENSOR_IS_INDEPENDENT_FROM_ADC + adc_apb_periph_claim(); +#endif temperature_sensor_ll_enable(true); } portEXIT_CRITICAL(&rtc_spinlock); @@ -62,6 +66,9 @@ void temperature_sensor_power_release(void) } else if (s_temperature_sensor_power_cnt == 0) { temperature_sensor_ll_clk_enable(false); temperature_sensor_ll_enable(false); +#if !SOC_TEMPERATURE_SENSOR_IS_INDEPENDENT_FROM_ADC + adc_apb_periph_free(); +#endif regi2c_saradc_disable(); periph_module_disable(PERIPH_TEMPSENSOR_MODULE); }