From 6abac38b9c6d82616b37068aad17d4b86263eed5 Mon Sep 17 00:00:00 2001 From: armando Date: Mon, 16 Jun 2025 10:21:06 +0800 Subject: [PATCH] refactor(adc): removed the legacy adc driver and legacy adc calibration calibration driver --- components/driver/CMakeLists.txt | 21 - components/driver/Kconfig | 66 -- components/driver/deprecated/adc1_private.h | 51 - components/driver/deprecated/adc_dma_legacy.c | 677 ------------- .../driver/deprecated/adc_i2s_deprecated.c | 248 ----- components/driver/deprecated/adc_legacy.c | 952 ------------------ components/driver/deprecated/driver/adc.h | 355 ------- .../driver/deprecated/driver/adc_i2s_legacy.h | 51 - .../deprecated/driver/adc_types_legacy.h | 130 --- .../driver/test_apps/.build-test-rules.yml | 14 - .../legacy_adc_driver/CMakeLists.txt | 8 - .../test_apps/legacy_adc_driver/README.md | 2 - .../legacy_adc_driver/main/CMakeLists.txt | 6 - .../legacy_adc_driver/main/test_app_main.c | 40 - .../legacy_adc_driver/main/test_legacy_adc.c | 161 --- .../legacy_adc_driver/pytest_legacy_adc.py | 36 - .../sdkconfig.ci.esp32c2_xtal26m_release | 8 - .../legacy_adc_driver/sdkconfig.ci.release | 5 - .../legacy_adc_driver/sdkconfig.defaults | 3 - components/esp_adc/CMakeLists.txt | 10 +- .../deprecated/esp32/esp_adc_cal_legacy.c | 352 ------- .../deprecated/esp32c3/esp_adc_cal_legacy.c | 175 ---- .../deprecated/esp32s2/esp_adc_cal_legacy.c | 201 ---- .../deprecated/esp32s3/esp_adc_cal_legacy.c | 186 ---- .../deprecated/esp_adc_cal_common_legacy.c | 95 -- .../deprecated/esp_adc_cal_internal_legacy.h | 49 - .../esp_adc/deprecated/include/esp_adc_cal.h | 113 --- .../include/esp_adc_cal_types_legacy.h | 49 - components/esp_adc/sdkconfig.rename | 7 + components/hal/include/hal/adc_types.h | 20 - docs/en/api-guides/performance/size.rst | 2 +- .../peripherals/adc_calibration.rst | 6 +- .../release-5.x/5.0/peripherals.rst | 7 +- .../release-6.x/6.0/peripherals.rst | 9 +- docs/zh_CN/api-guides/performance/size.rst | 2 +- .../peripherals/adc_calibration.rst | 6 +- .../release-5.x/5.0/peripherals.rst | 6 +- .../release-6.x/6.0/peripherals.rst | 8 +- tools/idf_py_actions/hints.yml | 3 + 39 files changed, 43 insertions(+), 4097 deletions(-) delete mode 100644 components/driver/deprecated/adc1_private.h delete mode 100644 components/driver/deprecated/adc_dma_legacy.c delete mode 100644 components/driver/deprecated/adc_i2s_deprecated.c delete mode 100644 components/driver/deprecated/adc_legacy.c delete mode 100644 components/driver/deprecated/driver/adc.h delete mode 100644 components/driver/deprecated/driver/adc_i2s_legacy.h delete mode 100644 components/driver/deprecated/driver/adc_types_legacy.h delete mode 100644 components/driver/test_apps/legacy_adc_driver/CMakeLists.txt delete mode 100644 components/driver/test_apps/legacy_adc_driver/README.md delete mode 100644 components/driver/test_apps/legacy_adc_driver/main/CMakeLists.txt delete mode 100644 components/driver/test_apps/legacy_adc_driver/main/test_app_main.c delete mode 100644 components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c delete mode 100644 components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py delete mode 100644 components/driver/test_apps/legacy_adc_driver/sdkconfig.ci.esp32c2_xtal26m_release delete mode 100644 components/driver/test_apps/legacy_adc_driver/sdkconfig.ci.release delete mode 100644 components/driver/test_apps/legacy_adc_driver/sdkconfig.defaults delete mode 100644 components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c delete mode 100644 components/esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c delete mode 100644 components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c delete mode 100644 components/esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c delete mode 100644 components/esp_adc/deprecated/esp_adc_cal_common_legacy.c delete mode 100644 components/esp_adc/deprecated/esp_adc_cal_internal_legacy.h delete mode 100644 components/esp_adc/deprecated/include/esp_adc_cal.h delete mode 100644 components/esp_adc/deprecated/include/esp_adc_cal_types_legacy.h create mode 100644 components/esp_adc/sdkconfig.rename diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 8bb1696cb5..a90ec57a66 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -16,15 +16,6 @@ set(includes "deprecated" # Always included linker fragments set(ldfragments "") -# ADC related source files (deprecated) -if(CONFIG_SOC_ADC_SUPPORTED) - list(APPEND srcs "deprecated/adc_legacy.c") - - if(CONFIG_SOC_ADC_DMA_SUPPORTED) - list(APPEND srcs "deprecated/adc_dma_legacy.c") - endif() -endif() - # I2C related source files if(CONFIG_SOC_I2C_SUPPORTED) list(APPEND srcs "i2c/i2c.c") @@ -61,18 +52,11 @@ if(CONFIG_SOC_TWAI_SUPPORTED AND NOT CONFIG_SOC_TWAI_SUPPORT_FD) list(APPEND ldfragments "twai/linker.lf") endif() -# Other source files -if(${target} STREQUAL "esp32") - list(APPEND srcs "deprecated/adc_i2s_deprecated.c") -endif() - if(BOOTLOADER_BUILD) # Bootloader shall NOT depend on the drivers idf_component_register() else() # (REQUIRES cannot hide soc headers, since many arguments in the driver headers are chip-dependent) - # (Legacy drivers requires `esp_adc`, due to ADC HW resource mutex logics are there. - # Can be removed together with legacy drivers) idf_component_register(SRCS "${srcs}" INCLUDE_DIRS ${includes} PRIV_REQUIRES efuse esp_timer esp_mm @@ -86,9 +70,4 @@ else() esp_driver_twai LDFRAGMENTS ${ldfragments} ) - if(CONFIG_SOC_ADC_SUPPORTED AND - CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO GCC-366 - set_source_files_properties(deprecated/adc_legacy.c - PROPERTIES COMPILE_FLAGS "-Wno-analyzer-use-of-uninitialized-value") - endif() endif() diff --git a/components/driver/Kconfig b/components/driver/Kconfig index d2e1d4cb91..137973094b 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -2,72 +2,6 @@ menu "Driver Configurations" orsource "./twai/Kconfig.twai" - menu "Legacy ADC Driver Configuration" - - config ADC_DISABLE_DAC - depends on SOC_DAC_SUPPORTED - bool "Disable DAC when ADC2 is used on GPIO 25 and 26" - default y - help - If this is set, the ADC2 driver will disable the output of the DAC corresponding to the specified - channel. This is the default value. - - For testing, disable this option so that we can measure the output of DAC by internal ADC. - - config ADC_SUPPRESS_DEPRECATE_WARN - bool "Suppress legacy driver deprecated warning" - default n - help - Whether to suppress the deprecation warnings when using legacy adc driver (driver/adc.h). - If you want to continue using the legacy driver, and don't want to see related deprecation warnings, - you can enable this option. - - config ADC_SKIP_LEGACY_CONFLICT_CHECK - bool "Skip legacy conflict check" - default n - help - This configuration option allows the user to bypass the conflict check mechanism with legacy code. - menu "Legacy ADC Calibration Configuration" - - config ADC_CAL_EFUSE_TP_ENABLE - depends on IDF_TARGET_ESP32 - bool "Use Two Point Values" - default "y" - help - Some ESP32s have Two Point calibration values burned into eFuse BLOCK3. - This option will allow the ADC calibration component to characterize the - ADC-Voltage curve using Two Point values if they are available. - - config ADC_CAL_EFUSE_VREF_ENABLE - depends on IDF_TARGET_ESP32 - bool "Use eFuse Vref" - default "y" - help - Some ESP32s have Vref burned into eFuse BLOCK0. This option will allow - the ADC calibration component to characterize the ADC-Voltage curve using - eFuse Vref if it is available. - - config ADC_CAL_LUT_ENABLE - depends on IDF_TARGET_ESP32 - bool "Use Lookup Tables" - default "y" - help - This option will allow the ADC calibration component to use Lookup Tables - to correct for non-linear behavior in 11db attenuation. Other attenuations - do not exhibit non-linear behavior hence will not be affected by this option. - - config ADC_CALI_SUPPRESS_DEPRECATE_WARN - bool "Suppress legacy driver deprecated warning" - default n - help - Whether to suppress the deprecation warnings when using legacy adc calibration - driver (esp_adc_cal.h). - If you want to continue using the legacy driver, and don't want to see related - deprecation warnings, you can enable this option. - - endmenu # Legacy ADC Calibration Configuration - endmenu # Legacy ADC Driver Configuration - menu "Legacy MCPWM Driver Configurations" depends on SOC_MCPWM_SUPPORTED config MCPWM_SUPPRESS_DEPRECATE_WARN diff --git a/components/driver/deprecated/adc1_private.h b/components/driver/deprecated/adc1_private.h deleted file mode 100644 index 3b3b703f1d..0000000000 --- a/components/driver/deprecated/adc1_private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "esp_err.h" - -/** - * @brief For I2S dma to claim the usage of ADC1. - * - * Other tasks will be forbidden to use ADC1 between ``adc1_dma_mode_acquire`` and ``adc1_i2s_release``. - * The I2S module may have to wait for a short time for the current conversion (if exist) to finish. - * - * @return - * - ESP_OK success - * - ESP_ERR_TIMEOUT reserved for future use. Currently the function will wait until success. - */ -esp_err_t adc1_dma_mode_acquire(void); - -/** - * @brief For ADC1 to claim the usage of ADC1. - * - * Other tasks will be forbidden to use ADC1 between ``adc1_rtc_mode_acquire`` and ``adc1_i2s_release``. - * The ADC1 may have to wait for some time for the I2S read operation to finish. - * - * @return - * - ESP_OK success - * - ESP_ERR_TIMEOUT reserved for future use. Currently the function will wait until success. - */ -esp_err_t adc1_rtc_mode_acquire(void); - -/** - * @brief to let other tasks use the ADC1 when I2S is not work. - * - * Other tasks will be forbidden to use ADC1 between ``adc1_adc/i2s_mode_acquire`` and ``adc1_i2s_release``. - * Call this function to release the occupation of ADC1 - * - * @return always return ESP_OK. - */ -esp_err_t adc1_lock_release(void); - -#ifdef __cplusplus -} -#endif diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c deleted file mode 100644 index 5e135ca53d..0000000000 --- a/components/driver/deprecated/adc_dma_legacy.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include "sdkconfig.h" -#include "soc/soc_caps.h" -#include "esp_intr_alloc.h" -#include "esp_log.h" -#include "esp_pm.h" -#include "esp_check.h" -#include "sys/lock.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/timers.h" -#include "freertos/ringbuf.h" -#include "esp_private/esp_clk_tree_common.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" -#include "hal/adc_hal_common.h" -#include "esp_private/regi2c_ctrl.h" - -#include "driver/gpio.h" -#include "driver/adc_types_legacy.h" - -//For calibration -#if CONFIG_IDF_TARGET_ESP32S2 -#include "esp_efuse_rtc_table.h" -#elif SOC_ADC_CALIBRATION_V1_SUPPORTED -#include "esp_efuse_rtc_calib.h" -#endif -//For DMA -#if SOC_GDMA_SUPPORTED -#include "esp_private/gdma.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "hal/spi_types.h" -#include "esp_private/spi_common_internal.h" -#elif CONFIG_IDF_TARGET_ESP32 -#include "driver/i2s_types.h" -#include "soc/i2s_periph.h" -#include "esp_private/i2s_platform.h" -#endif - -static const char *ADC_TAG = "ADC"; - -#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel]) - -extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. -#define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) -#define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) - -#define INTERNAL_BUF_NUM 5 - -#if SOC_AHB_GDMA_SUPPORTED -#define ADC_GDMA_HOST 0 -#define ADC_DMA_INTR_MASK GDMA_LL_EVENT_RX_SUC_EOF -#define ADC_DMA_INTR_MASK GDMA_LL_EVENT_RX_SUC_EOF -#define adc_dma_start(adc_dma, addr) gdma_start(s_adc_digi_ctx->rx_dma_channel, (intptr_t)addr) -#define adc_dma_stop(adc_dma) gdma_stop(s_adc_digi_ctx->rx_dma_channel) -#define adc_dma_reset(adc_dma) gdma_reset(s_adc_digi_ctx->rx_dma_channel) -#define adc_dma_clear_intr(adc_dma) -#define adc_dma_enable_intr(adc_dma) -#define adc_dma_disable_intr(adc_dma) -#define adc_dma_deinit(adc_dma) do { \ - gdma_disconnect(s_adc_digi_ctx->rx_dma_channel); \ - gdma_del_channel(s_adc_digi_ctx->rx_dma_channel); \ - } while (0) - -#elif CONFIG_IDF_TARGET_ESP32S2 -#define ADC_DMA_SPI_HOST SPI3_HOST -#define ADC_DMA_INTR_MASK SPI_LL_INTR_IN_SUC_EOF -#define adc_dma_start(adc_dma, addr) spi_dma_ll_rx_start(s_adc_digi_ctx->adc_spi_dev, s_adc_digi_ctx->spi_dma_ctx->rx_dma_chan.chan_id, (lldesc_t *)addr) -#define adc_dma_stop(adc_dma) spi_dma_ll_rx_stop(s_adc_digi_ctx->adc_spi_dev, s_adc_digi_ctx->spi_dma_ctx->rx_dma_chan.chan_id); -#define adc_dma_reset(adc_dma) spi_dma_ll_rx_reset(s_adc_digi_ctx->adc_spi_dev, s_adc_digi_ctx->spi_dma_ctx->rx_dma_chan.chan_id); -#define adc_dma_clear_intr(adc_dma) spi_ll_clear_intr(s_adc_digi_ctx->adc_spi_dev, ADC_DMA_INTR_MASK) -#define adc_dma_enable_intr(adc_dma) spi_ll_enable_intr(s_adc_digi_ctx->adc_spi_dev, ADC_DMA_INTR_MASK); -#define adc_dma_disable_intr(adc_dma) spi_ll_disable_intr(s_adc_digi_ctx->adc_spi_dev, ADC_DMA_INTR_MASK); -#define adc_dma_deinit(adc_dma) do { \ - esp_intr_free(s_adc_digi_ctx->intr_hdl); \ - spicommon_dma_chan_free(s_adc_digi_ctx->spi_dma_ctx); \ - spicommon_periph_free(ADC_DMA_SPI_HOST); \ - } while (0) - -#elif CONFIG_IDF_TARGET_ESP32 -#define ADC_DMA_I2S_HOST I2S_NUM_0 -#define ADC_DMA_INTR_MASK BIT(9) -#define adc_dma_start(adc_dma, addr) do { \ - i2s_ll_enable_dma(s_adc_digi_ctx->adc_i2s_dev, true); \ - i2s_ll_rx_start_link(s_adc_digi_ctx->adc_i2s_dev, (uint32_t)addr); \ - } while (0) -#define adc_dma_stop(adc_dma) i2s_ll_rx_stop_link(s_adc_digi_ctx->adc_i2s_dev); -#define adc_dma_reset(adc_dma) i2s_ll_rx_reset_dma(s_adc_digi_ctx->adc_i2s_dev); -#define adc_dma_clear_intr(adc_dma) i2s_ll_clear_intr_status(s_adc_digi_ctx->adc_i2s_dev, ADC_DMA_INTR_MASK); -#define adc_dma_enable_intr(adc_dma) i2s_ll_enable_intr(s_adc_digi_ctx->adc_i2s_dev, ADC_DMA_INTR_MASK, true); -#define adc_dma_disable_intr(adc_dma) i2s_ll_enable_intr(s_adc_digi_ctx->adc_i2s_dev, ADC_DMA_INTR_MASK, false); -#define adc_dma_deinit(adc_dma) do { \ - esp_intr_free(s_adc_digi_ctx->intr_hdl); \ - i2s_platform_release_occupation(I2S_CTLR_HP, ADC_DMA_I2S_HOST); \ - } while (0) -#endif - -/*--------------------------------------------------------------- - Digital Controller Context ----------------------------------------------------------------*/ -typedef struct adc_digi_context_t { - uint8_t *rx_dma_buf; //dma buffer - adc_hal_dma_ctx_t hal; //hal context -#if SOC_GDMA_SUPPORTED - gdma_channel_handle_t rx_dma_channel; //dma rx channel handle -#elif CONFIG_IDF_TARGET_ESP32S2 - spi_host_device_t spi_host; //ADC uses this SPI DMA - spi_dma_ctx_t *spi_dma_ctx; //spi_dma context - intr_handle_t intr_hdl; //Interrupt handler - spi_dev_t *adc_spi_dev ; -#elif CONFIG_IDF_TARGET_ESP32 - i2s_port_t i2s_host; //ADC uses this I2S DMA - intr_handle_t intr_hdl; //Interrupt handler - i2s_dev_t *adc_i2s_dev; -#endif - RingbufHandle_t ringbuf_hdl; //RX ringbuffer handler - intptr_t rx_eof_desc_addr; //eof descriptor address of RX channel - bool ringbuf_overflow_flag; //1: ringbuffer overflow - bool driver_start_flag; //1: driver is started; 0: driver is stopped - bool use_adc1; //1: ADC unit1 will be used; 0: ADC unit1 won't be used. - bool use_adc2; //1: ADC unit2 will be used; 0: ADC unit2 won't be used. This determines whether to acquire sar_adc2_mutex lock or not. - adc_atten_t adc1_atten; //Attenuation for ADC1. On this chip each ADC can only support one attenuation. - adc_atten_t adc2_atten; //Attenuation for ADC2. On this chip each ADC can only support one attenuation. - adc_hal_digi_ctrlr_cfg_t hal_digi_ctrlr_cfg; //Hal digital controller configuration - esp_pm_lock_handle_t pm_lock; //For power management -} adc_digi_context_t; - -static adc_digi_context_t *s_adc_digi_ctx = NULL; -#ifdef CONFIG_PM_ENABLE -//Only for deprecated API -extern esp_pm_lock_handle_t adc_digi_arbiter_lock; -#endif //CONFIG_PM_ENABLE - -/*--------------------------------------------------------------- - ADC Continuous Read Mode (via DMA) ----------------------------------------------------------------*/ -//Function to address transaction -static bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx); - -#if SOC_GDMA_SUPPORTED -static bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data); -#else -static void adc_dma_intr_handler(void *arg); -#endif - -static int8_t adc_digi_get_io_num(adc_unit_t adc_unit, uint8_t adc_channel) -{ - assert(adc_unit < SOC_ADC_PERIPH_NUM); - uint8_t adc_n = (adc_unit == ADC_UNIT_1) ? 0 : 1; - return adc_channel_io_map[adc_n][adc_channel]; -} - -static esp_err_t adc_digi_gpio_init(adc_unit_t adc_unit, uint16_t channel_mask) -{ - esp_err_t ret = ESP_OK; - uint64_t gpio_mask = 0; - uint32_t n = 0; - int8_t io = 0; - - while (channel_mask) { - if (channel_mask & 0x1) { - io = adc_digi_get_io_num(adc_unit, n); - if (io < 0) { - return ESP_ERR_INVALID_ARG; - } - gpio_mask |= BIT64(io); - } - channel_mask = channel_mask >> 1; - n++; - } - - gpio_config_t cfg = { - .pin_bit_mask = gpio_mask, - .mode = GPIO_MODE_DISABLE, - }; - ret = gpio_config(&cfg); - - return ret; -} - -esp_err_t adc_digi_deinitialize(void) -{ - if (!s_adc_digi_ctx) { - return ESP_ERR_INVALID_STATE; - } - - if (s_adc_digi_ctx->driver_start_flag != 0) { - ESP_LOGE(ADC_TAG, "The driver is not stopped"); - return ESP_ERR_INVALID_STATE; - } - - if (s_adc_digi_ctx->ringbuf_hdl) { - vRingbufferDelete(s_adc_digi_ctx->ringbuf_hdl); - s_adc_digi_ctx->ringbuf_hdl = NULL; - } - -#if CONFIG_PM_ENABLE - if (s_adc_digi_ctx->pm_lock) { - esp_pm_lock_delete(s_adc_digi_ctx->pm_lock); - } -#endif //CONFIG_PM_ENABLE - - ANALOG_CLOCK_DISABLE(); - - free(s_adc_digi_ctx->rx_dma_buf); - free(s_adc_digi_ctx->hal.rx_desc); - free(s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern); - - adc_dma_deinit(s_adc_digi_ctx); - free(s_adc_digi_ctx); - s_adc_digi_ctx = NULL; - - adc_apb_periph_free(); - - return ESP_OK; -} - -esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) -{ - esp_err_t ret = ESP_OK; - ESP_RETURN_ON_FALSE((init_config->conv_num_each_intr % SOC_ADC_DIGI_DATA_BYTES_PER_CONV == 0), ESP_ERR_INVALID_ARG, ADC_TAG, "conv_frame_size should be in multiples of `SOC_ADC_DIGI_DATA_BYTES_PER_CONV`"); - - s_adc_digi_ctx = calloc(1, sizeof(adc_digi_context_t)); - if (s_adc_digi_ctx == NULL) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - - //ringbuffer - s_adc_digi_ctx->ringbuf_hdl = xRingbufferCreate(init_config->max_store_buf_size, RINGBUF_TYPE_BYTEBUF); - if (!s_adc_digi_ctx->ringbuf_hdl) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - - //malloc internal buffer used by DMA - s_adc_digi_ctx->rx_dma_buf = heap_caps_calloc(1, init_config->conv_num_each_intr * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); - if (!s_adc_digi_ctx->rx_dma_buf) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - - //malloc dma descriptor - uint32_t dma_desc_num_per_frame = (init_config->conv_num_each_intr + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; - uint32_t dma_desc_max_num = dma_desc_num_per_frame * INTERNAL_BUF_NUM; - s_adc_digi_ctx->hal.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * dma_desc_max_num, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); - if (!s_adc_digi_ctx->hal.rx_desc) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - - //malloc pattern table - s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern = calloc(1, SOC_ADC_PATT_LEN_MAX * sizeof(adc_digi_pattern_config_t)); - if (!s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - -#if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &s_adc_digi_ctx->pm_lock); - if (ret != ESP_OK) { - goto cleanup; - } -#endif //CONFIG_PM_ENABLE - - //init gpio pins - if (init_config->adc1_chan_mask) { - ret = adc_digi_gpio_init(ADC_UNIT_1, init_config->adc1_chan_mask); - if (ret != ESP_OK) { - goto cleanup; - } - } - if (init_config->adc2_chan_mask) { - ret = adc_digi_gpio_init(ADC_UNIT_2, init_config->adc2_chan_mask); - if (ret != ESP_OK) { - goto cleanup; - } - } - -#if SOC_GDMA_SUPPORTED - //alloc rx gdma channel - gdma_channel_alloc_config_t rx_alloc_config = { - .direction = GDMA_CHANNEL_DIRECTION_RX, - }; - ret = gdma_new_ahb_channel(&rx_alloc_config, &s_adc_digi_ctx->rx_dma_channel); - if (ret != ESP_OK) { - goto cleanup; - } - gdma_connect(s_adc_digi_ctx->rx_dma_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_ADC, 0)); - - gdma_strategy_config_t strategy_config = { - .auto_update_desc = true, - .owner_check = true - }; - gdma_apply_strategy(s_adc_digi_ctx->rx_dma_channel, &strategy_config); - - gdma_rx_event_callbacks_t cbs = { - .on_recv_eof = adc_dma_in_suc_eof_callback - }; - gdma_register_rx_event_callbacks(s_adc_digi_ctx->rx_dma_channel, &cbs, s_adc_digi_ctx); - -#elif CONFIG_IDF_TARGET_ESP32S2 - //ADC utilises SPI3 DMA on ESP32S2 - bool spi_success = false; - - spi_success = spicommon_periph_claim(ADC_DMA_SPI_HOST, "adc"); - ret = spicommon_dma_chan_alloc(ADC_DMA_SPI_HOST, SPI_DMA_CH_AUTO, &(s_adc_digi_ctx->spi_dma_ctx)); - if (ret != ESP_OK || spi_success != ESP_OK) { - goto cleanup; - } - if (!spi_success || (s_adc_digi_ctx->spi_host != ADC_DMA_SPI_HOST)) { - goto cleanup; - } - - ret = esp_intr_alloc(spicommon_irqdma_source_for_host(ADC_DMA_SPI_HOST), 0, adc_dma_intr_handler, - (void *)s_adc_digi_ctx, &s_adc_digi_ctx->intr_hdl); - if (ret != ESP_OK) { - goto cleanup; - } - s_adc_digi_ctx->adc_spi_dev = SPI_LL_GET_HW(ADC_DMA_SPI_HOST); -#elif CONFIG_IDF_TARGET_ESP32 - //ADC utilises I2S0 DMA on ESP32 - ret = i2s_platform_acquire_occupation(I2S_CTLR_HP, ADC_DMA_I2S_HOST, "adc"); - if (ret != ESP_OK) { - ret = ESP_ERR_NOT_FOUND; - goto cleanup; - } - - s_adc_digi_ctx->i2s_host = I2S_NUM_0; - - ret = esp_intr_alloc(i2s_periph_signal[ADC_DMA_I2S_HOST].irq, 0, adc_dma_intr_handler, - (void *)s_adc_digi_ctx, &s_adc_digi_ctx->intr_hdl); - if (ret != ESP_OK) { - goto cleanup; - } - s_adc_digi_ctx->adc_i2s_dev = I2S_LL_GET_HW(ADC_DMA_I2S_HOST); -#endif - - adc_hal_dma_config_t config = { - .eof_desc_num = INTERNAL_BUF_NUM, - .eof_step = dma_desc_num_per_frame, - .eof_num = init_config->conv_num_each_intr / SOC_ADC_DIGI_DATA_BYTES_PER_CONV - }; - adc_hal_dma_ctx_config(&s_adc_digi_ctx->hal, &config); - - adc_apb_periph_claim(); - - ANALOG_CLOCK_ENABLE(); - -#if SOC_ADC_CALIBRATION_V1_SUPPORTED - adc_hal_calibration_init(ADC_UNIT_1); - adc_hal_calibration_init(ADC_UNIT_2); -#endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED - - return ret; - -cleanup: - adc_digi_deinitialize(); - return ret; -} - -#if SOC_GDMA_SUPPORTED -static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) -{ - assert(event_data); - s_adc_digi_ctx->rx_eof_desc_addr = event_data->rx_eof_desc_addr; - return s_adc_dma_intr(user_data); -} -#else -static IRAM_ATTR void adc_dma_intr_handler(void *arg) -{ - adc_digi_context_t *ctx = (adc_digi_context_t *)arg; - bool need_yield = false; - -#if CONFIG_IDF_TARGET_ESP32S2 - bool conversion_finish = spi_ll_get_intr(s_adc_digi_ctx->adc_spi_dev, ADC_DMA_INTR_MASK); - if (conversion_finish) { - spi_ll_clear_intr(s_adc_digi_ctx->adc_spi_dev, ADC_DMA_INTR_MASK); - intptr_t desc_addr = spi_dma_ll_get_in_suc_eof_desc_addr(s_adc_digi_ctx->adc_spi_dev, s_adc_digi_ctx->spi_dma_ctx->rx_dma_chan.chan_id); - ctx->rx_eof_desc_addr = desc_addr; - need_yield = s_adc_dma_intr(ctx); - } -#elif CONFIG_IDF_TARGET_ESP32 - bool conversion_finish = i2s_ll_get_intr_status(s_adc_digi_ctx->adc_i2s_dev) & ADC_DMA_INTR_MASK; - if (conversion_finish) { - i2s_ll_clear_intr_status(s_adc_digi_ctx->adc_i2s_dev, ADC_DMA_INTR_MASK); - uint32_t desc_addr; - i2s_ll_rx_get_eof_des_addr(s_adc_digi_ctx->adc_i2s_dev, &desc_addr); - ctx->rx_eof_desc_addr = (intptr_t)desc_addr; - need_yield = s_adc_dma_intr(ctx); - } -#endif - if (need_yield) { - portYIELD_FROM_ISR(); - } -} -#endif - -static IRAM_ATTR bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx) -{ - BaseType_t taskAwoken = 0; - BaseType_t ret; - adc_hal_dma_desc_status_t status = false; - uint8_t *finished_buffer = NULL; - uint32_t finished_size = 0; - - while (1) { - status = adc_hal_get_reading_result(&adc_digi_ctx->hal, adc_digi_ctx->rx_eof_desc_addr, &finished_buffer, &finished_size); - if (status != ADC_HAL_DMA_DESC_VALID) { - break; - } - - ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, finished_buffer, finished_size, &taskAwoken); - if (ret == pdFALSE) { - //ringbuffer overflow - adc_digi_ctx->ringbuf_overflow_flag = 1; - } - } - - return (taskAwoken == pdTRUE); -} - -esp_err_t adc_digi_start(void) -{ - - if (s_adc_digi_ctx->driver_start_flag != 0) { - ESP_LOGE(ADC_TAG, "The driver is already started"); - return ESP_ERR_INVALID_STATE; - } - //reset ADC digital part to reset ADC sampling EOF counter - 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; - s_adc_digi_ctx->driver_start_flag = 1; - if (s_adc_digi_ctx->use_adc1) { - adc_lock_acquire(ADC_UNIT_1); - } - if (s_adc_digi_ctx->use_adc2) { - adc_lock_acquire(ADC_UNIT_2); - } - -#if CONFIG_PM_ENABLE - // Lock APB frequency while ADC driver is in use - esp_pm_lock_acquire(s_adc_digi_ctx->pm_lock); -#endif - -#if SOC_ADC_CALIBRATION_V1_SUPPORTED - if (s_adc_digi_ctx->use_adc1) { - adc_set_hw_calibration_code(ADC_UNIT_1, s_adc_digi_ctx->adc1_atten); - } - if (s_adc_digi_ctx->use_adc2) { - adc_set_hw_calibration_code(ADC_UNIT_2, s_adc_digi_ctx->adc2_atten); - } -#endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED - -#if SOC_ADC_ARBITER_SUPPORTED - adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); - adc_hal_arbiter_config(&config); -#endif //#if SOC_ADC_ARBITER_SUPPORTED - - adc_hal_set_controller(ADC_UNIT_1, ADC_HAL_CONTINUOUS_READ_MODE); - adc_hal_set_controller(ADC_UNIT_2, ADC_HAL_CONTINUOUS_READ_MODE); - - adc_hal_digi_init(&s_adc_digi_ctx->hal); -#if !CONFIG_IDF_TARGET_ESP32 - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), true)); -#endif - adc_hal_digi_controller_config(&s_adc_digi_ctx->hal, &s_adc_digi_ctx->hal_digi_ctrlr_cfg); - - adc_dma_stop(s_adc_digi_ctx); - adc_hal_digi_connect(false); - - adc_dma_reset(s_adc_digi_ctx); - adc_hal_digi_reset(); - adc_hal_digi_dma_link(&s_adc_digi_ctx->hal, s_adc_digi_ctx->rx_dma_buf); - - adc_dma_start(s_adc_digi_ctx, s_adc_digi_ctx->hal.rx_desc); - adc_hal_digi_connect(true); - adc_hal_digi_enable(true); - - return ESP_OK; -} - -esp_err_t adc_digi_stop(void) -{ - if (s_adc_digi_ctx->driver_start_flag != 1) { - ESP_LOGE(ADC_TAG, "The driver is already stopped"); - return ESP_ERR_INVALID_STATE; - } - s_adc_digi_ctx->driver_start_flag = 0; - - adc_dma_stop(s_adc_digi_ctx); - adc_hal_digi_enable(false); - adc_hal_digi_connect(false); - - adc_hal_digi_deinit(); - -#if CONFIG_PM_ENABLE - if (s_adc_digi_ctx->pm_lock) { - esp_pm_lock_release(s_adc_digi_ctx->pm_lock); - } -#endif //CONFIG_PM_ENABLE - - if (s_adc_digi_ctx->use_adc2) { - adc_lock_release(ADC_UNIT_2); - } - if (s_adc_digi_ctx->use_adc1) { - adc_lock_release(ADC_UNIT_1); - } - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), false)); - sar_periph_ctrl_adc_continuous_power_release(); - - return ESP_OK; -} - -esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_length, uint32_t timeout_ms) -{ - TickType_t ticks_to_wait; - esp_err_t ret = ESP_OK; - uint8_t *data = NULL; - size_t size = 0; - - ticks_to_wait = timeout_ms / portTICK_PERIOD_MS; - if (timeout_ms == ADC_MAX_DELAY) { - ticks_to_wait = portMAX_DELAY; - } - - data = xRingbufferReceiveUpTo(s_adc_digi_ctx->ringbuf_hdl, &size, ticks_to_wait, length_max); - if (!data) { - ESP_LOGV(ADC_TAG, "No data, increase timeout or reduce conv_num_each_intr"); - ret = ESP_ERR_TIMEOUT; - *out_length = 0; - return ret; - } - - memcpy(buf, data, size); - vRingbufferReturnItem(s_adc_digi_ctx->ringbuf_hdl, data); - assert((size % 4) == 0); - *out_length = size; - - if (s_adc_digi_ctx->ringbuf_overflow_flag) { - ret = ESP_ERR_INVALID_STATE; - } - - return ret; -} - -/*--------------------------------------------------------------- - Digital controller setting ----------------------------------------------------------------*/ -esp_err_t adc_digi_controller_configure(const adc_digi_configuration_t *config) -{ - if (!s_adc_digi_ctx) { - return ESP_ERR_INVALID_STATE; - } - - //Pattern related check - ESP_RETURN_ON_FALSE(config->pattern_num <= SOC_ADC_PATT_LEN_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "Max pattern num is %d", SOC_ADC_PATT_LEN_MAX); -#if CONFIG_IDF_TARGET_ESP32 - for (int i = 0; i < config->pattern_num; i++) { - ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width >= SOC_ADC_DIGI_MIN_BITWIDTH && config->adc_pattern->bit_width <= SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported"); - ESP_RETURN_ON_FALSE(config->adc_pattern[i].unit == 0, ESP_ERR_INVALID_ARG, ADC_TAG, "Only support using ADC1 DMA mode"); - } -#else - for (int i = 0; i < config->pattern_num; i++) { - ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width == SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported"); - } -#endif - ESP_RETURN_ON_FALSE(config->sample_freq_hz <= SOC_ADC_SAMPLE_FREQ_THRES_HIGH && config->sample_freq_hz >= SOC_ADC_SAMPLE_FREQ_THRES_LOW, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC sampling frequency out of range"); - -#if CONFIG_IDF_TARGET_ESP32 - ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE1, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type1"); -#elif CONFIG_IDF_TARGET_ESP32S2 - if (config->conv_mode == ADC_CONV_BOTH_UNIT || config->conv_mode == ADC_CONV_ALTER_UNIT) { - ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE2, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type2"); - } else if (config->conv_mode == ADC_CONV_SINGLE_UNIT_1 || config->conv_mode == ADC_CONV_SINGLE_UNIT_2) { - ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE1, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type1"); - } -#else - ESP_RETURN_ON_FALSE(config->format == ADC_DIGI_OUTPUT_FORMAT_TYPE2, ESP_ERR_INVALID_ARG, ADC_TAG, "Please use type2"); -#endif - - s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern_len = config->pattern_num; - s_adc_digi_ctx->hal_digi_ctrlr_cfg.sample_freq_hz = config->sample_freq_hz; - s_adc_digi_ctx->hal_digi_ctrlr_cfg.conv_mode = config->conv_mode; - memcpy(s_adc_digi_ctx->hal_digi_ctrlr_cfg.adc_pattern, config->adc_pattern, config->pattern_num * sizeof(adc_digi_pattern_config_t)); - - const int atten_uninitialized = 999; - s_adc_digi_ctx->adc1_atten = atten_uninitialized; - s_adc_digi_ctx->adc2_atten = atten_uninitialized; - s_adc_digi_ctx->use_adc1 = 0; - s_adc_digi_ctx->use_adc2 = 0; - for (int i = 0; i < config->pattern_num; i++) { - const adc_digi_pattern_config_t *pat = &config->adc_pattern[i]; - if (pat->unit == ADC_UNIT_1) { - s_adc_digi_ctx->use_adc1 = 1; - - if (s_adc_digi_ctx->adc1_atten == atten_uninitialized) { - s_adc_digi_ctx->adc1_atten = pat->atten; - } else if (s_adc_digi_ctx->adc1_atten != pat->atten) { - return ESP_ERR_INVALID_ARG; - } - } else if (pat->unit == ADC_UNIT_2) { - //See whether ADC2 will be used or not. If yes, the ``sar_adc2_mutex`` should be acquired in the continuous read driver - s_adc_digi_ctx->use_adc2 = 1; - - if (s_adc_digi_ctx->adc2_atten == atten_uninitialized) { - s_adc_digi_ctx->adc2_atten = pat->atten; - } else if (s_adc_digi_ctx->adc2_atten != pat->atten) { - return ESP_ERR_INVALID_ARG; - } - } - } - - return ESP_OK; -} - -#if !CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK -/** - * @brief This function will be called during start up, to check that adc_continuous driver is not running along with the legacy adc_continuous driver - */ -__attribute__((constructor)) -static void check_adc_continuous_driver_conflict(void) -{ - // This function was declared as weak here. adc_continuous driver has one implementation. - // So if adc_continuous driver is not linked in, then `adc_continuous_new_handle` should be NULL at runtime. - extern __attribute__((weak)) esp_err_t adc_continuous_new_handle(const void *init_config, void **ret_handle); - if ((void *)adc_continuous_new_handle != NULL) { - ESP_EARLY_LOGE(ADC_TAG, "CONFLICT! driver_ng is not allowed to be used with the legacy driver"); - abort(); - } - ESP_EARLY_LOGW(ADC_TAG, "legacy driver is deprecated, please migrate to `esp_adc/adc_continuous.h`"); -} -#endif //CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK - -#if SOC_ADC_CALIBRATION_V1_SUPPORTED -/*--------------------------------------------------------------- - ADC Hardware Calibration ----------------------------------------------------------------*/ -static __attribute__((constructor)) void adc_hw_calibration(void) -{ - //Calculate all ICode - for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) { - adc_hal_calibration_init(i); - for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) { - /** - * This may get wrong when attenuations are NOT consecutive on some chips, - * update this when bringing up the calibration on that chip - */ - adc_calc_hw_calibration_code(i, j); -#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED - /* Load the channel compensation from efuse */ - for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) { - adc_load_hw_calibration_chan_compens(i, k, j); - } -#endif - } - } -} -#endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED diff --git a/components/driver/deprecated/adc_i2s_deprecated.c b/components/driver/deprecated/adc_i2s_deprecated.c deleted file mode 100644 index 7e1cd1f318..0000000000 --- a/components/driver/deprecated/adc_i2s_deprecated.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/*---------------------------------------------------------------------------------- - This file contains ESP32 and ESP32S2 Deprecated ADC APIs and functions ------------------------------------------------------------------------------------*/ - -#include "sdkconfig.h" -#include "esp_types.h" -#include "esp_log.h" -#include "esp_intr_alloc.h" -#include "driver/rtc_io.h" -#include "hal/adc_ll.h" -#include "hal/adc_types.h" -#ifdef CONFIG_PM_ENABLE -#include "esp_pm.h" -#endif -#include "freertos/FreeRTOS.h" - -#include "driver/adc_i2s_legacy.h" -#include "driver/adc_types_legacy.h" - -static __attribute__((unused)) const char *ADC_TAG = "ADC"; - -#define ADC_CHECK_RET(fun_ret) ({ \ - if (fun_ret != ESP_OK) { \ - ESP_LOGE(ADC_TAG,"%s:%d",__FUNCTION__,__LINE__); \ - return ESP_FAIL; \ - } \ -}) - -#define ADC_CHECK(a, str, ret_val) ({ \ - if (!(a)) { \ - ESP_LOGE(ADC_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \ - return (ret_val); \ - } \ -}) - -#define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG) -#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel]) - -extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. -#define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) -#define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) - -#ifdef CONFIG_PM_ENABLE -esp_pm_lock_handle_t adc_digi_arbiter_lock = NULL; -#endif //CONFIG_PM_ENABLE - -#if CONFIG_IDF_TARGET_ESP32 -/*--------------------------------------------------------------- - ESP32 Deprecated ADC APIs and functions ----------------------------------------------------------------*/ -#define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIGI_FORMAT_12BIT) -#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_12) -#define DIG_ADC_BIT_WIDTH_DEFUALT (3) //3 for ADC_WIDTH_BIT_12 - -/** - * @brief ADC digital controller (DMA mode) conversion rules setting. - */ -typedef struct { - union { - struct { - uint8_t atten: 2; /*!< ADC sampling voltage attenuation configuration. Modification of attenuation affects the range of measurements. - 0: measurement range 0 - 800mV, - 1: measurement range 0 - 1100mV, - 2: measurement range 0 - 1350mV, - 3: measurement range 0 - 2600mV. */ - uint8_t bit_width: 2; /*!< ADC resolution. -- 0: 9 bit; -- 1: 10 bit; -- 2: 11 bit; -- 3: 12 bit. */ - int8_t channel: 4; /*!< ADC channel index. */ - }; - uint8_t val; /*!> offset)); // clear old data - tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data - SYSCON.saradc_sar1_patt_tab[index] = tab; // Write back - } else { // adc_n == ADC_UNIT_2 - tab = SYSCON.saradc_sar2_patt_tab[index]; // Read old register value - tab &= (~(0xFF000000 >> offset)); // clear old data - tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data - SYSCON.saradc_sar2_patt_tab[index] = tab; // Write back - } -} - -static void adc_digi_controller_reg_set(const adc_digi_config_t *cfg) -{ - /* On ESP32, only support ADC1 */ - switch (cfg->conv_mode) { - case ADC_CONV_SINGLE_UNIT_1: - adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ONLY_ADC1); - break; - case ADC_CONV_SINGLE_UNIT_2: - adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ONLY_ADC2); - break; - case ADC_CONV_BOTH_UNIT: - adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_BOTH_UNIT); - break; - case ADC_CONV_ALTER_UNIT: - adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ALTER_UNIT); - break; - default: - abort(); - } - - if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) { - adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_DIG); - if (cfg->adc1_pattern_len) { - adc_ll_digi_clear_pattern_table(ADC_UNIT_1); - adc_ll_digi_set_pattern_table_len(ADC_UNIT_1, cfg->adc1_pattern_len); - for (uint32_t i = 0; i < cfg->adc1_pattern_len; i++) { - adc_ll_digi_prepare_pattern_table(ADC_UNIT_1, i, cfg->adc1_pattern[i]); - } - } - } - if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) { - adc_ll_set_controller(ADC_UNIT_2, ADC_LL_CTRL_DIG); - if (cfg->adc2_pattern_len) { - adc_ll_digi_clear_pattern_table(ADC_UNIT_2); - adc_ll_digi_set_pattern_table_len(ADC_UNIT_2, cfg->adc2_pattern_len); - for (uint32_t i = 0; i < cfg->adc2_pattern_len; i++) { - adc_ll_digi_prepare_pattern_table(ADC_UNIT_2, i, cfg->adc2_pattern[i]); - } - } - } - adc_ll_digi_set_output_format(cfg->format); - adc_ll_digi_convert_limit_enable(ADC_LL_DEFAULT_CONV_LIMIT_EN); - adc_ll_digi_set_convert_limit_num(ADC_LL_DEFAULT_CONV_LIMIT_NUM); - adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_ADC); -} - -esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src) -{ - ADC_CHECK((src == ADC_I2S_DATA_SRC_IO_SIG || src == ADC_I2S_DATA_SRC_ADC), "ADC i2s data source error", ESP_ERR_INVALID_ARG); - ADC_ENTER_CRITICAL(); - adc_ll_digi_set_data_source(src); - ADC_EXIT_CRITICAL(); - return ESP_OK; -} - -extern esp_err_t adc_common_gpio_init(adc_unit_t adc_unit, adc_channel_t channel); -esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel) -{ - if (adc_unit == ADC_UNIT_1) { - ADC_CHANNEL_CHECK(ADC_UNIT_1, channel); - } else if (adc_unit == ADC_UNIT_2) { - //ADC2 does not support DMA mode - ADC_CHECK(false, "ADC2 not support DMA for now.", ESP_ERR_INVALID_ARG); - ADC_CHANNEL_CHECK(ADC_UNIT_2, channel); - } - - adc_digi_pattern_table_t adc1_pattern[1]; - adc_digi_pattern_table_t adc2_pattern[1]; - adc_digi_config_t dig_cfg = { - .format = DIG_ADC_OUTPUT_FORMAT_DEFUALT, - .conv_mode = ADC_CONV_SINGLE_UNIT_1, - }; - - if (adc_unit == ADC_UNIT_1) { - adc1_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT; - adc1_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT; - adc1_pattern[0].channel = channel; - dig_cfg.adc1_pattern_len = 1; - dig_cfg.adc1_pattern = adc1_pattern; - } else if (adc_unit == ADC_UNIT_2) { - adc2_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT; - adc2_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT; - adc2_pattern[0].channel = channel; - dig_cfg.adc2_pattern_len = 1; - dig_cfg.adc2_pattern = adc2_pattern; - } - adc_common_gpio_init(adc_unit, channel); - ADC_ENTER_CRITICAL(); - adc_ll_digi_set_fsm_time(ADC_LL_FSM_RSTB_WAIT_DEFAULT, ADC_LL_FSM_START_WAIT_DEFAULT, - ADC_LL_FSM_STANDBY_WAIT_DEFAULT); - adc_ll_set_sample_cycle(ADC_LL_SAMPLE_CYCLE_DEFAULT); - adc_ll_pwdet_set_cct(ADC_LL_PWDET_CCT_DEFAULT); - adc_ll_digi_output_invert(ADC_UNIT_1, ADC_LL_DIGI_DATA_INVERT_DEFAULT(ADC_UNIT_1)); - adc_ll_digi_output_invert(ADC_UNIT_2, ADC_LL_DIGI_DATA_INVERT_DEFAULT(ADC_UNIT_2)); - adc_ll_digi_set_clk_div(ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT); - adc_digi_controller_reg_set(&dig_cfg); - ADC_EXIT_CRITICAL(); - - return ESP_OK; -} - -#endif //#if CONFIG_IDF_TARGET_ESP32 diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c deleted file mode 100644 index e331e0c30e..0000000000 --- a/components/driver/deprecated/adc_legacy.c +++ /dev/null @@ -1,952 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include "sdkconfig.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/timers.h" -#include "esp_log.h" -#include "esp_check.h" -#include "esp_pm.h" -#include "soc/rtc.h" -#include "soc/soc_caps.h" -#include "esp_private/gpio.h" -#include "sys/lock.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" -#include "hal/adc_ll.h" -#include "hal/adc_hal_common.h" -#include "esp_private/esp_clk_tree_common.h" -#include "esp_private/regi2c_ctrl.h" -#include "esp_private/periph_ctrl.h" -#include "driver/adc_types_legacy.h" -#include "esp_clk_tree.h" - -#if SOC_DAC_SUPPORTED -#include "hal/dac_types.h" -#include "hal/dac_ll.h" -#endif - -#if CONFIG_IDF_TARGET_ESP32S3 -#include "esp_efuse_rtc_calib.h" -#endif - -static const char *ADC_TAG = "ADC"; - -#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel]) - -//////////////////////// Locks /////////////////////////////////////////// -extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. - -#define RTC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) -#define RTC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) -#define DIGI_ENTER_CRITICAL() -#define DIGI_EXIT_CRITICAL() - -#define ADC_POWER_ENTER() RTC_ENTER_CRITICAL() -#define ADC_POWER_EXIT() RTC_EXIT_CRITICAL() - -#define DIGI_CONTROLLER_ENTER() DIGI_ENTER_CRITICAL() -#define DIGI_CONTROLLER_EXIT() DIGI_EXIT_CRITICAL() - -#define SARADC1_ENTER() RTC_ENTER_CRITICAL() -#define SARADC1_EXIT() RTC_EXIT_CRITICAL() - -#define SARADC2_ENTER() RTC_ENTER_CRITICAL() -#define SARADC2_EXIT() RTC_EXIT_CRITICAL() - -//n stands for ADC unit: 1 for ADC1 and 2 for ADC2. Currently both unit touches the same registers -#define VREF_ENTER(n) RTC_ENTER_CRITICAL() -#define VREF_EXIT(n) RTC_EXIT_CRITICAL() - -#define FSM_ENTER() RTC_ENTER_CRITICAL() -#define FSM_EXIT() RTC_EXIT_CRITICAL() - -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4 -//prevent ADC1 being used by I2S dma and other tasks at the same time. -static _lock_t adc1_dma_lock; -#define SARADC1_ACQUIRE() _lock_acquire( &adc1_dma_lock ) -#define SARADC1_RELEASE() _lock_release( &adc1_dma_lock ) -#endif - -/* -In ADC2, there're two locks used for different cases: -1. lock shared with app and Wi-Fi: - ESP32: - When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed. - ESP32S2: - The controller's control over the ADC is determined by the arbiter. There is no need to control by lock. - -2. lock shared between tasks: - when several tasks sharing the ADC2, we want to guarantee - all the requests will be handled. - Since conversions are short (about 31us), app returns the lock very soon, - we use a spinlock to stand there waiting to do conversions one by one. - -adc2_spinlock should be acquired first, then call `adc_lock_release(ADC_UNIT_2)` or rtc_spinlock. -*/ - -#if CONFIG_IDF_TARGET_ESP32S2 -#ifdef CONFIG_PM_ENABLE -static esp_pm_lock_handle_t s_adc2_arbiter_lock; -#endif //CONFIG_PM_ENABLE -#endif // !CONFIG_IDF_TARGET_ESP32 - -static uint32_t clk_src_freq_hz; - -static esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, uint32_t clk_src_freq_hz, int *out_raw); - -/*--------------------------------------------------------------- - ADC Common ----------------------------------------------------------------*/ -esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num) -{ - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_1), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel"); - - int io = ADC_GET_IO_NUM(ADC_UNIT_1, channel); - if (io < 0) { - return ESP_ERR_INVALID_ARG; - } else { - *gpio_num = (gpio_num_t)io; - } - - return ESP_OK; -} - -#if (SOC_ADC_PERIPH_NUM >= 2) -esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num) -{ - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_2), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel"); - - int io = ADC_GET_IO_NUM(ADC_UNIT_2, channel); - if (io < 0) { - return ESP_ERR_INVALID_ARG; - } else { - *gpio_num = (gpio_num_t)io; - } - - return ESP_OK; -} -#endif - -//------------------------------------------------------------RTC Single Read----------------------------------------------// -#if SOC_ADC_RTC_CTRL_SUPPORTED -esp_err_t adc_set_clk_div(uint8_t clk_div) -{ - DIGI_CONTROLLER_ENTER(); - adc_ll_digi_set_clk_div(clk_div); - DIGI_CONTROLLER_EXIT(); - return ESP_OK; -} - -static void adc_rtc_chan_init(adc_unit_t adc_unit) -{ - if (adc_unit == ADC_UNIT_1) { - /* Workaround: Disable the synchronization operation function of ADC1 and DAC. - If enabled(default), ADC RTC controller sampling will cause the DAC channel output voltage. */ -#if SOC_DAC_SUPPORTED - dac_ll_rtc_sync_by_adc(false); -#endif - adc_oneshot_ll_output_invert(ADC_UNIT_1, ADC_LL_DATA_INVERT_DEFAULT(ADC_UNIT_1)); - adc_ll_set_sar_clk_div(ADC_UNIT_1, ADC_LL_SAR_CLK_DIV_DEFAULT(ADC_UNIT_1)); -#ifdef CONFIG_IDF_TARGET_ESP32 - adc_ll_hall_disable(); //Disable other peripherals. - adc_ll_amp_disable(); //Currently the LNA is not open, close it by default. -#endif - } - if (adc_unit == ADC_UNIT_2) { - adc_ll_pwdet_set_cct(ADC_LL_PWDET_CCT_DEFAULT); - adc_oneshot_ll_output_invert(ADC_UNIT_2, ADC_LL_DATA_INVERT_DEFAULT(ADC_UNIT_2)); - adc_ll_set_sar_clk_div(ADC_UNIT_2, ADC_LL_SAR_CLK_DIV_DEFAULT(ADC_UNIT_2)); - } -} - -esp_err_t adc_common_gpio_init(adc_unit_t adc_unit, adc_channel_t channel) -{ - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(adc_unit), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel"); - gpio_num_t gpio_num = 0; - //If called with `ADC_UNIT_BOTH (ADC_UNIT_1 | ADC_UNIT_2)`, both if blocks will be run - if (adc_unit == ADC_UNIT_1) { - gpio_num = ADC_GET_IO_NUM(ADC_UNIT_1, channel); - - } else if (adc_unit == ADC_UNIT_2) { - gpio_num = ADC_GET_IO_NUM(ADC_UNIT_2, channel); - } else { - return ESP_ERR_INVALID_ARG; - } - return gpio_config_as_analog(gpio_num); -} - -esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en) -{ - if (adc_unit == ADC_UNIT_1) { - SARADC1_ENTER(); - adc_oneshot_ll_output_invert(ADC_UNIT_1, inv_en); - SARADC1_EXIT(); - } - if (adc_unit == ADC_UNIT_2) { - SARADC2_ENTER(); - adc_oneshot_ll_output_invert(ADC_UNIT_2, inv_en); - SARADC2_EXIT(); - } - - return ESP_OK; -} - -esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit) -{ - ESP_RETURN_ON_FALSE(width_bit < ADC_WIDTH_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "unsupported bit width"); - adc_bitwidth_t bitwidth = 0; -#if CONFIG_IDF_TARGET_ESP32 - if ((uint32_t)width_bit == (uint32_t)ADC_BITWIDTH_DEFAULT) { - bitwidth = SOC_ADC_RTC_MAX_BITWIDTH; - } else { - switch (width_bit) { - case ADC_WIDTH_BIT_9: - bitwidth = ADC_BITWIDTH_9; - break; - case ADC_WIDTH_BIT_10: - bitwidth = ADC_BITWIDTH_10; - break; - case ADC_WIDTH_BIT_11: - bitwidth = ADC_BITWIDTH_11; - break; - case ADC_WIDTH_BIT_12: - bitwidth = ADC_BITWIDTH_12; - break; - default: - return ESP_ERR_INVALID_ARG; - } - } -#elif CONFIG_IDF_TARGET_ESP32S2 - bitwidth = ADC_BITWIDTH_13; -#else //esp32s3 - bitwidth = ADC_BITWIDTH_12; -#endif - - if (adc_unit == ADC_UNIT_1) { - SARADC1_ENTER(); - adc_oneshot_ll_set_output_bits(ADC_UNIT_1, bitwidth); - SARADC1_EXIT(); - } - if (adc_unit == ADC_UNIT_2) { - SARADC2_ENTER(); - adc_oneshot_ll_set_output_bits(ADC_UNIT_2, bitwidth); - SARADC2_EXIT(); - } - - return ESP_OK; -} - -/** - * @brief Reset RTC controller FSM. - * - * @return - * - ESP_OK Success - */ -#if !CONFIG_IDF_TARGET_ESP32 -esp_err_t adc_rtc_reset(void) -{ - FSM_ENTER(); - adc_ll_rtc_reset(); - FSM_EXIT(); - return ESP_OK; -} -#endif - -/*------------------------------------------------------------------------------------- - * ADC1 - *------------------------------------------------------------------------------------*/ -esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) -{ - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_1), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel"); - ESP_RETURN_ON_FALSE(atten < SOC_ADC_ATTEN_NUM, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC Atten Err"); - -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - if (!clk_src_freq_hz) { - //should never fail - esp_clk_tree_src_get_freq_hz(ADC_DIGI_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz); - } -#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - - adc_common_gpio_init(ADC_UNIT_1, channel); - SARADC1_ENTER(); - adc_rtc_chan_init(ADC_UNIT_1); - adc_oneshot_ll_set_atten(ADC_UNIT_1, channel, atten); - SARADC1_EXIT(); - - return ESP_OK; -} - -esp_err_t adc1_config_width(adc_bits_width_t width_bit) -{ - ESP_RETURN_ON_FALSE(width_bit < ADC_WIDTH_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "unsupported bit width"); - adc_bitwidth_t bitwidth = 0; -#if CONFIG_IDF_TARGET_ESP32 - if ((uint32_t)width_bit == (uint32_t)ADC_BITWIDTH_DEFAULT) { - bitwidth = SOC_ADC_RTC_MAX_BITWIDTH; - } else { - switch (width_bit) { - case ADC_WIDTH_BIT_9: - bitwidth = ADC_BITWIDTH_9; - break; - case ADC_WIDTH_BIT_10: - bitwidth = ADC_BITWIDTH_10; - break; - case ADC_WIDTH_BIT_11: - bitwidth = ADC_BITWIDTH_11; - break; - case ADC_WIDTH_BIT_12: - bitwidth = ADC_BITWIDTH_12; - break; - default: - return ESP_ERR_INVALID_ARG; - } - } -#elif CONFIG_IDF_TARGET_ESP32S2 - bitwidth = ADC_BITWIDTH_13; -#else //esp32s3 - bitwidth = ADC_BITWIDTH_12; -#endif - - SARADC1_ENTER(); - adc_oneshot_ll_set_output_bits(ADC_UNIT_1, bitwidth); - SARADC1_EXIT(); - - return ESP_OK; -} - -esp_err_t adc1_dma_mode_acquire(void) -{ - /* Use locks to avoid digtal and RTC controller conflicts. - for adc1, block until acquire the lock. */ - SARADC1_ACQUIRE(); - ESP_LOGD(ADC_TAG, "dma mode takes adc1 lock."); - - sar_periph_ctrl_adc_continuous_power_acquire(); - - SARADC1_ENTER(); - /* switch SARADC into DIG channel */ - adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_DIG); - SARADC1_EXIT(); - - return ESP_OK; -} - -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(); - sar_periph_ctrl_adc_oneshot_power_acquire(); - - SARADC1_ENTER(); - /* switch SARADC into RTC channel. */ - adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_RTC); - SARADC1_EXIT(); - - return ESP_OK; -} - -esp_err_t adc1_lock_release(void) -{ - ESP_RETURN_ON_FALSE((uint32_t *)adc1_dma_lock != NULL, ESP_ERR_INVALID_STATE, ADC_TAG, "adc1 lock release called before acquire"); - /* Use locks to avoid digtal and RTC controller conflicts. for adc1, block until acquire the lock. */ - - sar_periph_ctrl_adc_oneshot_power_release(); - SARADC1_RELEASE(); - return ESP_OK; -} - -int adc1_get_raw(adc1_channel_t channel) -{ - int adc_value; - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_1), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel"); - adc1_rtc_mode_acquire(); - - ANALOG_CLOCK_ENABLE(); - -#if SOC_ADC_CALIBRATION_V1_SUPPORTED - adc_hal_calibration_init(ADC_UNIT_1); - adc_atten_t atten = adc_ll_get_atten(ADC_UNIT_1, channel); - adc_set_hw_calibration_code(ADC_UNIT_1, atten); -#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED - - ANALOG_CLOCK_DISABLE(); - - SARADC1_ENTER(); -#ifdef CONFIG_IDF_TARGET_ESP32 - adc_ll_hall_disable(); //Disable other peripherals. - adc_ll_amp_disable(); //Currently the LNA is not open, close it by default. -#endif - adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_RTC); //Set controller - adc_oneshot_ll_set_channel(ADC_UNIT_1, channel); - adc_hal_convert(ADC_UNIT_1, channel, clk_src_freq_hz, &adc_value); //Start conversion, For ADC1, the data always valid. -#if !CONFIG_IDF_TARGET_ESP32 - adc_ll_rtc_reset(); //Reset FSM of rtc controller -#endif - SARADC1_EXIT(); - - adc1_lock_release(); - return adc_value; -} - -int adc1_get_voltage(adc1_channel_t channel) //Deprecated. Use adc1_get_raw() instead -{ - return adc1_get_raw(channel); -} - -#if SOC_ULP_SUPPORTED -void adc1_ulp_enable(void) -{ - sar_periph_ctrl_adc_oneshot_power_acquire(); - - SARADC1_ENTER(); - adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_ULP); - /* since most users do not need LNA and HALL with uLP, we disable them here - open them in the uLP if needed. */ -#ifdef CONFIG_IDF_TARGET_ESP32 - /* disable other peripherals. */ - adc_ll_hall_disable(); - adc_ll_amp_disable(); -#endif - SARADC1_EXIT(); -} -#endif - -#if (SOC_ADC_PERIPH_NUM >= 2) -/*--------------------------------------------------------------- - ADC2 ----------------------------------------------------------------*/ -esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) -{ - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_2), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel"); - ESP_RETURN_ON_FALSE(atten <= SOC_ADC_ATTEN_NUM, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 Atten Err"); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - if (!clk_src_freq_hz) { - //should never fail - esp_clk_tree_src_get_freq_hz(ADC_DIGI_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz); - } -#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - - adc_common_gpio_init(ADC_UNIT_2, channel); - -#if CONFIG_IDF_TARGET_ESP32 - /** For ESP32S2 and S3, the right to use ADC2 is controlled by the arbiter, and there is no need to set a lock.*/ - if (adc_lock_try_acquire(ADC_UNIT_2) != ESP_OK) { - //try the lock, return if failed (wifi using). - return ESP_ERR_TIMEOUT; - } -#endif - - //avoid collision with other tasks - SARADC2_ENTER(); - adc_rtc_chan_init(ADC_UNIT_2); - adc_oneshot_ll_set_atten(ADC_UNIT_2, channel, atten); - SARADC2_EXIT(); - -#if CONFIG_IDF_TARGET_ESP32 - adc_lock_release(ADC_UNIT_2); -#endif - - return ESP_OK; -} - -static inline void adc2_init(void) -{ -#if CONFIG_IDF_TARGET_ESP32S2 -#ifdef CONFIG_PM_ENABLE - /* Lock APB clock. */ - if (s_adc2_arbiter_lock == NULL) { - esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc2", &s_adc2_arbiter_lock); - } -#endif //CONFIG_PM_ENABLE -#endif //CONFIG_IDF_TARGET_ESP32S2 -} - -static inline void adc2_dac_disable(adc2_channel_t channel) -{ -#if SOC_DAC_SUPPORTED -#ifdef CONFIG_IDF_TARGET_ESP32 - if (channel == ADC2_CHANNEL_8) { // the same as DAC channel 0 - dac_ll_power_down(DAC_CHAN_0); - } else if (channel == ADC2_CHANNEL_9) { - dac_ll_power_down(DAC_CHAN_1); - } -#else - if (channel == ADC2_CHANNEL_6) { // the same as DAC channel 0 - dac_ll_power_down(DAC_CHAN_0); - } else if (channel == ADC2_CHANNEL_7) { - dac_ll_power_down(DAC_CHAN_1); - } -#endif -#endif // SOC_DAC_SUPPORTED -} - -/** - * @note For ESP32S2: - * The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. - * Or, the RTC controller will fail when get raw data. - * This issue does not occur on digital controllers (DMA mode), and the hardware guarantees that there will be no errors. - */ -esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out) -{ - esp_err_t ret = ESP_OK; - int adc_value = 0; - adc_bitwidth_t bitwidth = 0; - - ESP_RETURN_ON_FALSE(raw_out != NULL, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC out value err"); - ESP_RETURN_ON_FALSE(channel < ADC2_CHANNEL_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC Channel Err"); - ESP_RETURN_ON_FALSE(width_bit < ADC_WIDTH_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "unsupported bit width"); -#if CONFIG_IDF_TARGET_ESP32 - if ((uint32_t)width_bit == (uint32_t)ADC_BITWIDTH_DEFAULT) { - bitwidth = SOC_ADC_RTC_MAX_BITWIDTH; - } else { - switch (width_bit) { - case ADC_WIDTH_BIT_9: - bitwidth = ADC_BITWIDTH_9; - break; - case ADC_WIDTH_BIT_10: - bitwidth = ADC_BITWIDTH_10; - break; - case ADC_WIDTH_BIT_11: - bitwidth = ADC_BITWIDTH_11; - break; - case ADC_WIDTH_BIT_12: - bitwidth = ADC_BITWIDTH_12; - break; - default: - return ESP_ERR_INVALID_ARG; - } - } -#elif CONFIG_IDF_TARGET_ESP32S2 - bitwidth = ADC_BITWIDTH_13; -#else //esp32s3 - bitwidth = ADC_BITWIDTH_12; -#endif - -#if CONFIG_IDF_TARGET_ESP32 - /** For ESP32S2 and S3, the right to use ADC2 is controlled by the arbiter, and there is no need to set a lock.*/ - if (adc_lock_try_acquire(ADC_UNIT_2) != ESP_OK) { - //try the lock, return if failed (wifi using). - return ESP_ERR_TIMEOUT; - } -#endif - sar_periph_ctrl_adc_oneshot_power_acquire(); //in critical section with whole rtc module - -#if SOC_ADC_CALIBRATION_V1_SUPPORTED - adc_hal_calibration_init(ADC_UNIT_2); - adc_atten_t atten = adc_ll_get_atten(ADC_UNIT_2, channel); - adc_set_hw_calibration_code(ADC_UNIT_2, atten); -#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED - - //avoid collision with other tasks - adc2_init(); // in critical section with whole rtc module. because the PWDET use the same registers, place it here. - SARADC2_ENTER(); - -#if SOC_ADC_ARBITER_SUPPORTED - adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); - adc_hal_arbiter_config(&config); -#endif - -#ifdef CONFIG_ADC_DISABLE_DAC - adc2_dac_disable(channel); //disable other peripherals -#endif - adc_oneshot_ll_set_output_bits(ADC_UNIT_2, bitwidth); - -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32P4 - adc_ll_set_controller(ADC_UNIT_2, ADC_LL_CTRL_RTC);// set controller -#else - adc_ll_set_controller(ADC_UNIT_2, ADC_LL_CTRL_ARB);// set controller -#endif - -#if CONFIG_IDF_TARGET_ESP32S2 -#ifdef CONFIG_PM_ENABLE - if (s_adc2_arbiter_lock) { - esp_pm_lock_acquire(s_adc2_arbiter_lock); - } -#endif //CONFIG_PM_ENABLE -#endif //CONFIG_IDF_TARGET_ESP32 - - adc_oneshot_ll_set_channel(ADC_UNIT_2, channel); - ret = adc_hal_convert(ADC_UNIT_2, channel, clk_src_freq_hz, &adc_value); - if (ret != ESP_OK) { - adc_value = -1; - } - -#if CONFIG_IDF_TARGET_ESP32S2 -#ifdef CONFIG_PM_ENABLE - /* Release APB clock. */ - if (s_adc2_arbiter_lock) { - esp_pm_lock_release(s_adc2_arbiter_lock); - } -#endif //CONFIG_PM_ENABLE -#endif //CONFIG_IDF_TARGET_ESP32 - SARADC2_EXIT(); - - sar_periph_ctrl_adc_oneshot_power_release(); -#if CONFIG_IDF_TARGET_ESP32 - adc_lock_release(ADC_UNIT_2); -#endif - - *raw_out = adc_value; - return ret; -} - -esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio) -{ -#ifdef CONFIG_IDF_TARGET_ESP32 - if (adc_unit == ADC_UNIT_1) { - return ESP_ERR_INVALID_ARG; - } -#endif - adc2_channel_t ch = ADC2_CHANNEL_MAX; - /* Check if the GPIO supported. */ - for (int i = 0; i < ADC2_CHANNEL_MAX; i++) { - if (gpio == ADC_GET_IO_NUM(ADC_UNIT_2, i)) { - ch = i; - break; - } - } - if (ch == ADC2_CHANNEL_MAX) { - return ESP_ERR_INVALID_ARG; - } - - sar_periph_ctrl_adc_oneshot_power_acquire(); - if (adc_unit == ADC_UNIT_1) { - VREF_ENTER(1); - adc_ll_vref_output(ADC_UNIT_1, ch, true); - VREF_EXIT(1); - } else if (adc_unit == ADC_UNIT_2) { - VREF_ENTER(2); - adc_ll_vref_output(ADC_UNIT_2, ch, true); - VREF_EXIT(2); - } - - //Configure RTC gpio, Only ADC2's channels IO are supported to output reference voltage. - adc_common_gpio_init(ADC_UNIT_2, ch); - return ESP_OK; -} - -#endif //SOC_ADC_RTC_CTRL_SUPPORTED -#endif //#if (SOC_ADC_PERIPH_NUM >= 2) - -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED -/*--------------------------------------------------------------- - Legacy ADC Single Read Mode - when RTC controller isn't supported ----------------------------------------------------------------*/ -#include "esp_check.h" - -portMUX_TYPE adc_reg_lock = portMUX_INITIALIZER_UNLOCKED; -#define ADC_REG_LOCK_ENTER() portENTER_CRITICAL(&adc_reg_lock) -#define ADC_REG_LOCK_EXIT() portEXIT_CRITICAL(&adc_reg_lock) - -static adc_atten_t s_atten1_single[ADC1_CHANNEL_MAX]; //Array saving attenuate of each channel of ADC1, used by single read API -#if (SOC_ADC_PERIPH_NUM >= 2) -static adc_atten_t s_atten2_single[ADC2_CHANNEL_MAX]; //Array saving attenuate of each channel of ADC2, used by single read API -#endif - -static int8_t adc_digi_get_io_num(adc_unit_t adc_unit, uint8_t adc_channel) -{ - assert(adc_unit < SOC_ADC_PERIPH_NUM); - uint8_t adc_n = (adc_unit == ADC_UNIT_1) ? 0 : 1; - return adc_channel_io_map[adc_n][adc_channel]; -} - -static esp_err_t adc_digi_gpio_init(adc_unit_t adc_unit, uint16_t channel_mask) -{ - esp_err_t ret = ESP_OK; - uint32_t n = 0; - int8_t io = 0; - - while (channel_mask) { - if (channel_mask & 0x1) { - io = adc_digi_get_io_num(adc_unit, n); - if (io < 0) { - return ESP_ERR_INVALID_ARG; - } - gpio_config_as_analog(io); - } - channel_mask = channel_mask >> 1; - n++; - } - return ret; -} - -#if CONFIG_IDF_TARGET_ESP32C3 -esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio) -{ - esp_err_t ret; - uint32_t channel = ADC2_CHANNEL_MAX; - if (adc_unit == ADC_UNIT_2) { - for (int i = 0; i < ADC2_CHANNEL_MAX; i++) { - if (gpio == ADC_GET_IO_NUM(ADC_UNIT_2, i)) { - channel = i; - break; - } - } - if (channel == ADC2_CHANNEL_MAX) { - return ESP_ERR_INVALID_ARG; - } - } - - sar_periph_ctrl_adc_oneshot_power_acquire(); - if (adc_unit == ADC_UNIT_1) { - RTC_ENTER_CRITICAL(); - adc_ll_vref_output(ADC_UNIT_1, channel, true); - RTC_EXIT_CRITICAL(); - } else { //ADC_UNIT_2 - RTC_ENTER_CRITICAL(); - adc_ll_vref_output(ADC_UNIT_2, channel, true); - RTC_EXIT_CRITICAL(); - } - - ret = adc_digi_gpio_init(ADC_UNIT_2, BIT(channel)); - - return ret; -} -#endif - -esp_err_t adc1_config_width(adc_bits_width_t width_bit) -{ - //On ESP32C3, the data width is always 12-bits. - if (width_bit != ADC_WIDTH_BIT_12) { - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; -} - -esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) -{ - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_1), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC1 channel error"); - ESP_RETURN_ON_FALSE((atten < SOC_ADC_ATTEN_NUM), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC Atten Err"); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - if (!clk_src_freq_hz) { - //should never fail - esp_clk_tree_src_get_freq_hz(ADC_DIGI_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz); - } -#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - - esp_err_t ret = ESP_OK; - s_atten1_single[channel] = atten; - ret = adc_digi_gpio_init(ADC_UNIT_1, BIT(channel)); - - return ret; -} - -int adc1_get_raw(adc1_channel_t channel) -{ - int raw_out = 0; - - if (adc_lock_try_acquire(ADC_UNIT_1) != ESP_OK) { - return ESP_ERR_TIMEOUT; - } - - adc_apb_periph_claim(); - sar_periph_ctrl_adc_oneshot_power_acquire(); - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true)); - adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); - - adc_atten_t atten = s_atten1_single[channel]; - - ANALOG_CLOCK_ENABLE(); - -#if SOC_ADC_CALIBRATION_V1_SUPPORTED - adc_hal_calibration_init(ADC_UNIT_1); - adc_set_hw_calibration_code(ADC_UNIT_1, atten); -#endif - - ANALOG_CLOCK_DISABLE(); - - ADC_REG_LOCK_ENTER(); - adc_oneshot_ll_set_atten(ADC_UNIT_1, channel, atten); - adc_hal_convert(ADC_UNIT_1, channel, clk_src_freq_hz, &raw_out); - ADC_REG_LOCK_EXIT(); - - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, false)); - sar_periph_ctrl_adc_oneshot_power_release(); - adc_apb_periph_free(); - adc_lock_release(ADC_UNIT_1); - - return raw_out; -} - -#if (SOC_ADC_PERIPH_NUM >= 2) -esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) -{ - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_2), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 channel error"); - ESP_RETURN_ON_FALSE((atten <= ADC_ATTEN_DB_12), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 Atten Err"); - - esp_err_t ret = ESP_OK; - s_atten2_single[channel] = atten; - ret = adc_digi_gpio_init(ADC_UNIT_2, BIT(channel)); - -#if SOC_ADC_CALIBRATION_V1_SUPPORTED - adc_hal_calibration_init(ADC_UNIT_2); -#endif - - return ret; -} - -esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out) -{ - //On ESP32C3, the data width is always 12-bits. - if (width_bit != ADC_WIDTH_BIT_12) { - return ESP_ERR_INVALID_ARG; - } -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - if (!clk_src_freq_hz) { - //should never fail - esp_clk_tree_src_get_freq_hz(ADC_DIGI_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz); - } -#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - - esp_err_t ret = ESP_OK; - - if (adc_lock_try_acquire(ADC_UNIT_2) != ESP_OK) { - return ESP_ERR_TIMEOUT; - } - - adc_apb_periph_claim(); - sar_periph_ctrl_adc_oneshot_power_acquire(); - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true)); - adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); - -#if SOC_ADC_ARBITER_SUPPORTED - adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); - adc_hal_arbiter_config(&config); -#endif - - adc_atten_t atten = s_atten2_single[channel]; -#if SOC_ADC_CALIBRATION_V1_SUPPORTED - adc_set_hw_calibration_code(ADC_UNIT_2, atten); -#endif - - ADC_REG_LOCK_ENTER(); - adc_oneshot_ll_set_atten(ADC_UNIT_2, channel, atten); - ret = adc_hal_convert(ADC_UNIT_2, channel, clk_src_freq_hz, raw_out); - ADC_REG_LOCK_EXIT(); - - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, false)); - sar_periph_ctrl_adc_oneshot_power_release(); - adc_apb_periph_free(); - adc_lock_release(ADC_UNIT_2); - - return ret; -} -#endif //#if (SOC_ADC_PERIPH_NUM >= 2) -#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - -static void adc_hal_onetime_start(adc_unit_t adc_n, uint32_t clk_src_freq_hz) -{ -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - (void)adc_n; - /** - * There is a hardware limitation. If the APB clock frequency is high, the step of this reg signal: ``onetime_start`` may not be captured by the - * ADC digital controller (when its clock frequency is too slow). A rough estimate for this step should be at least 3 ADC digital controller - * clock cycle. - */ - uint32_t digi_clk = clk_src_freq_hz / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1); - //Convert frequency to time (us). Since decimals are removed by this division operation. Add 1 here in case of the fact that delay is not enough. - uint32_t delay = (1000 * 1000) / digi_clk + 1; - //3 ADC digital controller clock cycle - delay = delay * 3; - //This coefficient (8) is got from test, and verified from DT. When digi_clk is not smaller than ``APB_CLK_FREQ/8``, no delay is needed. - if (digi_clk >= APB_CLK_FREQ / 8) { - delay = 0; - } - - adc_oneshot_ll_start(false); - esp_rom_delay_us(delay); - adc_oneshot_ll_start(true); - - //No need to delay here. Because if the start signal is not seen, there won't be a done intr. -#else - (void)clk_src_freq_hz; - adc_oneshot_ll_start(adc_n); -#endif -} - -static esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, uint32_t clk_src_freq_hz, int *out_raw) -{ - - uint32_t event = (adc_n == ADC_UNIT_1) ? ADC_LL_EVENT_ADC1_ONESHOT_DONE : ADC_LL_EVENT_ADC2_ONESHOT_DONE; - adc_oneshot_ll_clear_event(event); - adc_oneshot_ll_disable_all_unit(); - adc_oneshot_ll_enable(adc_n); - adc_oneshot_ll_set_channel(adc_n, channel); - - adc_hal_onetime_start(adc_n, clk_src_freq_hz); - - while (adc_oneshot_ll_get_event(event) != true) { - ; - } - - *out_raw = adc_oneshot_ll_get_raw_result(adc_n); - if (adc_oneshot_ll_raw_check_valid(adc_n, *out_raw) == false) { - return ESP_ERR_INVALID_STATE; - } - - //HW workaround: when enabling periph clock, this should be false - adc_oneshot_ll_disable_all_unit(); - - return ESP_OK; -} - -#if !CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK -/** - * @brief This function will be called during start up, to check that adc_oneshot driver is not running along with the legacy adc oneshot driver - */ -__attribute__((constructor)) -static void check_adc_oneshot_driver_conflict(void) -{ - // This function was declared as weak here. adc_oneshot driver has one implementation. - // So if adc_oneshot driver is not linked in, then `adc_oneshot_new_unit` should be NULL at runtime. - extern __attribute__((weak)) esp_err_t adc_oneshot_new_unit(const void *init_config, void **ret_unit); - if ((void *)adc_oneshot_new_unit != NULL) { - ESP_EARLY_LOGE(ADC_TAG, "CONFLICT! driver_ng is not allowed to be used with the legacy driver"); - abort(); - } - ESP_EARLY_LOGW(ADC_TAG, "legacy driver is deprecated, please migrate to `esp_adc/adc_oneshot.h`"); -} -#endif //CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK - -#if SOC_ADC_CALIBRATION_V1_SUPPORTED -/*--------------------------------------------------------------- - ADC Hardware Calibration ----------------------------------------------------------------*/ -static __attribute__((constructor)) void adc_hw_calibration(void) -{ - ANALOG_CLOCK_ENABLE(); - //Calculate all ICode - for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) { - adc_hal_calibration_init(i); - for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) { - /** - * This may get wrong when attenuations are NOT consecutive on some chips, - * update this when bringing up the calibration on that chip - */ - adc_calc_hw_calibration_code(i, j); -#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED - /* Load the channel compensation from efuse */ - for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) { - adc_load_hw_calibration_chan_compens(i, k, j); - } -#endif - } - } - ANALOG_CLOCK_DISABLE(); -} -#endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED diff --git a/components/driver/deprecated/driver/adc.h b/components/driver/deprecated/driver/adc.h deleted file mode 100644 index d5d683c63c..0000000000 --- a/components/driver/deprecated/driver/adc.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/*---------------------------------------------------------------------------------- - This file contains Deprecated ADC APIs ------------------------------------------------------------------------------------*/ - -#pragma once -#include "sdkconfig.h" -#include "esp_err.h" -#include "driver/gpio.h" -#include "driver/adc_types_legacy.h" -#include "hal/adc_types.h" - -#if !CONFIG_ADC_SUPPRESS_DEPRECATE_WARN -#warning "legacy adc driver is deprecated, please migrate to use esp_adc/adc_oneshot.h and esp_adc/adc_continuous.h for oneshot mode and continuous mode drivers respectively" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/*--------------------------------------------------------------- - Deprecated API ----------------------------------------------------------------*/ -/*--------------------------------------------------------------- - ADC Single Read Setting ----------------------------------------------------------------*/ -/** - * @brief Get the GPIO number of a specific ADC1 channel. - * - * @param channel Channel to get the GPIO number - * @param gpio_num output buffer to hold the GPIO number - * - * @return - * - ESP_OK if success - * - ESP_ERR_INVALID_ARG if channel not valid - */ -esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num); - -/** - * @brief Set the attenuation of a particular channel on ADC1, and configure its associated GPIO pin mux. - * - * The default ADC voltage is for attenuation 0 dB and listed in the table below. - * By setting higher attenuation it is possible to read higher voltages. - * - * Due to ADC characteristics, most accurate results are obtained within the "suggested range" - * shown in the following table. - * - * +----------+-------------+-----------------+ - * | | attenuation | suggested range | - * | SoC | (dB) | (mV) | - * +==========+=============+=================+ - * | | 0 | 100 ~ 950 | - * | +-------------+-----------------+ - * | | 2.5 | 100 ~ 1250 | - * | ESP32 +-------------+-----------------+ - * | | 6 | 150 ~ 1750 | - * | +-------------+-----------------+ - * | | 11 | 150 ~ 2450 | - * +----------+-------------+-----------------+ - * | | 0 | 0 ~ 750 | - * | +-------------+-----------------+ - * | | 2.5 | 0 ~ 1050 | - * | ESP32-S2 +-------------+-----------------+ - * | | 6 | 0 ~ 1300 | - * | +-------------+-----------------+ - * | | 11 | 0 ~ 2500 | - * +----------+-------------+-----------------+ - * - * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. - * - * @note For any given channel, this function must be called before the first time ``adc1_get_raw()`` is called for that channel. - * - * @note This function can be called multiple times to configure multiple - * ADC channels simultaneously. You may call ``adc1_get_raw()`` only after configuring a channel. - * - * @param channel ADC1 channel to configure - * @param atten Attenuation level - * - * @return - * - ESP_OK success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten); - -/** - * @brief Configure ADC1 capture width, meanwhile enable output invert for ADC1. - * The configuration is for all channels of ADC1 - * @param width_bit Bit capture width for ADC1 - * - * @return - * - ESP_OK success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t adc1_config_width(adc_bits_width_t width_bit); - -/** - * @brief Take an ADC1 reading from a single channel. - * @note ESP32: - * When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on, - * 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 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 - * function is called. - * - * @note For any given channel, adc1_config_channel_atten(channel) - * must be called before the first time this function is called. Configuring - * a new channel does not prevent a previously configured channel from being read. - * - * @param channel ADC1 channel to read - * - * @return - * - -1: Parameter error - * - Other: ADC1 channel reading. - */ -int adc1_get_raw(adc1_channel_t channel); - -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 -//TODO IDF-3610, replace these with proper caps -/** - * @brief Set ADC data invert - * @param adc_unit ADC unit index - * @param inv_en whether enable data invert - * @return - * - ESP_OK success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en); - -/** - * @brief Set ADC source clock - * @param clk_div ADC clock divider, ADC clock is divided from APB clock - * @return - * - ESP_OK success - */ -esp_err_t adc_set_clk_div(uint8_t clk_div); - -/** - * @brief Configure ADC capture width. - * - * @param adc_unit ADC unit index - * @param width_bit Bit capture width for ADC unit. - * - * @return - * - ESP_OK success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit); - -/** - * @brief Configure ADC1 to be usable by the ULP - * - * This function reconfigures ADC1 to be controlled by the ULP. - * Effect of this function can be reverted using ``adc1_get_raw()`` function. - * - * Note that adc1_config_channel_atten, ``adc1_config_width()`` functions need - * to be called to configure ADC1 channels, before ADC1 is used by the ULP. - */ -void adc1_ulp_enable(void); -#endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 - -#if (SOC_ADC_PERIPH_NUM >= 2) -/** - * @brief Get the GPIO number of a specific ADC2 channel. - * - * @param channel Channel to get the GPIO number - * - * @param gpio_num output buffer to hold the GPIO number - * - * @return - * - ESP_OK if success - * - ESP_ERR_INVALID_ARG if channel not valid - */ -esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num); - -/** - * @brief Configure the ADC2 channel, including setting attenuation. - * - * The default ADC voltage is for attenuation 0 dB and listed in the table below. - * By setting higher attenuation it is possible to read higher voltages. - * - * Due to ADC characteristics, most accurate results are obtained within the "suggested range" - * shown in the following table. - * - * +----------+-------------+-----------------+ - * | | attenuation | suggested range | - * | SoC | (dB) | (mV) | - * +==========+=============+=================+ - * | | 0 | 100 ~ 950 | - * | +-------------+-----------------+ - * | | 2.5 | 100 ~ 1250 | - * | ESP32 +-------------+-----------------+ - * | | 6 | 150 ~ 1750 | - * | +-------------+-----------------+ - * | | 11 | 150 ~ 2450 | - * +----------+-------------+-----------------+ - * | | 0 | 0 ~ 750 | - * | +-------------+-----------------+ - * | | 2.5 | 0 ~ 1050 | - * | ESP32-S2 +-------------+-----------------+ - * | | 6 | 0 ~ 1300 | - * | +-------------+-----------------+ - * | | 11 | 0 ~ 2500 | - * +----------+-------------+-----------------+ - * - * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. - * - * @note This function also configures the input GPIO pin mux to - * connect it to the ADC2 channel. It must be called before calling - * ``adc2_get_raw()`` for this channel. - * - * @note For any given channel, this function must be called before the first time ``adc2_get_raw()`` is called for that channel. - * - * @param channel ADC2 channel to configure - * @param atten Attenuation level - * - * @return - * - ESP_OK success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten); - -/** - * @brief Take an ADC2 reading on a single channel - * - * @note ESP32: - * When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on, - * 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 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 ESP32: - * For a given channel, ``adc2_config_channel_atten()`` - * must be called before the first time this function is called. If Wi-Fi is started via ``esp_wifi_start()``, this - * function will always fail with ``ESP_ERR_TIMEOUT``. - * - * @note ESP32-S2: - * ADC2 support hardware arbiter. 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 ADC2 data. Default priority: Wi-Fi > RTC > Digital; - * - * @param channel ADC2 channel to read - * @param width_bit Bit capture width for ADC2 - * @param raw_out the variable to hold the output data. - * - * @return - * - ESP_OK if success - * - ESP_ERR_TIMEOUT ADC2 is being used by other controller and the request timed out. - * - ESP_ERR_INVALID_STATE The controller status is invalid. Please try again. - */ -esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out); - -/** - * @brief Output ADC1 or ADC2's reference voltage to ``adc2_channe_t``'s IO. - * - * This function routes the internal reference voltage of ADCn to one of - * ADC2's channels. This reference voltage can then be manually measured - * for calibration purposes. - * - * @note ESP32 only supports output of ADC2's internal reference voltage. - * @param[in] adc_unit ADC unit index - * @param[in] gpio GPIO number (Only ADC2's channels IO are supported) - * - * @return - * - ESP_OK: v_ref successfully routed to selected GPIO - * - ESP_ERR_INVALID_ARG: Unsupported GPIO - */ -esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio); -#endif //#if (SOC_ADC_PERIPH_NUM >= 2) - -/*--------------------------------------------------------------- - ADC DMA Read Setting ----------------------------------------------------------------*/ -#if SOC_ADC_DMA_SUPPORTED -/** - * @brief Initialize the Digital ADC. - * - * @param init_config Pointer to Digital ADC initialization config. Refer to ``adc_digi_init_config_t``. - * - * @return - * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. - * - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags - * - ESP_ERR_NO_MEM If out of memory - * - ESP_OK On success - */ -esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config); - -/** - * @brief Read bytes from Digital ADC through DMA. - * - * @param[out] buf Buffer to read from ADC. - * @param[in] length_max Expected length of data read from the ADC. - * @param[out] out_length Real length of data read from the ADC via this API. - * @param[in] timeout_ms Time to wait for data via this API, in millisecond. - * - * @return - * - ESP_ERR_INVALID_STATE Driver state is invalid. Usually it means the ADC sampling rate is faster than the task processing rate. - * - ESP_ERR_TIMEOUT Operation timed out - * - ESP_OK On success - */ -esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_length, uint32_t timeout_ms); - -/** - * @brief Start the Digital ADC and DMA peripherals. After this, the hardware starts working. - * - * @return - * - ESP_ERR_INVALID_STATE Driver state is invalid. - * - ESP_OK On success - */ -esp_err_t adc_digi_start(void); - -/** - * @brief Stop the Digital ADC and DMA peripherals. After this, the hardware stops working. - * - * @return - * - ESP_ERR_INVALID_STATE Driver state is invalid. - * - ESP_OK On success - */ -esp_err_t adc_digi_stop(void); - -/** - * @brief Deinitialize the Digital ADC. - * - * @return - * - ESP_ERR_INVALID_STATE Driver state is invalid. - * - ESP_OK On success - */ -esp_err_t adc_digi_deinitialize(void); - -/** - * @brief Setting the digital controller. - * - * @param config Pointer to digital controller parameter. Refer to ``adc_digi_config_t``. - * - * @return - * - ESP_ERR_INVALID_STATE Driver state is invalid. - * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. - * - ESP_OK On success - */ -esp_err_t adc_digi_controller_configure(const adc_digi_configuration_t *config); -#endif - -#ifdef __cplusplus -} -#endif diff --git a/components/driver/deprecated/driver/adc_i2s_legacy.h b/components/driver/deprecated/driver/adc_i2s_legacy.h deleted file mode 100644 index 44af449212..0000000000 --- a/components/driver/deprecated/driver/adc_i2s_legacy.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once -#include "sdkconfig.h" -#include "esp_err.h" -#include "hal/adc_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef CONFIG_IDF_TARGET_ESP32 -/** - * @brief ESP32 ADC DMA source selection. - */ -typedef enum { - ADC_I2S_DATA_SRC_IO_SIG = 0, /*!< I2S data from GPIO matrix signal */ - ADC_I2S_DATA_SRC_ADC = 1, /*!< I2S data from ADC */ -} adc_i2s_source_t; -#endif - -#if CONFIG_IDF_TARGET_ESP32 -/*--------------------------------------------------------------- - ESP32 Deprecated API ----------------------------------------------------------------*/ -/** - * @brief Set I2S data source - * @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC. - * @return - * - ESP_OK success - */ -esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src); - -/** - * @brief Initialize I2S ADC mode - * @param adc_unit ADC unit index - * @param channel ADC channel index - * @return - * - ESP_OK success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel); -#endif - -#ifdef __cplusplus -} -#endif diff --git a/components/driver/deprecated/driver/adc_types_legacy.h b/components/driver/deprecated/driver/adc_types_legacy.h deleted file mode 100644 index 30587e1d2c..0000000000 --- a/components/driver/deprecated/driver/adc_types_legacy.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once -#include "hal/adc_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief ADC resolution setting option. - * @note Only used in single read mode - */ -typedef enum { -#if CONFIG_IDF_TARGET_ESP32 - ADC_WIDTH_BIT_9 = 9, /*!< ADC capture width is 9Bit. */ - ADC_WIDTH_BIT_10 = 10, /*!< ADC capture width is 10Bit. */ - ADC_WIDTH_BIT_11 = 11, /*!< ADC capture width is 11Bit. */ - ADC_WIDTH_BIT_12 = 12, /*!< ADC capture width is 12Bit. */ -#elif SOC_ADC_RTC_MAX_BITWIDTH == 12 - ADC_WIDTH_BIT_12 = 12, /*!< ADC capture width is 12Bit. */ -#elif SOC_ADC_RTC_MAX_BITWIDTH == 13 - ADC_WIDTH_BIT_13 = 13, /*!< ADC capture width is 13Bit. */ -#endif - ADC_WIDTH_MAX, -} adc_bits_width_t; - -/** - * The default (max) bit width of the ADC of current version. You can also get the maximum bitwidth - * by `SOC_ADC_RTC_MAX_BITWIDTH` defined in soc_caps.h. - */ -#define ADC_WIDTH_BIT_DEFAULT (ADC_WIDTH_MAX-1) - -typedef enum { - ADC1_CHANNEL_0 = 0, - ADC1_CHANNEL_1, - ADC1_CHANNEL_2, - ADC1_CHANNEL_3, -#if SOC_ADC_CHANNEL_NUM(0) > 4 - ADC1_CHANNEL_4, -#endif -#if SOC_ADC_CHANNEL_NUM(0) > 5 - ADC1_CHANNEL_5, -#endif -#if SOC_ADC_CHANNEL_NUM(0) > 6 - ADC1_CHANNEL_6, -#endif -#if SOC_ADC_CHANNEL_NUM(0) > 7 - ADC1_CHANNEL_7, -#endif -#if SOC_ADC_CHANNEL_NUM(0) > 8 - ADC1_CHANNEL_8, -#endif -#if SOC_ADC_CHANNEL_NUM(0) > 9 - ADC1_CHANNEL_9, -#endif - ADC1_CHANNEL_MAX = SOC_ADC_CHANNEL_NUM(0), -} adc1_channel_t; - -#if SOC_ADC_PERIPH_NUM > 1 -typedef enum { - ADC2_CHANNEL_0 = 0, -#if SOC_ADC_CHANNEL_NUM(1) > 1 - ADC2_CHANNEL_1, -#endif -#if SOC_ADC_CHANNEL_NUM(1) > 2 - ADC2_CHANNEL_2, -#endif -#if SOC_ADC_CHANNEL_NUM(1) > 3 - ADC2_CHANNEL_3, -#endif -#if SOC_ADC_CHANNEL_NUM(1) > 4 - ADC2_CHANNEL_4, -#endif -#if SOC_ADC_CHANNEL_NUM(1) > 5 - ADC2_CHANNEL_5, -#endif -#if SOC_ADC_CHANNEL_NUM(1) > 6 - ADC2_CHANNEL_6, -#endif -#if SOC_ADC_CHANNEL_NUM(1) > 7 - ADC2_CHANNEL_7, -#endif -#if SOC_ADC_CHANNEL_NUM(1) > 8 - ADC2_CHANNEL_8, -#endif -#if SOC_ADC_CHANNEL_NUM(1) > 9 - ADC2_CHANNEL_9, -#endif - ADC2_CHANNEL_MAX = SOC_ADC_CHANNEL_NUM(1), -} adc2_channel_t; -#endif - -#if SOC_ADC_DMA_SUPPORTED -/** - * @brief Digital ADC DMA read max timeout value, it may make the ``adc_digi_read_bytes`` block forever if the OS supports - */ -#define ADC_MAX_DELAY UINT32_MAX - -/** - * @brief ADC DMA driver configuration - */ -typedef struct adc_digi_init_config_s { - uint32_t max_store_buf_size; ///< Max length of the converted data that driver can store before they are processed. - uint32_t conv_num_each_intr; ///< Bytes of data that can be converted in 1 interrupt. This should be in multiples of `SOC_ADC_DIGI_DATA_BYTES_PER_CONV`. - uint32_t adc1_chan_mask; ///< Channel list of ADC1 to be initialized. - uint32_t adc2_chan_mask; ///< Channel list of ADC2 to be initialized. -} adc_digi_init_config_t; - -/** - * @brief ADC digital controller settings - */ -typedef struct { - bool conv_limit_en; ///< Suggest leaving it empty, this parameter has been deprecated - uint32_t conv_limit_num; ///< suggest leaving it empty, this parameter has been deprecated - uint32_t pattern_num; ///< Number of ADC channels that will be used - adc_digi_pattern_config_t *adc_pattern; ///< List of configs for each ADC channel that will be used - uint32_t sample_freq_hz; /*!< Please refer to `soc/soc_caps.h` to know the ADC sampling frequency range*/ - adc_digi_convert_mode_t conv_mode; ///< ADC DMA conversion mode, see `adc_digi_convert_mode_t`. - adc_digi_output_format_t format; ///< ADC DMA conversion output format, see `adc_digi_output_format_t`. -} adc_digi_configuration_t; -#endif // #if SOC_ADC_DMA_SUPPORTED - -#ifdef __cplusplus -} -#endif diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index f82656e047..86bee22c20 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -1,19 +1,5 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps -components/driver/test_apps/legacy_adc_driver: - disable: - - if: SOC_ADC_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32c61" - temporary: true - reason: lack of runners - depends_components: - - efuse - - esp_driver_i2s - - esp_driver_spi - depends_filepatterns: - - components/driver/deprecated/**/*adc* - components/driver/test_apps/legacy_i2c_driver: disable: - if: SOC_I2C_SUPPORTED != 1 diff --git a/components/driver/test_apps/legacy_adc_driver/CMakeLists.txt b/components/driver/test_apps/legacy_adc_driver/CMakeLists.txt deleted file mode 100644 index 4372ec085e..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# This is the project CMakeLists.txt file for the test subproject -cmake_minimum_required(VERSION 3.16) - -# "Trim" the build. Include the minimal set of components, main, and anything it depends on. -set(COMPONENTS main) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(legacy_adc_driver_test) diff --git a/components/driver/test_apps/legacy_adc_driver/README.md b/components/driver/test_apps/legacy_adc_driver/README.md deleted file mode 100644 index 7b96141437..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/README.md +++ /dev/null @@ -1,2 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_adc_driver/main/CMakeLists.txt b/components/driver/test_apps/legacy_adc_driver/main/CMakeLists.txt deleted file mode 100644 index 97e214a19e..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/main/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(srcs "test_app_main.c" - "test_legacy_adc.c") - -idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity driver - WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/legacy_adc_driver/main/test_app_main.c b/components/driver/test_apps/legacy_adc_driver/main/test_app_main.c deleted file mode 100644 index 69a22c523f..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/main/test_app_main.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "unity.h" -#include "unity_test_runner.h" -#include "esp_heap_caps.h" - -#define TEST_MEMORY_LEAK_THRESHOLD (-400) - -static size_t before_free_8bit; -static size_t before_free_32bit; - -static void check_leak(size_t before_free, size_t after_free, const char *type) -{ - ssize_t delta = after_free - before_free; - printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); - TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); -} - -void setUp(void) -{ - before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); -} - -void tearDown(void) -{ - size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); - check_leak(before_free_8bit, after_free_8bit, "8BIT"); - check_leak(before_free_32bit, after_free_32bit, "32BIT"); -} - -void app_main(void) -{ - unity_run_menu(); -} diff --git a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c deleted file mode 100644 index 9f15c8fb58..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -#include -#include -#include "unity.h" -#include "esp_log.h" -#include "driver/adc.h" -#include "driver/gpio.h" -#include "driver/rtc_io.h" -#include "soc/adc_periph.h" -#include "hal/adc_ll.h" - -#define ADC_GET_IO_NUM(unit, channel) (adc_channel_io_map[unit][channel]) - -/** - * We use weak pulldown, `ADC_TEST_LOW_THRESH` may vary. - * If connect to GND, `ADC_TEST_LOW_THRESH` will usually within 10 - */ -#if CONFIG_IDF_TARGET_ESP32 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 10 - -#define ADC_TEST_HIGH_VAL 4095 -#define ADC_TEST_HIGH_THRESH 10 - -#elif CONFIG_IDF_TARGET_ESP32S2 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 35 - -#define ADC_TEST_HIGH_VAL 8191 -#define ADC_TEST_HIGH_THRESH 10 - -#elif CONFIG_IDF_TARGET_ESP32C3 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 60 //This is due to ADC2 accuracy is not as good as ADC1, and also we use weak pulldown - -#define ADC_TEST_HIGH_VAL 4095 -#define ADC_TEST_HIGH_THRESH 10 - -#elif CONFIG_IDF_TARGET_ESP32S3 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 15 - -#define ADC_TEST_HIGH_VAL 4095 -#define ADC_TEST_HIGH_THRESH 0 - -#elif CONFIG_IDF_TARGET_ESP32C2 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 15 - -#define ADC_TEST_HIGH_VAL 3400 -#define ADC_TEST_HIGH_THRESH 200 - -#elif CONFIG_IDF_TARGET_ESP32C6 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 15 - -#define ADC_TEST_HIGH_VAL 3350 -#define ADC_TEST_HIGH_THRESH 200 - -#elif CONFIG_IDF_TARGET_ESP32H2 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 17 - -#define ADC_TEST_HIGH_VAL 3390 -#define ADC_TEST_HIGH_THRESH 200 - -#elif CONFIG_IDF_TARGET_ESP32P4 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 10 - -#define ADC_TEST_HIGH_VAL 3360 -#define ADC_TEST_HIGH_THRESH 200 - -#elif CONFIG_IDF_TARGET_ESP32C5 -#define ADC_TEST_LOW_VAL 0 -#define ADC_TEST_LOW_THRESH 17 - -#define ADC_TEST_HIGH_VAL 3375 -#define ADC_TEST_HIGH_THRESH 200 - -#elif CONFIG_IDF_TARGET_ESP32C61 -#define ADC_TEST_LOW_VAL 2140 -#define ADC_TEST_LOW_THRESH 200 - -#define ADC_TEST_HIGH_VAL 4095 -#define ADC_TEST_HIGH_THRESH 200 - -#endif - -//ADC Channels -#if CONFIG_IDF_TARGET_ESP32 -#define ADC1_TEST_CHAN0 ADC1_CHANNEL_4 -#define ADC2_TEST_CHAN0 ADC2_CHANNEL_0 -#elif (SOC_ADC_PERIPH_NUM >= 2) -#define ADC1_TEST_CHAN0 ADC1_CHANNEL_2 -#define ADC2_TEST_CHAN0 ADC2_CHANNEL_0 -#else -#define ADC1_TEST_CHAN0 ADC1_CHANNEL_2 -#endif - -//ESP32C3 ADC2 oneshot mode is not supported anymore -#define ADC_TEST_ADC2 ((SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3) - -const __attribute__((unused)) static char *TAG = "TEST_ADC_LEGACY"; - -void test_adc_set_io_level(adc_unit_t unit, adc_channel_t channel, bool level) -{ - TEST_ASSERT(channel < SOC_ADC_CHANNEL_NUM(unit) && "invalid channel"); - - uint32_t io_num = ADC_GET_IO_NUM(unit, channel); - TEST_ESP_OK(gpio_set_pull_mode(io_num, (level ? GPIO_PULLUP_ONLY : GPIO_PULLDOWN_ONLY))); -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED - if (rtc_gpio_is_valid_gpio(io_num)) { - if (level) { - TEST_ESP_OK(rtc_gpio_pullup_en(io_num)); - TEST_ESP_OK(rtc_gpio_pulldown_dis(io_num)); - } else { - TEST_ESP_OK(rtc_gpio_pullup_dis(io_num)); - TEST_ESP_OK(rtc_gpio_pulldown_en(io_num)); - } - } -#endif -} - -TEST_CASE("Legacy ADC oneshot high/low test", "[legacy_adc_oneshot]") -{ - int adc_raw = 0; - //ADC1 config - TEST_ESP_OK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT)); - TEST_ESP_OK(adc1_config_channel_atten(ADC1_TEST_CHAN0, ADC_ATTEN_DB_12)); -#if ADC_TEST_ADC2 - //ADC2 config - TEST_ESP_OK(adc2_config_channel_atten(ADC2_TEST_CHAN0, ADC_ATTEN_DB_12)); -#endif - - test_adc_set_io_level(ADC_UNIT_1, (adc1_channel_t)ADC1_TEST_CHAN0, 0); - adc_raw = adc1_get_raw(ADC1_TEST_CHAN0); - ESP_LOGI(TAG, "ADC%d Channel %d raw: %d", ADC_UNIT_1 + 1, ADC1_TEST_CHAN0, adc_raw); - TEST_ASSERT_INT_WITHIN(ADC_TEST_LOW_THRESH, ADC_TEST_LOW_VAL, adc_raw); - - test_adc_set_io_level(ADC_UNIT_1, (adc1_channel_t)ADC1_TEST_CHAN0, 1); - adc_raw = adc1_get_raw(ADC1_TEST_CHAN0); - ESP_LOGI(TAG, "ADC%d Channel %d raw: %d", ADC_UNIT_1 + 1, ADC1_TEST_CHAN0, adc_raw); - TEST_ASSERT_INT_WITHIN(ADC_TEST_HIGH_THRESH, ADC_TEST_HIGH_VAL, adc_raw); - -#if ADC_TEST_ADC2 - test_adc_set_io_level(ADC_UNIT_2, (adc2_channel_t)ADC2_TEST_CHAN0, 0); - TEST_ESP_OK(adc2_get_raw(ADC2_TEST_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc_raw)); - ESP_LOGI(TAG, "ADC%d Channel %d raw: %d", ADC_UNIT_2 + 1, ADC2_TEST_CHAN0, adc_raw); - TEST_ASSERT_INT_WITHIN(ADC_TEST_LOW_THRESH, ADC_TEST_LOW_VAL, adc_raw); - - test_adc_set_io_level(ADC_UNIT_2, (adc2_channel_t)ADC2_TEST_CHAN0, 1); - TEST_ESP_OK(adc2_get_raw(ADC2_TEST_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc_raw)); - ESP_LOGI(TAG, "ADC%d Channel %d raw: %d", ADC_UNIT_2 + 1, ADC2_TEST_CHAN0, adc_raw); - TEST_ASSERT_INT_WITHIN(ADC_TEST_HIGH_THRESH, ADC_TEST_HIGH_VAL, adc_raw); -#endif -} diff --git a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py b/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py deleted file mode 100644 index a7acc58b25..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: CC0-1.0 -import pytest -from pytest_embedded import Dut -from pytest_embedded_idf.utils import idf_parametrize - - -@pytest.mark.adc -@pytest.mark.parametrize( - 'config', - [ - 'release', - ], - indirect=True, -) -@idf_parametrize( - 'target', - ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32c5', 'esp32p4'], - indirect=['target'], -) -def test_legacy_adc(dut: Dut) -> None: - dut.run_all_single_board_cases() - - -@pytest.mark.adc -@pytest.mark.xtal_26mhz -@pytest.mark.parametrize( - 'config, baud', - [ - ('esp32c2_xtal26m_release', '74880'), - ], - indirect=True, -) -@idf_parametrize('target', ['esp32c2'], indirect=['target']) -def test_legacy_adc_esp32c2_xtal_26mhz(dut: Dut) -> None: - dut.run_all_single_board_cases() diff --git a/components/driver/test_apps/legacy_adc_driver/sdkconfig.ci.esp32c2_xtal26m_release b/components/driver/test_apps/legacy_adc_driver/sdkconfig.ci.esp32c2_xtal26m_release deleted file mode 100644 index 493256fa2f..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/sdkconfig.ci.esp32c2_xtal26m_release +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_IDF_TARGET="esp32c2" -CONFIG_XTAL_FREQ_26=y - -CONFIG_PM_ENABLE=y -CONFIG_FREERTOS_USE_TICKLESS_IDLE=y -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/driver/test_apps/legacy_adc_driver/sdkconfig.ci.release b/components/driver/test_apps/legacy_adc_driver/sdkconfig.ci.release deleted file mode 100644 index 91d93f163e..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/sdkconfig.ci.release +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_PM_ENABLE=y -CONFIG_FREERTOS_USE_TICKLESS_IDLE=y -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/driver/test_apps/legacy_adc_driver/sdkconfig.defaults b/components/driver/test_apps/legacy_adc_driver/sdkconfig.defaults deleted file mode 100644 index 88d4fecf25..0000000000 --- a/components/driver/test_apps/legacy_adc_driver/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT_EN=n -CONFIG_ADC_SUPPRESS_DEPRECATE_WARN=y diff --git a/components/esp_adc/CMakeLists.txt b/components/esp_adc/CMakeLists.txt index bf0f1330c2..d52d3c70dd 100644 --- a/components/esp_adc/CMakeLists.txt +++ b/components/esp_adc/CMakeLists.txt @@ -4,7 +4,7 @@ if(${target} STREQUAL "linux") return() # This component is not supported by the POSIX/Linux simulator endif() -set(includes "include" "interface" "${target}/include" "deprecated/include") +set(includes "include" "interface" "${target}/include") set(srcs) @@ -14,7 +14,6 @@ if(CONFIG_SOC_ADC_SUPPORTED) "adc_common.c" "adc_cali.c" "adc_cali_curve_fitting.c" - "deprecated/esp_adc_cal_common_legacy.c" ) if(CONFIG_SOC_ADC_DMA_SUPPORTED) @@ -46,11 +45,6 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${target}/curve_fitting_coefficients.c") list(APPEND srcs "${target}/curve_fitting_coefficients.c") endif() -# legacy calibration driver -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/deprecated/${target}/esp_adc_cal_legacy.c") - list(APPEND srcs "deprecated/${target}/esp_adc_cal_legacy.c") -endif() - set(extra_requires) idf_build_get_property(target IDF_TARGET) if(${target} STREQUAL "esp32") @@ -60,8 +54,6 @@ if(${target} STREQUAL "esp32s2") list(APPEND extra_requires esp_driver_spi) endif() -list(APPEND extra_requires driver) # esp_adc depends on "driver/adc_types_legacy.h" - idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} PRIV_REQUIRES esp_driver_gpio efuse esp_pm esp_ringbuf esp_mm ${extra_requires} diff --git a/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c deleted file mode 100644 index 68c46e534b..0000000000 --- a/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include "esp_types.h" -#include "esp_err.h" -#include "esp_check.h" -#include "assert.h" -#include "hal/efuse_ll.h" -#include "hal/adc_types.h" -#include "driver/adc_types_legacy.h" -#include "esp_adc_cal_types_legacy.h" - -/* ----------------------------- Configuration ------------------------------ */ -#ifdef CONFIG_ADC_CAL_EFUSE_TP_ENABLE -#define EFUSE_TP_ENABLED 1 -#else -#define EFUSE_TP_ENABLED 0 -#endif - -#ifdef CONFIG_ADC_CAL_EFUSE_VREF_ENABLE -#define EFUSE_VREF_ENABLED 1 -#else -#define EFUSE_VREF_ENABLED 0 -#endif - -#ifdef CONFIG_ADC_CAL_LUT_ENABLE -#define LUT_ENABLED 1 -#else -#define LUT_ENABLED 0 -#endif - -/* ESP32s with both Two Point Values and Vref burned into eFuse are required to - * also also burn the EFUSE_BLK3_PART_RESERVE flag. A limited set of ESP32s - * (not available through regular sales channel) DO NOT have the - * EFUSE_BLK3_PART_RESERVE burned. Moreover, this set of ESP32s represents Vref - * in Two's Complement format. If this is the case, modify the preprocessor - * definitions below as follows... - * #define CHECK_BLK3_FLAG 0 //Do not check BLK3 flag as it is not burned - * #define VREF_FORMAT 1 //eFuse Vref is in Two's Complement format - */ -#define CHECK_BLK3_FLAG 1 -#define VREF_FORMAT 0 - -/* ------------------------------ eFuse Access ----------------------------- */ -#define VREF_MASK 0x1F -#define VREF_STEP_SIZE 7 -#define VREF_OFFSET 1100 - -#define TP_LOW1_OFFSET 278 -#define TP_LOW2_OFFSET 421 -#define TP_LOW_MASK 0x7F -#define TP_LOW_VOLTAGE 150 -#define TP_HIGH1_OFFSET 3265 -#define TP_HIGH2_OFFSET 3406 -#define TP_HIGH_MASK 0x1FF -#define TP_HIGH_VOLTAGE 850 -#define TP_STEP_SIZE 4 - -/* ----------------------- Raw to Voltage Constants ------------------------- */ -#define LIN_COEFF_A_SCALE 65536 -#define LIN_COEFF_A_ROUND (LIN_COEFF_A_SCALE/2) - -#define LUT_VREF_LOW 1000 -#define LUT_VREF_HIGH 1200 -#define LUT_ADC_STEP_SIZE 64 -#define LUT_POINTS 20 -#define LUT_LOW_THRESH 2880 -#define LUT_HIGH_THRESH (LUT_LOW_THRESH + LUT_ADC_STEP_SIZE) -#define ADC_12_BIT_RES 4096 - -/* ------------------------ Characterization Constants ---------------------- */ -static const uint32_t adc1_tp_atten_scale[4] = {65504, 86975, 120389, 224310}; -static const uint32_t adc2_tp_atten_scale[4] = {65467, 86861, 120416, 224708}; -static const uint32_t adc1_tp_atten_offset[4] = {0, 1, 27, 54}; -static const uint32_t adc2_tp_atten_offset[4] = {0, 9, 26, 66}; - -static const uint32_t adc1_vref_atten_scale[4] = {57431, 76236, 105481, 196602}; -static const uint32_t adc2_vref_atten_scale[4] = {57236, 76175, 105678, 197170}; -static const uint32_t adc1_vref_atten_offset[4] = {75, 78, 107, 142}; -static const uint32_t adc2_vref_atten_offset[4] = {63, 66, 89, 128}; - -//20 Point lookup tables, covering ADC readings from 2880 to 4096, step size of 64 -static const uint32_t lut_adc1_low[LUT_POINTS] = {2240, 2297, 2352, 2405, 2457, 2512, 2564, 2616, 2664, 2709, - 2754, 2795, 2832, 2868, 2903, 2937, 2969, 3000, 3030, 3060 - }; -static const uint32_t lut_adc1_high[LUT_POINTS] = {2667, 2706, 2745, 2780, 2813, 2844, 2873, 2901, 2928, 2956, - 2982, 3006, 3032, 3059, 3084, 3110, 3135, 3160, 3184, 3209 - }; -static const uint32_t lut_adc2_low[LUT_POINTS] = {2238, 2293, 2347, 2399, 2451, 2507, 2561, 2613, 2662, 2710, - 2754, 2792, 2831, 2869, 2904, 2937, 2968, 2999, 3029, 3059 - }; -static const uint32_t lut_adc2_high[LUT_POINTS] = {2657, 2698, 2738, 2774, 2807, 2838, 2867, 2894, 2921, 2946, - 2971, 2996, 3020, 3043, 3067, 3092, 3116, 3139, 3162, 3185 - }; - -/* ----------------------- EFuse Access Functions --------------------------- */ -static bool check_efuse_vref(void) -{ - //Check if Vref is burned in eFuse - return (efuse_ll_get_adc_vref() != 0) ? true : false; -} - -static bool check_efuse_tp(void) -{ - //Check if Two Point values are burned in eFuse - if (CHECK_BLK3_FLAG && (efuse_ll_get_blk3_part_reserve() == 0)) { - return false; - } - //All TP cal values must be non zero - return efuse_ll_get_adc1_tp_low() && - efuse_ll_get_adc2_tp_low() && - efuse_ll_get_adc1_tp_high() && - efuse_ll_get_adc2_tp_high(); -} - -static inline int decode_bits(uint32_t bits, uint32_t mask, bool is_twos_compl) -{ - int ret; - if (bits & (~(mask >> 1) & mask)) { //Check sign bit (MSB of mask) - //Negative - if (is_twos_compl) { - ret = -(((~bits) + 1) & (mask >> 1)); //2's complement - } else { - ret = -(bits & (mask >> 1)); //Sign-magnitude - } - } else { - //Positive - ret = bits & (mask >> 1); - } - return ret; -} - -static uint32_t read_efuse_vref(void) -{ - //eFuse stores deviation from ideal reference voltage - uint32_t ret = VREF_OFFSET; //Ideal vref - uint32_t bits = efuse_ll_get_adc_vref(); - ret += decode_bits(bits, VREF_MASK, VREF_FORMAT) * VREF_STEP_SIZE; - return ret; //ADC Vref in mV -} - -static uint32_t read_efuse_tp_low(adc_unit_t adc_num) -{ - //ADC reading at 150mV stored in two's complement format - uint32_t ret; - uint32_t bits; - - if (adc_num == ADC_UNIT_1) { - ret = TP_LOW1_OFFSET; - bits = efuse_ll_get_adc1_tp_low(); - } else { - ret = TP_LOW2_OFFSET; - bits = efuse_ll_get_adc2_tp_low(); - } - ret += decode_bits(bits, TP_LOW_MASK, true) * TP_STEP_SIZE; - return ret; //Reading of ADC at 150mV -} - -static uint32_t read_efuse_tp_high(adc_unit_t adc_num) -{ - //ADC reading at 850mV stored in two's complement format - uint32_t ret; - uint32_t bits; - - if (adc_num == ADC_UNIT_1) { - ret = TP_HIGH1_OFFSET; - bits = efuse_ll_get_adc1_tp_high(); - } else { - ret = TP_HIGH2_OFFSET; - bits = efuse_ll_get_adc2_tp_high(); - } - ret += decode_bits(bits, TP_HIGH_MASK, true) * TP_STEP_SIZE; - return ret; //Reading of ADC at 850mV -} - -/* ----------------------- Characterization Functions ----------------------- */ -static void characterize_using_two_point(adc_unit_t adc_num, - adc_atten_t atten, - uint32_t high, - uint32_t low, - uint32_t *coeff_a, - uint32_t *coeff_b) -{ - const uint32_t *atten_scales; - const uint32_t *atten_offsets; - - if (adc_num == ADC_UNIT_1) { //Using ADC 1 - atten_scales = adc1_tp_atten_scale; - atten_offsets = adc1_tp_atten_offset; - } else { //Using ADC 2 - atten_scales = adc2_tp_atten_scale; - atten_offsets = adc2_tp_atten_offset; - } - //Characterize ADC-Voltage curve as y = (coeff_a * x) + coeff_b - uint32_t delta_x = high - low; - uint32_t delta_v = TP_HIGH_VOLTAGE - TP_LOW_VOLTAGE; - //Where coeff_a = (delta_v/delta_x) * atten_scale - *coeff_a = (delta_v * atten_scales[atten] + (delta_x / 2)) / delta_x; //+(delta_x/2) for rounding - //Where coeff_b = high_v - ((delta_v/delta_x) * high_x) + atten_offset - *coeff_b = TP_HIGH_VOLTAGE - ((delta_v * high + (delta_x / 2)) / delta_x) + atten_offsets[atten]; -} - -static void characterize_using_vref(adc_unit_t adc_num, - adc_atten_t atten, - uint32_t vref, - uint32_t *coeff_a, - uint32_t *coeff_b) -{ - const uint32_t *atten_scales; - const uint32_t *atten_offsets; - - if (adc_num == ADC_UNIT_1) { //Using ADC 1 - atten_scales = adc1_vref_atten_scale; - atten_offsets = adc1_vref_atten_offset; - } else { //Using ADC 2 - atten_scales = adc2_vref_atten_scale; - atten_offsets = adc2_vref_atten_offset; - } - //Characterize ADC-Voltage curve as y = (coeff_a * x) + coeff_b - //Where coeff_a = (vref/4096) * atten_scale - *coeff_a = (vref * atten_scales[atten]) / (ADC_12_BIT_RES); - *coeff_b = atten_offsets[atten]; -} - -/* ------------------------ Conversion Functions --------------------------- */ -static uint32_t calculate_voltage_linear(uint32_t adc_reading, uint32_t coeff_a, uint32_t coeff_b) -{ - //Where voltage = coeff_a * adc_reading + coeff_b - return (((coeff_a * adc_reading) + LIN_COEFF_A_ROUND) / LIN_COEFF_A_SCALE) + coeff_b; -} - -//Only call when ADC reading is above threshold -static uint32_t calculate_voltage_lut(uint32_t adc, uint32_t vref, const uint32_t *low_vref_curve, const uint32_t *high_vref_curve) -{ - //Get index of lower bound points of LUT - uint32_t i = (adc - LUT_LOW_THRESH) / LUT_ADC_STEP_SIZE; - - //Let the X Axis be Vref, Y axis be ADC reading, and Z be voltage - int x2dist = LUT_VREF_HIGH - vref; //(x2 - x) - int x1dist = vref - LUT_VREF_LOW; //(x - x1) - int y2dist = ((i + 1) * LUT_ADC_STEP_SIZE) + LUT_LOW_THRESH - adc; //(y2 - y) - int y1dist = adc - ((i * LUT_ADC_STEP_SIZE) + LUT_LOW_THRESH); //(y - y1) - - //For points for bilinear interpolation - int q11 = low_vref_curve[i]; //Lower bound point of low_vref_curve - int q12 = low_vref_curve[i + 1]; //Upper bound point of low_vref_curve - int q21 = high_vref_curve[i]; //Lower bound point of high_vref_curve - int q22 = high_vref_curve[i + 1]; //Upper bound point of high_vref_curve - - //Bilinear interpolation - //Where z = 1/((x2-x1)*(y2-y1)) * ( (q11*x2dist*y2dist) + (q21*x1dist*y2dist) + (q12*x2dist*y1dist) + (q22*x1dist*y1dist) ) - int voltage = (q11 * x2dist * y2dist) + (q21 * x1dist * y2dist) + (q12 * x2dist * y1dist) + (q22 * x1dist * y1dist); - voltage += ((LUT_VREF_HIGH - LUT_VREF_LOW) * LUT_ADC_STEP_SIZE) / 2; //Integer division rounding - voltage /= ((LUT_VREF_HIGH - LUT_VREF_LOW) * LUT_ADC_STEP_SIZE); //Divide by ((x2-x1)*(y2-y1)) - return (uint32_t)voltage; -} - -static inline uint32_t interpolate_two_points(uint32_t y1, uint32_t y2, uint32_t x_step, uint32_t x) -{ - //Interpolate between two points (x1,y1) (x2,y2) between 'lower' and 'upper' separated by 'step' - return ((y1 * x_step) + (y2 * x) - (y1 * x) + (x_step / 2)) / x_step; -} - -/* ------------------------- Public API ------------------------------------- */ -esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t source) -{ - if (source == ESP_ADC_CAL_VAL_EFUSE_TP) { - return (check_efuse_tp()) ? ESP_OK : ESP_ERR_NOT_SUPPORTED; - } else if (source == ESP_ADC_CAL_VAL_EFUSE_VREF) { - return (check_efuse_vref()) ? ESP_OK : ESP_ERR_NOT_SUPPORTED; - } else { - return ESP_ERR_INVALID_ARG; - } -} - -esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, - adc_atten_t atten, - adc_bits_width_t bit_width, - uint32_t default_vref, - esp_adc_cal_characteristics_t *chars) -{ - //Check parameters - assert((adc_num == ADC_UNIT_1) || (adc_num == ADC_UNIT_2)); - assert(chars != NULL); - assert(bit_width < ADC_WIDTH_MAX); - - //Check eFuse if enabled to do so - bool efuse_tp_present = check_efuse_tp(); - bool efuse_vref_present = check_efuse_vref(); - esp_adc_cal_value_t ret; - - if (efuse_tp_present && EFUSE_TP_ENABLED) { - //Characterize based on Two Point values - uint32_t high = read_efuse_tp_high(adc_num); - uint32_t low = read_efuse_tp_low(adc_num); - characterize_using_two_point(adc_num, atten, high, low, &chars->coeff_a, &chars->coeff_b); - ret = ESP_ADC_CAL_VAL_EFUSE_TP; - } else if (efuse_vref_present && EFUSE_VREF_ENABLED) { - //Characterize based on eFuse Vref - uint32_t vref = read_efuse_vref(); - characterize_using_vref(adc_num, atten, vref, &chars->coeff_a, &chars->coeff_b); - ret = ESP_ADC_CAL_VAL_EFUSE_VREF; - } else { - //Characterized based on default Vref - characterize_using_vref(adc_num, atten, default_vref, &chars->coeff_a, &chars->coeff_b); - ret = ESP_ADC_CAL_VAL_DEFAULT_VREF; - } - - //Initialized remaining fields - chars->adc_num = adc_num; - chars->atten = atten; - chars->bit_width = bit_width; - chars->vref = (EFUSE_VREF_ENABLED && efuse_vref_present) ? read_efuse_vref() : default_vref; - //Initialize fields for lookup table if necessary - if (LUT_ENABLED && atten == ADC_ATTEN_DB_12) { - chars->low_curve = (adc_num == ADC_UNIT_1) ? lut_adc1_low : lut_adc2_low; - chars->high_curve = (adc_num == ADC_UNIT_1) ? lut_adc1_high : lut_adc2_high; - } else { - chars->low_curve = NULL; - chars->high_curve = NULL; - } - return ret; -} - -uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars) -{ - assert(chars != NULL); - - //Scale adc_rading if not 12 bits wide - adc_reading = (adc_reading << (ADC_WIDTH_BIT_12 - chars->bit_width)); - if (adc_reading > ADC_12_BIT_RES - 1) { - adc_reading = ADC_12_BIT_RES - 1; //Set to 12bit res max - } - - if (LUT_ENABLED && (chars->atten == ADC_ATTEN_DB_12) && (adc_reading >= LUT_LOW_THRESH)) { //Check if in non-linear region - //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_12 - uint32_t lut_voltage = calculate_voltage_lut(adc_reading, chars->vref, chars->low_curve, chars->high_curve); - if (adc_reading <= LUT_HIGH_THRESH) { //If ADC is transitioning from linear region to non-linear region - //Linearly interpolate between linear voltage and lut voltage - uint32_t linear_voltage = calculate_voltage_linear(adc_reading, chars->coeff_a, chars->coeff_b); - return interpolate_two_points(linear_voltage, lut_voltage, LUT_ADC_STEP_SIZE, (adc_reading - LUT_LOW_THRESH)); - } else { - return lut_voltage; - } - } else { - return calculate_voltage_linear(adc_reading, chars->coeff_a, chars->coeff_b); - } -} diff --git a/components/esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c deleted file mode 100644 index 02bc42564f..0000000000 --- a/components/esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include "esp_types.h" -#include "esp_err.h" -#include "esp_log.h" -#include "esp_check.h" -#include "esp_efuse_rtc_calib.h" -#include "hal/adc_ll.h" -#include "hal/adc_types.h" -#include "driver/adc_types_legacy.h" -#include "esp_adc_cal_types_legacy.h" -#include "../esp_adc_cal_internal_legacy.h" - -const static char LOG_TAG[] = "ADC_CALI"; - -/* ------------------------ Characterization Constants ---------------------- */ - -// coeff_a is actually a float number -// it is scaled to put them into uint32_t so that the headers do not have to be changed -static const int coeff_a_scaling = 65536; - -/** - * @note Error Calculation - * Coefficients for calculating the reading voltage error. - * Four sets of coefficients for atten0 ~ atten3 respectively. - * - * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. - * - * @note {0,0} stands for unused item - * @note In case of the overflow, these coefficients are recorded as Absolute Value - * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); - * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. - * @note ADC1 and ADC2 use same coefficients - */ -const static uint64_t adc_error_coef_atten[4][5][2] = { - {{225966470500043, 1e15}, {7265418501948, 1e16}, {109410402681, 1e16}, {0, 0}, {0, 0}}, //atten0 - {{4229623392600516, 1e16}, {731527490903, 1e16}, {88166562521, 1e16}, {0, 0}, {0, 0}}, //atten1 - {{1017859239236435, 1e15}, {97159265299153, 1e16}, {149794028038, 1e16}, {0, 0}, {0, 0}}, //atten2 - {{14912262772850453, 1e16}, {228549975564099, 1e16}, {356391935717, 1e16}, {179964582, 1e16}, {42046, 1e16}} //atten3 -}; -/** - * Term sign - * @note ADC1 and ADC2 use same coefficients - */ -const static int32_t adc_error_sign[4][5] = { - {-1, -1, 1, 0, 0}, //atten0 - { 1, -1, 1, 0, 0}, //atten1 - {-1, -1, 1, 0, 0}, //atten2 - {-1, -1, 1, -1, 1} //atten3 -}; - -/* -------------------- Characterization Helper Data Types ------------------ */ -typedef struct { - uint32_t voltage; - uint32_t digi; -} adc_calib_data_ver1; - -typedef struct { - char version_num; - adc_unit_t adc_num; - adc_atten_t atten_level; - union { - adc_calib_data_ver1 ver1; - } efuse_data; -} adc_calib_parsed_info_t; - -static esp_err_t prepare_calib_data_for(int version_num, adc_unit_t adc_num, adc_atten_t atten, adc_calib_parsed_info_t *parsed_data_storage) -{ - assert(version_num == 1); - esp_err_t ret; - - parsed_data_storage->version_num = version_num; - parsed_data_storage->adc_num = adc_num; - parsed_data_storage->atten_level = atten; - uint32_t voltage, digi; - /** - * V1 we don't have calibration data for ADC2, using the efuse data of ADC1. - * Here passing the `adc_num` is just for compatibility - */ - ret = esp_efuse_rtc_calib_get_cal_voltage(version_num, adc_num, atten, &digi, &voltage); - if (ret != ESP_OK) { - return ret; - } - parsed_data_storage->efuse_data.ver1.voltage = voltage; - parsed_data_storage->efuse_data.ver1.digi = digi; - return ret; -} - -/* ----------------------- Characterization Functions ----------------------- */ -/* - * Estimate the (assumed) linear relationship btwn the measured raw value and the voltage - * with the previously done measurement when the chip was manufactured. - */ -static void calculate_characterization_coefficients(const adc_calib_parsed_info_t *parsed_data, esp_adc_cal_characteristics_t *chars) -{ - ESP_LOGD(LOG_TAG, "Calib V1, Cal Voltage = %"PRId32", Digi out = %"PRId32, parsed_data->efuse_data.ver1.voltage, parsed_data->efuse_data.ver1.digi); - - chars->coeff_a = coeff_a_scaling * parsed_data->efuse_data.ver1.voltage / parsed_data->efuse_data.ver1.digi; - chars->coeff_b = 0; -} - -/* ------------------------- Public API ------------------------------------- */ -esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t source) -{ - if (source != ESP_ADC_CAL_VAL_EFUSE_TP) { - return ESP_ERR_NOT_SUPPORTED; - } - uint8_t adc_encoding_version = esp_efuse_rtc_calib_get_ver(); - if (adc_encoding_version != 1) { - // current version only accepts encoding ver 1. - return ESP_ERR_INVALID_VERSION; - } - return ESP_OK; -} - -esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, - adc_atten_t atten, - adc_bits_width_t bit_width, - uint32_t default_vref, - esp_adc_cal_characteristics_t *chars) -{ - esp_err_t ret; - adc_calib_parsed_info_t efuse_parsed_data = {0}; - // Check parameters - ESP_RETURN_ON_FALSE(adc_num == ADC_UNIT_1 || adc_num == ADC_UNIT_2, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid unit num"); - ESP_RETURN_ON_FALSE(chars != NULL, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid characteristic"); - ESP_RETURN_ON_FALSE(bit_width == ADC_WIDTH_BIT_12, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid bit_width"); - ESP_RETURN_ON_FALSE(atten < SOC_ADC_ATTEN_NUM, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid attenuation"); - - int version_num = esp_efuse_rtc_calib_get_ver(); - ESP_RETURN_ON_FALSE(version_num == 1, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "No calibration efuse burnt"); - - memset(chars, 0, sizeof(esp_adc_cal_characteristics_t)); - - // make sure adc is calibrated. - ret = prepare_calib_data_for(version_num, adc_num, atten, &efuse_parsed_data); - if (ret != ESP_OK) { - abort(); - } - - calculate_characterization_coefficients(&efuse_parsed_data, chars); - ESP_LOGD(LOG_TAG, "adc%d (atten leven %d) calibration done: A:%"PRId32" B:%"PRId32, adc_num, atten, chars->coeff_a, chars->coeff_b); - - // Initialize remaining fields - chars->adc_num = adc_num; - chars->atten = atten; - chars->bit_width = bit_width; - - // in esp32c3 we only use the two point method to calibrate the adc. - return ESP_ADC_CAL_VAL_EFUSE_TP; -} - -uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars) -{ - assert(chars != NULL); - - int32_t error = 0; - uint64_t v_cali_1 = (uint64_t)adc_reading * chars->coeff_a / coeff_a_scaling; - esp_adc_error_calc_param_t param = { - .v_cali_input = v_cali_1, - .term_num = (chars->atten == 3) ? 5 : 3, - .coeff = &adc_error_coef_atten, - .sign = &adc_error_sign, - }; - error = esp_adc_cal_get_reading_error(¶m, chars->atten); - - return (int32_t)v_cali_1 - error; -} diff --git a/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c deleted file mode 100644 index c59f27ad90..0000000000 --- a/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include "esp_types.h" -#include "soc/efuse_periph.h" -#include "esp_err.h" -#include "esp_check.h" -#include "assert.h" -#include "esp_efuse.h" -#include "esp_efuse_table.h" -#include "esp_efuse_rtc_table.h" -#include "hal/adc_hal.h" -#include "hal/adc_types.h" -#include "driver/adc_types_legacy.h" -#include "esp_adc_cal_types_legacy.h" - -const static char LOG_TAG[] = "adc_calib"; - -/* ------------------------ Characterization Constants ---------------------- */ - -// coeff_a and coeff_b are actually floats -// they are scaled to put them into uint32_t so that the headers do not have to be changed -static const int coeff_a_scaling = 65536; -static const int coeff_b_scaling = 1024; -/* -------------------- Characterization Helper Data Types ------------------ */ -typedef struct { - int adc_calib_high; - int adc_calib_low; -} adc_calib_data_ver1; - -typedef struct { - int adc_calib_high; // the reading of adc ... - int adc_calib_high_voltage; // ... at this voltage (mV) -} adc_calib_data_ver2; - -typedef struct { - char version_num; - adc_unit_t adc_num; - adc_atten_t atten_level; - union { - adc_calib_data_ver1 ver1; - adc_calib_data_ver2 ver2; - } efuse_data; -} adc_calib_parsed_info; - -static bool prepare_calib_data_for(adc_unit_t adc_num, adc_atten_t atten, adc_calib_parsed_info *parsed_data_storage) -{ - int version_num = esp_efuse_rtc_table_read_calib_version(); - int tag; - parsed_data_storage->version_num = version_num; - parsed_data_storage->adc_num = adc_num; - parsed_data_storage->atten_level = atten; - switch (version_num) { - case 1: - // note: use the adc_num as in hal, which start from 0. - tag = esp_efuse_rtc_table_get_tag(version_num, adc_num, atten, RTCCALIB_V1_PARAM_VLOW); - parsed_data_storage->efuse_data.ver1.adc_calib_low = esp_efuse_rtc_table_get_parsed_efuse_value(tag, false); - tag = esp_efuse_rtc_table_get_tag(version_num, adc_num, atten, RTCCALIB_V1_PARAM_VHIGH); - parsed_data_storage->efuse_data.ver1.adc_calib_high = esp_efuse_rtc_table_get_parsed_efuse_value(tag, false); - break; - case 2: - tag = esp_efuse_rtc_table_get_tag(version_num, adc_num, atten, RTCCALIB_V2_PARAM_VHIGH); - parsed_data_storage->efuse_data.ver2.adc_calib_high = esp_efuse_rtc_table_get_parsed_efuse_value(tag, false); - switch (parsed_data_storage->atten_level) { - case ADC_ATTEN_DB_0: - parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 600; - break; - case ADC_ATTEN_DB_2_5: - parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 800; - break; - case ADC_ATTEN_DB_6: - parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 1000; - break; - case ADC_ATTEN_DB_12: - parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 2000; - break; - default: - break; - } - break; - default: - // fall back to case 1 with zeros as params. - parsed_data_storage->version_num = 1; - tag = esp_efuse_rtc_table_get_tag(version_num, adc_num, atten, RTCCALIB_V1_PARAM_VLOW); - parsed_data_storage->efuse_data.ver1.adc_calib_high = esp_efuse_rtc_table_get_parsed_efuse_value(tag, true); - tag = esp_efuse_rtc_table_get_tag(version_num, adc_num, atten, RTCCALIB_V1_PARAM_VHIGH); - parsed_data_storage->efuse_data.ver1.adc_calib_low = esp_efuse_rtc_table_get_parsed_efuse_value(tag, true); - break; - } - return true; -} - -/* ----------------------- Characterization Functions ----------------------- */ -/** - * (Used in V1 of calibration scheme) - * The Two Point calibration measures the reading at two specific input voltages, and calculates the (assumed linear) relation - * between input voltage and ADC response. (Response = A * Vinput + B) - * A and B are scaled ints. - * @param high The ADC response at the higher voltage of the corresponding attenuation (600mV, 800mV, 1000mV, 2000mV). - * @param low The ADC response at the lower voltage of the corresponding attenuation (all 250mV). - * - */ -static void characterize_using_two_point(adc_unit_t adc_num, - adc_atten_t atten, - uint32_t high, - uint32_t low, - uint32_t *coeff_a, - uint32_t *coeff_b) -{ - // once we have recovered the reference high(Dhigh) and low(Dlow) readings, we can calculate a and b from - // the measured high and low readings - static const uint32_t v_high[] = {600, 800, 1000, 2000}; - static const uint32_t v_low = 250; - *coeff_a = coeff_a_scaling * (v_high[atten] - v_low) / (high - low); - *coeff_b = coeff_b_scaling * (v_low * high - v_high[atten] * low) / (high - low); -} - -/* - * Estimate the (assumed) linear relationship btwn the measured raw value and the voltage - * with the previously done measurement when the chip was manufactured. - * */ -static bool calculate_characterization_coefficients(const adc_calib_parsed_info *parsed_data, esp_adc_cal_characteristics_t *chars) -{ - switch (parsed_data->version_num) { - case 1: - ESP_LOGD(LOG_TAG, "Calib V1, low%dmV, high%dmV", parsed_data->efuse_data.ver1.adc_calib_low, parsed_data->efuse_data.ver1.adc_calib_high); - - characterize_using_two_point(parsed_data->adc_num, parsed_data->atten_level, - parsed_data->efuse_data.ver1.adc_calib_high, parsed_data->efuse_data.ver1.adc_calib_low, - &(chars->coeff_a), &(chars->coeff_b)); - break; - case 2: - ESP_LOGD(LOG_TAG, "Calib V2, volt%dmV", parsed_data->efuse_data.ver2.adc_calib_high); - chars->coeff_a = coeff_a_scaling * parsed_data->efuse_data.ver2.adc_calib_high_voltage / - parsed_data->efuse_data.ver2.adc_calib_high; - chars->coeff_b = 0; - break; - default: - return false; - break; - } - return true; -} - -/* ------------------------- Public API ------------------------------------- */ -esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t source) -{ - if (source != ESP_ADC_CAL_VAL_EFUSE_TP) { - return ESP_ERR_NOT_SUPPORTED; - } - uint8_t adc_encoding_version = esp_efuse_rtc_table_read_calib_version(); - if (adc_encoding_version != 1 && adc_encoding_version != 2) { - // current version only accepts encoding ver 1 and ver 2. - return ESP_ERR_INVALID_VERSION; - } - return ESP_OK; -} - -esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, - adc_atten_t atten, - adc_bits_width_t bit_width, - uint32_t default_vref, - esp_adc_cal_characteristics_t *chars) -{ - bool res __attribute__((unused)); - adc_calib_parsed_info efuse_parsed_data = {0}; - // Check parameters - assert((adc_num == ADC_UNIT_1) || (adc_num == ADC_UNIT_2)); - assert(chars != NULL); - assert(bit_width == ADC_WIDTH_BIT_13); - - // make sure adc is calibrated. - res = prepare_calib_data_for(adc_num, atten, &efuse_parsed_data); - assert(res); - res = calculate_characterization_coefficients(&efuse_parsed_data, chars); - assert(res); - ESP_LOGD(LOG_TAG, "adc%d (atten leven %d) calibration done: A:%" PRId32 " B:%" PRId32, adc_num, atten, chars->coeff_a, chars->coeff_b); - - // Initialize remaining fields - chars->adc_num = adc_num; - chars->atten = atten; - chars->bit_width = bit_width; - - // these values are not used as the corresponding calibration themes are deprecated. - chars->vref = 0; - chars->low_curve = NULL; - chars->high_curve = NULL; - - // in esp32s2 we only use the two point method to calibrate the adc. - return ESP_ADC_CAL_VAL_EFUSE_TP; -} - -uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars) -{ - assert(chars != NULL); - return adc_reading * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling; -} diff --git a/components/esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c deleted file mode 100644 index 53d99acb40..0000000000 --- a/components/esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include "esp_types.h" -#include "esp_err.h" -#include "esp_log.h" -#include "esp_check.h" -#include "hal/adc_types.h" -#include "esp_efuse_rtc_calib.h" -#include "hal/adc_types.h" -#include "driver/adc_types_legacy.h" -#include "esp_adc_cal_types_legacy.h" -#include "../esp_adc_cal_internal_legacy.h" - -const static char LOG_TAG[] = "ADC_CALI"; - -/* ------------------------ Characterization Constants ---------------------- */ - -//coeff_a is actually a float number -//it is scaled to put them into uint32_t so that the headers do not have to be changed -static const int coeff_a_scaling = 1000000; - -/** - * @note Error Calculation - * Coefficients for calculating the reading voltage error. - * Four sets of coefficients for atten0 ~ atten3 respectively. - * - * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. - * - * @note {0,0} stands for unused item - * @note In case of the overflow, these coefficients are recorded as Absolute Value - * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); - * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. - */ -const static uint64_t adc1_error_coef_atten[4][5][2] = { - {{27856531419538344, 1e16}, {50871540569528, 1e16}, {9798249589, 1e15}, {0, 0}, {0, 0}}, //ADC1 atten0 - {{29831022915028695, 1e16}, {49393185868806, 1e16}, {101379430548, 1e16}, {0, 0}, {0, 0}}, //ADC1 atten1 - {{23285545746296417, 1e16}, {147640181047414, 1e16}, {208385525314, 1e16}, {0, 0}, {0, 0}}, //ADC1 atten2 - {{644403418269478, 1e15}, {644334888647536, 1e16}, {1297891447611, 1e16}, {70769718, 1e15}, {13515, 1e15}} //ADC1 atten3 -}; -const static uint64_t adc2_error_coef_atten[4][5][2] = { - {{25668651654328927, 1e16}, {1353548869615, 1e16}, {36615265189, 1e16}, {0, 0}, {0, 0}}, //ADC2 atten0 - {{23690184690298404, 1e16}, {66319894226185, 1e16}, {118964995959, 1e16}, {0, 0}, {0, 0}}, //ADC2 atten1 - {{9452499397020617, 1e16}, {200996773954387, 1e16}, {259011467956, 1e16}, {0, 0}, {0, 0}}, //ADC2 atten2 - {{12247719764336924, 1e16}, {755717904943462, 1e16}, {1478791187119, 1e16}, {79672528, 1e15}, {15038, 1e15}} //ADC2 atten3 -}; -/** - * Term sign - */ -const static int32_t adc1_error_sign[4][5] = { - {-1, -1, 1, 0, 0}, //ADC1 atten0 - {-1, -1, 1, 0, 0}, //ADC1 atten1 - {-1, -1, 1, 0, 0}, //ADC1 atten2 - {-1, -1, 1, -1, 1} //ADC1 atten3 -}; -const static int32_t adc2_error_sign[4][5] = { - {-1, 1, 1, 0, 0}, //ADC2 atten0 - {-1, -1, 1, 0, 0}, //ADC2 atten1 - {-1, -1, 1, 0, 0}, //ADC2 atten2 - { 1, -1, 1, -1, 1} //ADC2 atten3 -}; - -/* -------------------- Characterization Helper Data Types ------------------ */ -typedef struct { - uint32_t voltage; - uint32_t digi; -} adc_calib_data_ver1_t; - -typedef struct { - char version_num; - adc_unit_t adc_num; - adc_atten_t atten_level; - union { - adc_calib_data_ver1_t ver1; - } ref_data; -} adc_calib_info_t; - -//To get the reference point (Dout, Vin) -static esp_err_t get_reference_point(int version_num, adc_unit_t adc_num, adc_atten_t atten, adc_calib_info_t *calib_info) -{ - assert(version_num == 1); - esp_err_t ret; - - calib_info->version_num = version_num; - calib_info->adc_num = adc_num; - calib_info->atten_level = atten; - - uint32_t voltage = 0; - uint32_t digi = 0; - ret = esp_efuse_rtc_calib_get_cal_voltage(version_num, adc_num, atten, &digi, &voltage); - assert(ret == ESP_OK); - calib_info->ref_data.ver1.voltage = voltage; - calib_info->ref_data.ver1.digi = digi; - return ret; -} - -esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t source) -{ - if (source != ESP_ADC_CAL_VAL_EFUSE_TP_FIT) { - return ESP_ERR_NOT_SUPPORTED; - } - uint8_t adc_encoding_version = esp_efuse_rtc_calib_get_ver(); - if (adc_encoding_version != 1) { - // current version only accepts encoding ver 1. - return ESP_ERR_INVALID_VERSION; - } - return ESP_OK; -} - -/* - * Get an expected linear relationship btwn Vin and Dout - */ -static void calculate_characterization_coefficients(const adc_calib_info_t *parsed_data, esp_adc_cal_characteristics_t *chars) -{ - chars->coeff_a = coeff_a_scaling * parsed_data->ref_data.ver1.voltage / parsed_data->ref_data.ver1.digi; - chars->coeff_b = 0; - ESP_LOGV(LOG_TAG, "Calib V1, Cal Voltage = %" PRId32 ", Digi out = %" PRId32 ", Coef_a = %" PRId32, parsed_data->ref_data.ver1.voltage, parsed_data->ref_data.ver1.digi, chars->coeff_a); -} - -esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, - adc_atten_t atten, - adc_bits_width_t bit_width, - uint32_t default_vref, - esp_adc_cal_characteristics_t *chars) -{ - (void) default_vref; - - // Check parameters - ESP_RETURN_ON_FALSE(adc_num == ADC_UNIT_1 || adc_num == ADC_UNIT_2, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid unit num"); - ESP_RETURN_ON_FALSE(chars != NULL, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid characteristic"); - ESP_RETURN_ON_FALSE(atten < SOC_ADC_ATTEN_NUM, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid attenuation"); - - int version_num = esp_efuse_rtc_calib_get_ver(); - ESP_RETURN_ON_FALSE(version_num == 1, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "No calibration efuse burnt"); - - memset(chars, 0, sizeof(esp_adc_cal_characteristics_t)); - - adc_calib_info_t calib_info = {0}; - // make sure adc is calibrated. - get_reference_point(version_num, adc_num, atten, &calib_info); - calculate_characterization_coefficients(&calib_info, chars); - - // Initialize remaining fields - chars->adc_num = adc_num; - chars->atten = atten; - chars->bit_width = bit_width; - - return ESP_ADC_CAL_VAL_EFUSE_TP_FIT; -} - -uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars) -{ - assert(chars != NULL); - - //ADC reading won't exceed 4096. Otherwise the raw reading result is wrong, the next calculation will overflow. - assert(adc_reading < 4096); - - uint32_t voltage = 0; - int32_t error = 0; - uint64_t v_cali_1 = 0; - - //raw * gradient * 1000000 - v_cali_1 = (uint64_t)adc_reading * chars->coeff_a; - //convert to real number - v_cali_1 = v_cali_1 / coeff_a_scaling; - ESP_LOGV(LOG_TAG, "v_cali_1 is %llu", v_cali_1); - - //Curve Fitting error correction - esp_adc_error_calc_param_t param = { - .v_cali_input = v_cali_1, - .term_num = (chars->atten == 3) ? 5 : 3, - .coeff = (chars->adc_num == ADC_UNIT_1) ? &adc1_error_coef_atten :&adc2_error_coef_atten, - .sign = (chars->adc_num == ADC_UNIT_1) ? &adc1_error_sign :&adc2_error_sign, - }; - error = esp_adc_cal_get_reading_error(¶m, chars->atten); - - voltage = (int32_t)v_cali_1 - error; - - return voltage; -} diff --git a/components/esp_adc/deprecated/esp_adc_cal_common_legacy.c b/components/esp_adc/deprecated/esp_adc_cal_common_legacy.c deleted file mode 100644 index 982f7c9f7c..0000000000 --- a/components/esp_adc/deprecated/esp_adc_cal_common_legacy.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "inttypes.h" -#include "sdkconfig.h" - -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 -#include "esp_types.h" -#include "esp_err.h" -#include "esp_log.h" -#include "esp_check.h" -#include "hal/adc_types.h" -#define CONFIG_ADC_SUPPRESS_DEPRECATE_WARN 1 -#include "esp_adc_cal.h" -#include "esp_adc_cal_internal_legacy.h" -#include "driver/adc.h" - -const __attribute__((unused)) static char *TAG = "ADC_CALI"; - -esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, - const esp_adc_cal_characteristics_t *chars, - uint32_t *voltage) -{ - // Check parameters - ESP_RETURN_ON_FALSE(chars != NULL, ESP_ERR_INVALID_ARG, TAG, "No characteristic input"); - ESP_RETURN_ON_FALSE(voltage != NULL, ESP_ERR_INVALID_ARG, TAG, "No output buffer"); - - esp_err_t ret = ESP_OK; - int adc_reading; - if (chars->adc_num == ADC_UNIT_1) { - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(0), ESP_ERR_INVALID_ARG, TAG, "Invalid channel"); - adc_reading = adc1_get_raw(channel); - } else { - ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(1), ESP_ERR_INVALID_ARG, TAG, "Invalid channel"); - ret = adc2_get_raw(channel, chars->bit_width, &adc_reading); - } - - if (ret == ESP_OK) { - *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); - } - return ret; -} - -#if ESP_ADC_CAL_CURVE_FITTING_SUPPORTED -/*------------------------------------------------------------------------------ - * Private API - *----------------------------------------------------------------------------*/ -int32_t esp_adc_cal_get_reading_error(const esp_adc_error_calc_param_t *param, uint8_t atten) -{ - if (param->v_cali_input == 0) { - return 0; - } - - uint64_t v_cali_1 = param->v_cali_input; - uint8_t term_num = param->term_num; - int32_t error = 0; - uint64_t coeff = 0; - uint64_t variable[term_num]; - uint64_t term[term_num]; - memset(variable, 0, term_num * sizeof(uint64_t)); - memset(term, 0, term_num * sizeof(uint64_t)); - - /** - * For atten0 ~ 2: - * error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); - * - * For atten3: - * error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); - */ - variable[0] = 1; - coeff = (*param->coeff)[atten][0][0]; - term[0] = variable[0] * coeff / (*param->coeff)[atten][0][1]; - error = (int32_t)term[0] * (*param->sign)[atten][0]; - - for (int i = 1; i < term_num; i++) { - variable[i] = variable[i - 1] * v_cali_1; - coeff = (*param->coeff)[atten][i][0]; - term[i] = variable[i] * coeff; - ESP_LOGV(TAG, "big coef is %llu, big term%d is %llu, coef_id is %d", coeff, i, term[i], i); - - term[i] = term[i] / (*param->coeff)[atten][i][1]; - error += (int32_t)term[i] * (*param->sign)[atten][i]; - ESP_LOGV(TAG, "term%d is %llu, error is %"PRId32, i, term[i], error); - } - - return error; -} -#endif //#if ESP_ADC_CAL_CURVE_FITTING_SUPPORTED - -#endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 diff --git a/components/esp_adc/deprecated/esp_adc_cal_internal_legacy.h b/components/esp_adc/deprecated/esp_adc_cal_internal_legacy.h deleted file mode 100644 index 3f2218e8ba..0000000000 --- a/components/esp_adc/deprecated/esp_adc_cal_internal_legacy.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include "sdkconfig.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 -#define ESP_ADC_CAL_CURVE_FITTING_SUPPORTED 1 - -#define COEFF_GROUP_NUM 4 -#define TERM_MAX 5 -#endif - -#if ESP_ADC_CAL_CURVE_FITTING_SUPPORTED -/** - * Calculation parameters used for curve fitting calibration algorithm error - * - * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); - * Where X is the `v_cali_input`. - */ -typedef struct { - uint64_t v_cali_input; //Input to calculate the error - uint8_t term_num; //Term number of the algorithm formula - const uint64_t (*coeff)[COEFF_GROUP_NUM][TERM_MAX][2]; //Coeff of each term. See `adc_error_coef_atten` for details (and the magic number 2) - const int32_t (*sign)[COEFF_GROUP_NUM][TERM_MAX]; //Sign of each term -} esp_adc_error_calc_param_t; - -/** - * Calculate the curve fitting error - * - * @param param see `esp_adc_error_calc_param_t` - * @param atten ADC attenuation - */ -int32_t esp_adc_cal_get_reading_error(const esp_adc_error_calc_param_t *param, uint8_t atten); - -#endif //#if ESP_ADC_CAL_CURVE_FITTING_SUPPORTED - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_adc/deprecated/include/esp_adc_cal.h b/components/esp_adc/deprecated/include/esp_adc_cal.h deleted file mode 100644 index 6ce111496b..0000000000 --- a/components/esp_adc/deprecated/include/esp_adc_cal.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include "sdkconfig.h" -#include "esp_err.h" -#include "hal/adc_types.h" -#include "driver/adc_types_legacy.h" -#include "esp_adc_cal_types_legacy.h" - -#if !CONFIG_ADC_SUPPRESS_DEPRECATE_WARN -#warning "legacy adc calibration driver is deprecated, please migrate to use esp_adc/adc_cali.h and esp_adc/adc_cali_scheme.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 -/** - * @brief Checks if ADC calibration values are burned into eFuse - * - * This function checks if ADC reference voltage or Two Point values have been - * burned to the eFuse of the current ESP32 - * - * @param value_type Type of calibration value (ESP_ADC_CAL_VAL_EFUSE_VREF or ESP_ADC_CAL_VAL_EFUSE_TP) - * @note in ESP32S2, only ESP_ADC_CAL_VAL_EFUSE_TP is supported. Some old ESP32S2s do not support this, either. - * In which case you have to calibrate it manually, possibly by performing your own two-point calibration on the chip. - * - * @return - * - ESP_OK: The calibration mode is supported in eFuse - * - ESP_ERR_NOT_SUPPORTED: Error, eFuse values are not burned - * - ESP_ERR_INVALID_ARG: Error, invalid argument (ESP_ADC_CAL_VAL_DEFAULT_VREF) - */ -esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t value_type); - -/** - * @brief Characterize an ADC at a particular attenuation - * - * This function will characterize the ADC at a particular attenuation and generate - * the ADC-Voltage curve in the form of [y = coeff_a * x + coeff_b]. - * Characterization can be based on Two Point values, eFuse Vref, or default Vref - * and the calibration values will be prioritized in that order. - * - * @note - * For ESP32, Two Point values and eFuse Vref calibration can be enabled/disabled using menuconfig. - * For ESP32s2, only Two Point values calibration and only ADC_WIDTH_BIT_13 is supported. The parameter default_vref is unused. - * - * - * @param[in] adc_num ADC to characterize (ADC_UNIT_1 or ADC_UNIT_2) - * @param[in] atten Attenuation to characterize - * @param[in] bit_width Bit width configuration of ADC - * @param[in] default_vref Default ADC reference voltage in mV (Only in ESP32, used if eFuse values is not available) - * @param[out] chars Pointer to empty structure used to store ADC characteristics - * - * @return - * - ESP_ADC_CAL_VAL_EFUSE_VREF: eFuse Vref used for characterization - * - ESP_ADC_CAL_VAL_EFUSE_TP: Two Point value used for characterization (only in Linear Mode) - * - ESP_ADC_CAL_VAL_DEFAULT_VREF: Default Vref used for characterization - */ -esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, - adc_atten_t atten, - adc_bits_width_t bit_width, - uint32_t default_vref, - esp_adc_cal_characteristics_t *chars); - -/** - * @brief Convert an ADC reading to voltage in mV - * - * This function converts an ADC reading to a voltage in mV based on the ADC's - * characteristics. - * - * @note Characteristics structure must be initialized before this function - * is called (call esp_adc_cal_characterize()) - * - * @param[in] adc_reading ADC reading - * @param[in] chars Pointer to initialized structure containing ADC characteristics - * - * @return Voltage in mV - */ -uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars); - -/** - * @brief Reads an ADC and converts the reading to a voltage in mV - * - * This function reads an ADC then converts the raw reading to a voltage in mV - * based on the characteristics provided. The ADC that is read is also - * determined by the characteristics. - * - * @note The Characteristics structure must be initialized before this - * function is called (call esp_adc_cal_characterize()) - * - * @param[in] channel ADC Channel to read - * @param[in] chars Pointer to initialized ADC characteristics structure - * @param[out] voltage Pointer to store converted voltage - * - * @return - * - ESP_OK: ADC read and converted to mV - * - ESP_ERR_INVALID_ARG: Error due to invalid arguments - * - ESP_ERR_INVALID_STATE: Reading result is invalid. Try to read again. - */ -esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, const esp_adc_cal_characteristics_t *chars, uint32_t *voltage); - -#endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_adc/deprecated/include/esp_adc_cal_types_legacy.h b/components/esp_adc/deprecated/include/esp_adc_cal_types_legacy.h deleted file mode 100644 index 613f09a4c6..0000000000 --- a/components/esp_adc/deprecated/include/esp_adc_cal_types_legacy.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "sdkconfig.h" -#include "driver/adc_types_legacy.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 -/** - * @brief Type of calibration value used in characterization - */ -typedef enum { - ESP_ADC_CAL_VAL_EFUSE_VREF = 0, /**< Characterization based on reference voltage stored in eFuse*/ - ESP_ADC_CAL_VAL_EFUSE_TP = 1, /**< Characterization based on Two Point values stored in eFuse*/ - ESP_ADC_CAL_VAL_DEFAULT_VREF = 2, /**< Characterization based on default reference voltage*/ - ESP_ADC_CAL_VAL_EFUSE_TP_FIT = 3, /**< Characterization based on Two Point values and fitting curve coefficients stored in eFuse */ - ESP_ADC_CAL_VAL_MAX, - ESP_ADC_CAL_VAL_NOT_SUPPORTED = ESP_ADC_CAL_VAL_MAX, -} esp_adc_cal_value_t; - -/** - * @brief Structure storing characteristics of an ADC - * - * @note Call esp_adc_cal_characterize() to initialize the structure - */ -typedef struct { - adc_unit_t adc_num; /**< ADC unit*/ - adc_atten_t atten; /**< ADC attenuation*/ - adc_bits_width_t bit_width; /**< ADC bit width */ - uint32_t coeff_a; /**< Gradient of ADC-Voltage curve*/ - uint32_t coeff_b; /**< Offset of ADC-Voltage curve*/ - uint32_t vref; /**< Vref used by lookup table*/ - const uint32_t *low_curve; /**< Pointer to low Vref curve of lookup table (NULL if unused)*/ - const uint32_t *high_curve; /**< Pointer to high Vref curve of lookup table (NULL if unused)*/ - uint8_t version; /**< ADC Calibration */ -} esp_adc_cal_characteristics_t; -#endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_adc/sdkconfig.rename b/components/esp_adc/sdkconfig.rename new file mode 100644 index 0000000000..eb9f76ee65 --- /dev/null +++ b/components/esp_adc/sdkconfig.rename @@ -0,0 +1,7 @@ +# sdkconfig replacement configurations for deprecated options formatted as +# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION + +CONFIG_ADC_DISABLE_DAC CONFIG_ADC_DISABLE_DAC_OUTPUT +CONFIG_ADC_CAL_EFUSE_TP_ENABLE CONFIG_ADC_CALI_EFUSE_TP_ENABLE +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE CONFIG_ADC_CALI_EFUSE_VREF_ENABLE +CONFIG_ADC_CAL_LUT_ENABLE CONFIG_ADC_CALI_LUT_ENABLE diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index 56f673fa04..62fd0a573c 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -49,7 +49,6 @@ typedef enum { ADC_ATTEN_DB_2_5 = 1, ///