diff --git a/components/bootloader_support/src/bootloader_random_esp32p4.c b/components/bootloader_support/src/bootloader_random_esp32p4.c index 4d0552f16a..df88e8d7b2 100644 --- a/components/bootloader_support/src/bootloader_random_esp32p4.c +++ b/components/bootloader_support/src/bootloader_random_esp32p4.c @@ -9,7 +9,7 @@ #include "soc/pmu_reg.h" #include "soc/regi2c_saradc.h" #include "soc/hp_sys_clkrst_reg.h" -#include "soc/rtcadc_reg.h" +#include "soc/lp_adc_reg.h" #include "esp_private/regi2c_ctrl.h" #include "esp_rom_regi2c.h" diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index dd3e9f3a72..04eb8c9024 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -57,7 +57,7 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi #define INTERNAL_BUF_NUM 5 -#if SOC_AHB_GDMA_VERSION == 1 +#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 @@ -434,7 +434,10 @@ esp_err_t adc_digi_start(void) return ESP_ERR_INVALID_STATE; } //reset ADC digital part to reset ADC sampling EOF counter - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_reset_register(); + } + sar_periph_ctrl_adc_continuous_power_acquire(); //reset flags s_adc_digi_ctx->ringbuf_overflow_flag = 0; diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index 87e66e56a8..76277ac5e5 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -70,7 +70,7 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi #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 +#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 ) @@ -172,7 +172,7 @@ static void adc_rtc_chan_init(adc_unit_t adc_unit) 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"); - +#if ADC_LL_RTC_GPIO_SUPPORTED 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) { @@ -188,7 +188,7 @@ esp_err_t adc_common_gpio_init(adc_unit_t adc_unit, adc_channel_t channel) ESP_RETURN_ON_ERROR(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED), ADC_TAG, "rtc_gpio_set_direction fail"); ESP_RETURN_ON_ERROR(rtc_gpio_pulldown_dis(gpio_num), ADC_TAG, "rtc_gpio_pulldown_dis fail"); ESP_RETURN_ON_ERROR(rtc_gpio_pullup_dis(gpio_num), ADC_TAG, "rtc_gpio_pullup_dis fail"); - +#endif return ESP_OK; } @@ -571,7 +571,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * #endif adc_oneshot_ll_set_output_bits(ADC_UNIT_2, bitwidth); -#if CONFIG_IDF_TARGET_ESP32 +#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 diff --git a/components/driver/deprecated/driver/adc_types_legacy.h b/components/driver/deprecated/driver/adc_types_legacy.h index 8ea32f9d47..9186b9c245 100644 --- a/components/driver/deprecated/driver/adc_types_legacy.h +++ b/components/driver/deprecated/driver/adc_types_legacy.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -81,6 +81,18 @@ typedef enum { ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO6 */ ADC1_CHANNEL_MAX, } adc1_channel_t; +#elif CONFIG_IDF_TARGET_ESP32P4 +typedef enum { + ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO16 */ + ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO17 */ + ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO18 */ + ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO19 */ + ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO20 */ + ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO21 */ + ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO22 */ + ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO23 */ + ADC1_CHANNEL_MAX, +} adc1_channel_t; #endif // CONFIG_IDF_TARGET_* #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -103,6 +115,17 @@ typedef enum { ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO5 */ ADC2_CHANNEL_MAX, } adc2_channel_t; + +#elif CONFIG_IDF_TARGET_ESP32P4 +typedef enum { + ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO49 */ + ADC2_CHANNEL_1, /*!< ADC2 channel 1 is GPIO50 */ + ADC2_CHANNEL_2, /*!< ADC2 channel 2 is GPIO51 */ + ADC2_CHANNEL_3, /*!< ADC2 channel 3 is GPIO52 */ + ADC2_CHANNEL_4, /*!< ADC2 channel 4 is GPIO53 */ + ADC2_CHANNEL_5, /*!< ADC2 channel 5 is GPIO54 */ + ADC2_CHANNEL_MAX, +} adc2_channel_t; #endif #if SOC_ADC_DMA_SUPPORTED diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 4e30f5c6ec..996eacf13c 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -17,6 +17,10 @@ components/driver/test_apps/i2s_test_apps/legacy_i2s_driver: components/driver/test_apps/legacy_adc_driver: disable: - if: SOC_ADC_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: lack of runners, TODO IDF-9573 depends_components: - efuse - esp_driver_i2s diff --git a/components/driver/test_apps/legacy_adc_driver/README.md b/components/driver/test_apps/legacy_adc_driver/README.md index a8b7833fa3..bf47d80ec6 100644 --- a/components/driver/test_apps/legacy_adc_driver/README.md +++ b/components/driver/test_apps/legacy_adc_driver/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | 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 index 196c56764a..e09a741b18 100644 --- 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -67,6 +67,13 @@ #define ADC_TEST_HIGH_VAL 3390 #define ADC_TEST_HIGH_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32P4 +#define ADC_TEST_LOW_VAL 3100 +#define ADC_TEST_LOW_THRESH 200 + +#define ADC_TEST_HIGH_VAL 4095 +#define ADC_TEST_HIGH_THRESH 200 + #endif //ADC Channels 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 index 6bc3b838d6..dd7ce7097f 100644 --- a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py +++ b/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut diff --git a/components/esp_adc/CMakeLists.txt b/components/esp_adc/CMakeLists.txt index 633c954959..92a4d9304a 100644 --- a/components/esp_adc/CMakeLists.txt +++ b/components/esp_adc/CMakeLists.txt @@ -53,5 +53,5 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} - PRIV_REQUIRES driver esp_driver_gpio efuse esp_pm esp_ringbuf + PRIV_REQUIRES driver esp_driver_gpio efuse esp_pm esp_ringbuf esp_mm LDFRAGMENTS linker.lf) diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 6a13fb2911..7fb2f68dca 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -37,6 +37,11 @@ #include "adc_continuous_internal.h" #include "esp_private/adc_dma.h" #include "adc_dma_internal.h" +#include "esp_dma_utils.h" +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#include "esp_cache.h" +#include "esp_private/esp_cache_private.h" +#endif static const char *ADC_TAG = "adc_continuous"; @@ -66,6 +71,12 @@ static IRAM_ATTR bool adc_dma_intr(adc_continuous_ctx_t *adc_digi_ctx) if (status != ADC_HAL_DMA_DESC_VALID) { break; } +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + else { + esp_err_t msync_ret = esp_cache_msync((void *)finished_buffer, finished_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(msync_ret == ESP_OK); + } +#endif ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, finished_buffer, finished_size, &taskAwoken); need_yield |= (taskAwoken == pdTRUE); @@ -108,7 +119,10 @@ static IRAM_ATTR bool adc_dma_intr(adc_continuous_ctx_t *adc_digi_ctx) } } } - +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_err_t msync_ret = esp_cache_msync((void *)(adc_digi_ctx->hal.rx_desc), adc_digi_ctx->adc_desc_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(msync_ret == ESP_OK); +#endif return need_yield; } @@ -178,7 +192,11 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi } //malloc internal buffer used by DMA - adc_ctx->rx_dma_buf = heap_caps_calloc(1, hdl_config->conv_frame_size * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + esp_dma_mem_info_t dma_mem_info = { + .extra_heap_caps = (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA), + .dma_alignment_bytes = 4, + }; + esp_dma_capable_calloc(1, hdl_config->conv_frame_size * INTERNAL_BUF_NUM, &dma_mem_info, (void **)&adc_ctx->rx_dma_buf, NULL); if (!adc_ctx->rx_dma_buf) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -187,7 +205,7 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi //malloc dma descriptor uint32_t dma_desc_num_per_frame = (hdl_config->conv_frame_size + 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; - adc_ctx->hal.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * dma_desc_max_num, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + esp_dma_capable_calloc(1, (sizeof(dma_descriptor_t)) * dma_desc_max_num, &dma_mem_info, (void **)&adc_ctx->hal.rx_desc, &adc_ctx->adc_desc_size); if (!adc_ctx->hal.rx_desc) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -245,7 +263,9 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle) ESP_RETURN_ON_FALSE(handle->fsm == ADC_FSM_INIT, ESP_ERR_INVALID_STATE, ADC_TAG, "ADC continuous mode isn't in the init state, it's started already"); //reset ADC digital part to reset ADC sampling EOF counter - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_reset_register(); + } if (handle->pm_lock) { ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(handle->pm_lock), ADC_TAG, "acquire pm_lock failed"); @@ -295,6 +315,10 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle) adc_dma_reset(handle->adc_dma); adc_hal_digi_reset(); adc_hal_digi_dma_link(&handle->hal, handle->rx_dma_buf); +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_err_t ret = esp_cache_msync(handle->hal.rx_desc, handle->adc_desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + assert(ret == ESP_OK); +#endif adc_dma_start(handle->adc_dma, handle->hal.rx_desc); adc_hal_digi_connect(true); diff --git a/components/esp_adc/adc_continuous_internal.h b/components/esp_adc/adc_continuous_internal.h index 03ae5d970a..a2fb28dfac 100644 --- a/components/esp_adc/adc_continuous_internal.h +++ b/components/esp_adc/adc_continuous_internal.h @@ -99,6 +99,7 @@ struct adc_continuous_ctx_t { #if SOC_ADC_MONITOR_SUPPORTED adc_monitor_t *adc_monitor[SOC_ADC_DIGI_MONITOR_NUM]; // adc monitor context #endif + size_t adc_desc_size; adc_dma_t adc_dma; adc_dma_intr_func_t adc_intr_func; }; diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index 80f2711489..0691e22f1a 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -115,7 +115,6 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a }; adc_oneshot_hal_init(&(unit->hal), &config); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED //To enable the APB_SARADC periph if needed _lock_acquire(&s_ctx.mutex); s_ctx.apb_periph_ref_cnts++; @@ -123,12 +122,13 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a adc_apb_periph_claim(); } _lock_release(&s_ctx.mutex); -#endif if (init_config->ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_acquire(); } else { +#if !CONFIG_IDF_TARGET_ESP32P4 // # TODO: IDF-7528, IDF-7529 esp_sleep_enable_adc_tsens_monitor(true); +#endif } ESP_LOGD(TAG, "new adc unit%"PRId32" is created", unit->unit_id); @@ -229,7 +229,9 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) if (ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_release(); } else { +#if !CONFIG_IDF_TARGET_ESP32P4 // # TODO: IDF-7528, IDF-7529 esp_sleep_enable_adc_tsens_monitor(false); +#endif } #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED @@ -262,7 +264,7 @@ static esp_err_t s_adc_io_init(adc_unit_t unit, adc_channel_t channel) { ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(unit), ESP_ERR_INVALID_ARG, TAG, "invalid channel"); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED +#if !ADC_LL_RTC_GPIO_SUPPORTED uint32_t io_num = ADC_GET_IO_NUM(unit, channel); gpio_config_t cfg = { diff --git a/components/esp_adc/test_apps/.build-test-rules.yml b/components/esp_adc/test_apps/.build-test-rules.yml index aa97546c7d..6a284fa6d2 100644 --- a/components/esp_adc/test_apps/.build-test-rules.yml +++ b/components/esp_adc/test_apps/.build-test-rules.yml @@ -4,6 +4,10 @@ components/esp_adc/test_apps/adc: disable: - if: SOC_ADC_SUPPORTED != 1 - if: CONFIG_NAME == "gdma_iram_safe" and IDF_TARGET in ["esp32", "esp32s2", "esp32c2"] + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: not runners for ESP32P4 ADC # TODO: IDF-9573 depends_components: - esp_adc - esp_driver_gpio diff --git a/components/esp_adc/test_apps/adc/README.md b/components/esp_adc/test_apps/adc/README.md index a8b7833fa3..bf47d80ec6 100644 --- a/components/esp_adc/test_apps/adc/README.md +++ b/components/esp_adc/test_apps/adc/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.c b/components/esp_adc/test_apps/adc/main/test_common_adc.c index 7cf974c43f..2636803588 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.c @@ -13,6 +13,7 @@ #include "driver/rtc_io.h" #include "soc/adc_periph.h" #include "test_common_adc.h" +#include "hal/adc_ll.h" __attribute__((unused)) static const char *TAG = "TEST_ADC"; @@ -98,7 +99,7 @@ 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"); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED +#if !ADC_LL_RTC_GPIO_SUPPORTED 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))); #else diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.h b/components/esp_adc/test_apps/adc/main/test_common_adc.h index 5228713af9..1d28c66e4e 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.h +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -86,6 +86,14 @@ extern "C" { #define ADC_TEST_HIGH_VAL 3390 #define ADC_TEST_HIGH_VAL_DMA 4081 #define ADC_TEST_HIGH_THRESH 200 + +#elif CONFIG_IDF_TARGET_ESP32P4 +#define ADC_TEST_LOW_VAL 3100 +#define ADC_TEST_LOW_THRESH 200 + +#define ADC_TEST_HIGH_VAL 4095 +#define ADC_TEST_HIGH_VAL_DMA 4095 +#define ADC_TEST_HIGH_THRESH 200 #endif /*--------------------------------------------------------------- diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c index 86d3738d5e..32f3c67b79 100644 --- a/components/esp_hw_support/adc_share_hw_ctrl.c +++ b/components/esp_hw_support/adc_share_hw_ctrl.c @@ -12,7 +12,7 @@ * * However, usages of above components are different. * Therefore, we put the common used parts into `esp_hw_support`, including: - * - adc power maintainance + * - adc power maintenance * - adc hw calibration settings * - adc locks, to prevent concurrently using adc hw */ @@ -205,10 +205,10 @@ void adc_apb_periph_claim(void) portENTER_CRITICAL(&s_spinlock); s_adc_digi_ctrlr_cnt++; if (s_adc_digi_ctrlr_cnt == 1) { - //enable ADC digital part - periph_module_enable(PERIPH_SARADC_MODULE); - //reset ADC digital part - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_enable_bus_clock(true); + adc_ll_reset_register(); + } } portEXIT_CRITICAL(&s_spinlock); @@ -219,7 +219,9 @@ void adc_apb_periph_free(void) portENTER_CRITICAL(&s_spinlock); s_adc_digi_ctrlr_cnt--; if (s_adc_digi_ctrlr_cnt == 0) { - periph_module_disable(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_enable_bus_clock(false); + } } else if (s_adc_digi_ctrlr_cnt < 0) { portEXIT_CRITICAL(&s_spinlock); ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__); diff --git a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h index 5bf1084730..a0c82e394b 100644 --- a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h +++ b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h @@ -12,7 +12,7 @@ * * However, usages of above components are different. * Therefore, we put the common used parts into `esp_hw_support`, including: - * - adc power maintainance + * - adc power maintenance * - adc hw calibration settings * - adc locks, to prevent concurrently using adc hw */ @@ -26,6 +26,12 @@ extern "C" { #endif +#if SOC_RCC_IS_INDEPENDENT || CONFIG_IDF_TARGET_ESP32 +#define ADC_BUS_CLK_ATOMIC() +#else +#define ADC_BUS_CLK_ATOMIC() PERIPH_RCC_ATOMIC() +#endif + #if SOC_ADC_CALIBRATION_V1_SUPPORTED /*--------------------------------------------------------------- ADC Hardware Calibration diff --git a/components/esp_hw_support/port/esp32p4/CMakeLists.txt b/components/esp_hw_support/port/esp32p4/CMakeLists.txt index f81f017081..2965e1746d 100644 --- a/components/esp_hw_support/port/esp32p4/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32p4/CMakeLists.txt @@ -10,7 +10,8 @@ set(srcs "rtc_clk_init.c" ) if(NOT BOOTLOADER_BUILD) - list(APPEND srcs "esp_crypto_lock.c") + list(APPEND srcs "sar_periph_ctrl.c" + "esp_crypto_lock.c") if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) list(APPEND srcs "mspi_timing_config.c") diff --git a/components/esp_hw_support/port/esp32p4/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32p4/sar_periph_ctrl.c new file mode 100644 index 0000000000..90a4b986ae --- /dev/null +++ b/components/esp_hw_support/port/esp32p4/sar_periph_ctrl.c @@ -0,0 +1,116 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * Related peripherals are: + * - ADC + * - PWDET + */ + +#include "sdkconfig.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "esp_private/sar_periph_ctrl.h" +#include "esp_private/esp_modem_clock.h" +#include "hal/sar_ctrl_ll.h" + +static const char *TAG = "sar_periph_ctrl"; +extern portMUX_TYPE rtc_spinlock; + + +void sar_periph_ctrl_init(void) +{ + //Put SAR control mux to FSM state + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); +} + +void sar_periph_ctrl_power_enable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +void sar_periph_ctrl_power_disable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF); + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +/** + * This gets incremented when s_sar_power_acquire() is called, + * and decremented when s_sar_power_release() is called. + * PWDET is powered down when the value reaches zero. + * Should be modified within critical section. + */ +static int s_sar_power_on_cnt; + +static void s_sar_power_acquire(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + s_sar_power_on_cnt++; + if (s_sar_power_on_cnt == 1) { + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON); + } + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +static void s_sar_power_release(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + s_sar_power_on_cnt--; + if (s_sar_power_on_cnt < 0) { + portEXIT_CRITICAL(&rtc_spinlock); + ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); + abort(); + } else if (s_sar_power_on_cnt == 0) { + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); + } + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + + +/*------------------------------------------------------------------------------ +* PWDET Power +*----------------------------------------------------------------------------*/ +void sar_periph_ctrl_pwdet_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_pwdet_power_release(void) +{ + s_sar_power_release(); +} + + +/*------------------------------------------------------------------------------ +* ADC Power +*----------------------------------------------------------------------------*/ +void sar_periph_ctrl_adc_oneshot_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_adc_oneshot_power_release(void) +{ + s_sar_power_release(); +} + +void sar_periph_ctrl_adc_continuous_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_adc_continuous_power_release(void) +{ + s_sar_power_release(); +} diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 90827e94d8..39e7af3708 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -663,7 +663,7 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep) #endif } -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-6496 +#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7370 if (!(deep_sleep && s_adc_tsen_enabled)){ sar_periph_ctrl_power_disable(); @@ -679,11 +679,7 @@ FORCE_INLINE_ATTR void misc_modules_wake_prepare(void) #if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP sleep_console_usj_pad_restore(); #endif - -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-6496 sar_periph_ctrl_power_enable(); -#endif - #if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_RTCCNTL sleep_disable_cpu_retention(); #endif diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index bb62c05de9..1688491f2d 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -74,6 +74,10 @@ void adc_hal_digi_init(adc_hal_dma_ctx_t *hal) void adc_hal_digi_deinit() { +#if ADC_LL_POWER_MANAGE_SUPPORTED + adc_ll_set_power_manage(ADC_UNIT_1, ADC_LL_POWER_SW_OFF); + adc_ll_set_power_manage(ADC_UNIT_2, ADC_LL_POWER_SW_OFF); +#endif adc_ll_digi_trigger_disable(); adc_ll_digi_dma_disable(); adc_ll_digi_clear_pattern_table(ADC_UNIT_1); @@ -144,6 +148,9 @@ void adc_hal_digi_controller_config(adc_hal_dma_ctx_t *hal, const adc_hal_digi_c for (int i = 0; i < cfg->adc_pattern_len; i++) { adc_ll_digi_set_pattern_table(pattern_both, i, cfg->adc_pattern[i]); } +#if ADC_LL_POWER_MANAGE_SUPPORTED + adc_ll_set_power_manage(0, ADC_LL_POWER_SW_ON); +#endif #elif (SOC_ADC_DIGI_CONTROLLER_NUM >= 2) uint32_t adc1_pattern_idx = 0; @@ -154,9 +161,15 @@ void adc_hal_digi_controller_config(adc_hal_dma_ctx_t *hal, const adc_hal_digi_c for (int i = 0; i < cfg->adc_pattern_len; i++) { if (cfg->adc_pattern[i].unit == ADC_UNIT_1) { +#if ADC_LL_POWER_MANAGE_SUPPORTED + adc_ll_set_power_manage(ADC_UNIT_1, ADC_LL_POWER_SW_ON); +#endif adc_ll_digi_set_pattern_table(ADC_UNIT_1, adc1_pattern_idx, cfg->adc_pattern[i]); adc1_pattern_idx++; } else if (cfg->adc_pattern[i].unit == ADC_UNIT_2) { +#if ADC_LL_POWER_MANAGE_SUPPORTED + adc_ll_set_power_manage(ADC_UNIT_2, ADC_LL_POWER_SW_ON); +#endif adc_ll_digi_set_pattern_table(ADC_UNIT_2, adc2_pattern_idx, cfg->adc_pattern[i]); adc2_pattern_idx++; } else { diff --git a/components/hal/adc_oneshot_hal.c b/components/hal/adc_oneshot_hal.c index 1a5b56da4e..c74079d464 100644 --- a/components/hal/adc_oneshot_hal.c +++ b/components/hal/adc_oneshot_hal.c @@ -142,7 +142,7 @@ bool adc_oneshot_hal_convert(adc_oneshot_hal_ctx_t *hal, int *out_raw) } esp_rom_delay_us(read_delay_us); *out_raw = adc_oneshot_ll_get_raw_result(hal->unit); -#if (SOC_ADC_PERIPH_NUM == 2) +#if SOC_ADC_ARBITER_SUPPORTED if (hal->unit == ADC_UNIT_2) { valid = adc_oneshot_ll_raw_check_valid(ADC_UNIT_2, *out_raw); if (!valid) { diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index 08e93a0c6d..8f412ea3d6 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,6 +31,7 @@ extern "C" { #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) +#define ADC_LL_RTC_GPIO_SUPPORTED (1) /*--------------------------------------------------------------- DMA @@ -229,7 +230,7 @@ static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t } /** - * Set pattern table lenth for digital controller. + * Set pattern table length for digital controller. * The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection, * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the * pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. @@ -564,6 +565,25 @@ static inline void adc_oneshot_ll_disable_all_unit(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + (void)enable; + //For compatibility +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + //For compatibility +} + /** * Set ADC module controller. * There are five SAR ADC controllers: diff --git a/components/hal/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index 9427b0e4c4..2e234d740c 100644 --- a/components/hal/esp32c2/include/hal/adc_ll.h +++ b/components/hal/esp32c2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/misc.h" #include "hal/assert.h" #include "hal/adc_types.h" @@ -286,6 +287,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index b780bcebd5..779312f4fa 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -15,6 +15,7 @@ #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/misc.h" #include "hal/assert.h" #include "hal/adc_types.h" @@ -560,6 +561,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.reg_apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.reg_apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.reg_apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h index d7d689e74a..db51a869da 100644 --- a/components/hal/esp32c6/include/hal/adc_ll.h +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -59,6 +59,7 @@ extern "C" { #define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 #define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 +#define ADC_LL_POWER_MANAGE_SUPPORTED 1 //ESP32C6 supported to manage power mode /*--------------------------------------------------------------- PWDET (Power Detect) ---------------------------------------------------------------*/ @@ -554,13 +555,33 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + PCR.saradc_conf.saradc_reg_clk_en = enable; +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + PCR.saradc_conf.saradc_reg_rst_en = 1; + PCR.saradc_conf.saradc_reg_rst_en = 0; +} + /** * Set ADC module power management. * * @param manage Set ADC power status. */ -static inline void adc_ll_set_power_manage(adc_ll_power_t manage) +static inline void adc_ll_set_power_manage(adc_unit_t adc_n, adc_ll_power_t manage) { + (void) adc_n; /* Bit1 0:Fsm 1: SW mode Bit0 0:SW mode power down 1: SW mode power on */ if (manage == ADC_LL_POWER_SW_ON) { diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index dd9c811379..8c02ddd191 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,6 +60,7 @@ extern "C" { #define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 #define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 +#define ADC_LL_POWER_MANAGE_SUPPORTED 1 //ESP32H2 supported to manage power mode /*--------------------------------------------------------------- PWDET (Power Detect) ---------------------------------------------------------------*/ @@ -555,13 +556,32 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + PCR.saradc_conf.saradc_reg_clk_en = enable; +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + PCR.saradc_conf.saradc_reg_rst_en = 1; + PCR.saradc_conf.saradc_reg_rst_en = 0; +} /** * Set ADC module power management. * * @param manage Set ADC power status. */ -static inline void adc_ll_set_power_manage(adc_ll_power_t manage) +static inline void adc_ll_set_power_manage(adc_unit_t adc_n, adc_ll_power_t manage) { + (void) adc_n; /* Bit1 0:Fsm 1: SW mode Bit0 0:SW mode power down 1: SW mode power on */ if (manage == ADC_LL_POWER_SW_ON) { diff --git a/components/hal/esp32p4/include/hal/adc_ll.h b/components/hal/esp32p4/include/hal/adc_ll.h new file mode 100644 index 0000000000..881cfd0c63 --- /dev/null +++ b/components/hal/esp32p4/include/hal/adc_ll.h @@ -0,0 +1,913 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_attr.h" + +#include "soc/adc_periph.h" +#include "soc/adc_struct.h" +#include "soc/clk_tree_defs.h" +#include "soc/hp_sys_clkrst_struct.h" +#include "soc/lpperi_struct.h" +#include "soc/regi2c_saradc.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/adc_types.h" +#include "hal/adc_types_private.h" +#include "hal/regi2c_ctrl.h" +#include "hal/sar_ctrl_ll.h" +#include "soc/lp_adc_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) + +#define LP_ADC_FORCE_XPD_SAR_FSM 0 // Use FSM to control power down +#define LP_ADC_FORCE_XPD_SAR_PD 2 // Force power down +#define LP_ADC_FORCE_XPD_SAR_PU 3 // Force power up + +/*--------------------------------------------------------------- + Oneshot +---------------------------------------------------------------*/ +#define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) + +/*--------------------------------------------------------------- + DMA +---------------------------------------------------------------*/ +#define ADC_LL_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_FSM_RSTB_WAIT_DEFAULT (8) +#define ADC_LL_FSM_START_WAIT_DEFAULT (5) +#define ADC_LL_FSM_STANDBY_WAIT_DEFAULT (100) +#define ADC_LL_SAMPLE_CYCLE_DEFAULT (2) +#define ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT (1) + +#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 +#define ADC_LL_CLKM_DIV_B_DEFAULT 1 +#define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 +#define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 + +#define ADC_LL_POWER_MANAGE_SUPPORTED 1 //ESP32P4 supported to manage power mode +/*--------------------------------------------------------------- + PWDET (Power Detect) +---------------------------------------------------------------*/ +#define ADC_LL_PWDET_CCT_DEFAULT (4) + +typedef enum { + ADC_LL_CTRL_RTC = 0, ///< For ADC1 and ADC2. Select RTC controller. + ADC_LL_CTRL_ULP = 1, ///< For ADC1 and ADC2. Select ULP controller. + ADC_LL_CTRL_DIG = 2, ///< For ADC1 and ADC2. Select DIG controller. + ADC_LL_CTRL_PWDET = 3, ///< For ADC2. Select PWDET controller. +} adc_ll_controller_t; + +typedef enum { + ADC_LL_POWER_BY_FSM = SAR_CTRL_LL_POWER_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_LL_POWER_SW_ON = SAR_CTRL_LL_POWER_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_LL_POWER_SW_OFF = SAR_CTRL_LL_POWER_OFF, /*!< ADC XPD controlled by SW. power off. */ +} adc_ll_power_t; + +/** + * @brief ADC digital controller (DMA mode) work mode. + * + * @note The conversion mode affects the sampling frequency: + * SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once. + * SINGLE_UNIT_2: When the measurement is triggered, only ADC2 is sampled once. + * BOTH_UNIT : When the measurement is triggered, ADC1 and ADC2 are sampled at the same time. + * ALTER_UNIT : When the measurement is triggered, ADC1 or ADC2 samples alternately. + */ +typedef enum { + ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion + ADC_LL_DIGI_CONV_ONLY_ADC2 = 1, // Only use ADC2 for conversion + ADC_LL_DIGI_CONV_BOTH_UNIT = 2, // Use Both ADC1 and ADC2 for conversion simultaneously + ADC_LL_DIGI_CONV_ALTER_UNIT = 3 // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 ..... +} adc_ll_digi_convert_mode_t; + +typedef struct { + union { + struct { + uint8_t atten: 2; + uint8_t channel: 3; + uint8_t unit: 1; + uint8_t reserved: 2; + }; + uint8_t val; + }; +} __attribute__((packed)) adc_ll_digi_pattern_table_t; + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + +/** + * Set adc fsm interval parameter for digital controller. These values are fixed for same platforms. + * + * @param rst_wait cycles between DIG ADC controller reset ADC sensor and start ADC sensor. + * @param start_wait Delay time after open xpd. + * @param standby_wait Delay time to close xpd. + */ +static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait) +{ + // Internal FSM reset wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.fsm_wait, rstb_wait, rst_wait); + // Internal FSM start wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.fsm_wait, xpd_wait, start_wait); + // Internal FSM standby wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.fsm_wait, standby_wait, standby_wait); +} + +/** + * Set adc sample cycle for digital controller. + * + * @note Normally, please use default value. + * @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor. + * Range: 2 ~ 0xFF. + */ +static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle) +{ + /* Peripheral reg i2c has powered up in rtc_init, write directly */ + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle); +} + +/** + * Set SAR ADC module clock division factor. + * SAR ADC clock divided from digital controller clock. + * + * @param div Division factor. + */ +static inline void adc_ll_digi_set_clk_div(uint32_t div) +{ + /* ADC clock divided from digital controller clock clk */ + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.ctrl_reg, sar_clk_div, div); +} + +/** + * Set adc max conversion number for digital controller. + * If the number of ADC conversion is equal to the maximum, the conversion is stopped. + * + * @param meas_num Max conversion number. Range: 0 ~ 255. + */ +static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.ctrl2, max_meas_num, meas_num); +} + +/** + * Enable max conversion number detection for digital controller. + * If the number of ADC conversion is equal to the maximum, the conversion is stopped. + * + * @param enable true: enable; false: disable + */ +static inline void adc_ll_digi_convert_limit_enable(bool enable) +{ + ADC.ctrl2.meas_num_limit = enable; +} + +/** + * Set adc conversion mode for digital controller. + * + * @param mode Conversion mode select. + */ +static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode) +{ + if (mode == ADC_LL_DIGI_CONV_ONLY_ADC1) { + ADC.ctrl_reg.work_mode = 0; + ADC.ctrl_reg.sar_sel = 0; + } else if (mode == ADC_LL_DIGI_CONV_ONLY_ADC2) { + ADC.ctrl_reg.work_mode = 0; + ADC.ctrl_reg.sar_sel = 1; + } else if (mode == ADC_LL_DIGI_CONV_BOTH_UNIT) { + ADC.ctrl_reg.work_mode = 1; + } else if (mode == ADC_LL_DIGI_CONV_ALTER_UNIT) { + ADC.ctrl_reg.work_mode = 2; + } + ADC.ctrl_reg.data_sar_sel = 1; +} + +/** + * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. + * Expression: controller_clk = (APLL or APB) / (div_num + div_a / div_b + 1). + * + * @param div_num Division factor. Range: 0 ~ 255. + * @param div_b Division factor. Range: 1 ~ 63. + * @param div_a Division factor. Range: 0 ~ 63. + */ +static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl23, reg_adc_clk_div_num, div_num); + HP_SYS_CLKRST.peri_clk_ctrl23.reg_adc_clk_div_numerator = div_a; + HP_SYS_CLKRST.peri_clk_ctrl23.reg_adc_clk_div_denominator = div_b; +} + +/** + * Enable clock and select clock source for ADC digital controller. + * + * @param clk_src clock source for ADC digital controller. + */ +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) +{ + switch (clk_src) { + case ADC_DIGI_CLK_SRC_XTAL: + HP_SYS_CLKRST.peri_clk_ctrl22.reg_adc_clk_src_sel = 0; + break; + case ADC_DIGI_CLK_SRC_RC_FAST: + HP_SYS_CLKRST.peri_clk_ctrl22.reg_adc_clk_src_sel = 1; + break; + case ADC_DIGI_CLK_SRC_PLL_F80M: + HP_SYS_CLKRST.peri_clk_ctrl22.reg_adc_clk_src_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock"); + } + // Enable ADC_CTRL_CLK (i.e. digital domain clock) + ADC.ctrl_reg.sar_clk_gated = 1; +} + +/** + * Disable clock for ADC digital controller. + */ +static inline void adc_ll_digi_controller_clk_disable(void) +{ + ADC.ctrl_reg.sar_clk_gated = 0; +} + +/** + * Reset adc digital controller filter. + * + * @param idx Filter index + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n) +{ + (void)adc_n; + ADC.filter_ctrl0.filter_reset = 1; + ADC.filter_ctrl0.filter_reset = 0; +} + +/** + * Set adc digital controller filter coeff. + * + * @param idx filter index + * @param adc_n adc unit + * @param channel adc channel + * @param coeff filter coeff + */ +static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff) +{ + uint32_t factor_reg_val = 0; + switch (coeff) { + case ADC_DIGI_IIR_FILTER_COEFF_2: + factor_reg_val = 1; + break; + case ADC_DIGI_IIR_FILTER_COEFF_4: + factor_reg_val = 2; + break; + case ADC_DIGI_IIR_FILTER_COEFF_8: + factor_reg_val = 3; + break; + case ADC_DIGI_IIR_FILTER_COEFF_16: + factor_reg_val = 4; + break; + case ADC_DIGI_IIR_FILTER_COEFF_64: + factor_reg_val = 6; + break; + default: + HAL_ASSERT(false); + } + + if (idx == ADC_DIGI_IIR_FILTER_0) { + ADC.filter_ctrl0.filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7); + ADC.filter_ctrl1.filter_factor0 = factor_reg_val; + } else if (idx == ADC_DIGI_IIR_FILTER_1) { + ADC.filter_ctrl0.filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7); + ADC.filter_ctrl1.filter_factor1 = factor_reg_val; + } +} + +/** + * Enable adc digital controller filter. + * Filtering the ADC data to obtain smooth data at higher sampling rates. + * + * @param idx filter index + * @param adc_n ADC unit + * @param enable Enable / Disable + */ +static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable) +{ + (void)adc_n; + if (!enable) { + if (idx == ADC_DIGI_IIR_FILTER_0) { + ADC.filter_ctrl0.filter_channel0 = 0xF; + ADC.filter_ctrl1.filter_factor0 = 0; + } else if (idx == ADC_DIGI_IIR_FILTER_1) { + ADC.filter_ctrl0.filter_channel1 = 0xF; + ADC.filter_ctrl1.filter_factor1 = 0; + } + } + //nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled. +} + +/** + * Set pattern table length for digital controller. + * The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection, + * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the + * pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. + * + * @param adc_n ADC unit. + * @param patt_len Items range: 1 ~ 16. + */ +static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t patt_len) +{ + if (adc_n == ADC_UNIT_1) { + ADC.ctrl_reg.sar1_patt_len = patt_len - 1; + } else { // adc_n == ADC_UNIT_2 + ADC.ctrl_reg.sar2_patt_len = patt_len - 1; + } +} + +/** + * Set pattern table for digital controller. + * The pattern table that defines the conversion rules for each SAR ADC. Each table has 12 items, in which channel selection, + * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the + * pattern table one by one. For each controller the scan sequence has at most 12 different rules before repeating itself. + * + * @param adc_n ADC unit. + * @param pattern_index Items index. Range: 0 ~ 11. + * @param pattern Stored conversion rules. + */ +static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t pattern_index, adc_digi_pattern_config_t table) +{ + uint32_t tab; + uint8_t index = pattern_index / 4; + uint8_t offset = (pattern_index % 4) * 6; + adc_ll_digi_pattern_table_t pattern = {0}; + + pattern.val = (table.atten & 0x3) | ((table.channel & 0xF) << 2); + if (table.unit == ADC_UNIT_1){ + tab = ADC.sar1_patt_tab[index].sar1_patt_tab; //Read old register value + tab &= (~(0xFC0000 >> offset)); //Clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; //Fill in the new data + ADC.sar1_patt_tab[index].sar1_patt_tab = tab; //Write back + } else { + tab = ADC.sar2_patt_tab[index].sar2_patt_tab; //Read old register value + tab &= (~(0xFC0000 >> offset)); //clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; //Fill in the new data + ADC.sar2_patt_tab[index].sar2_patt_tab = tab; //Write back + } +} + +/** + * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_clear_pattern_table(adc_unit_t adc_n) +{ + if (adc_n == ADC_UNIT_1) { + ADC.ctrl_reg.sar1_patt_p_clear = 1; + ADC.ctrl_reg.sar1_patt_p_clear = 0; + } else { // adc_n == ADC_UNIT_2 + ADC.ctrl_reg.sar2_patt_p_clear = 1; + ADC.ctrl_reg.sar2_patt_p_clear = 0; + } +} + +/** + * ADC Digital controller output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_ll_digi_output_invert(adc_unit_t adc_n, bool inv_en) +{ + if (adc_n == ADC_UNIT_1) { + ADC.ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert + } else { // adc_n == ADC_UNIT_2 + ADC.ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Set the interval clock cycle for the digital controller to trigger the measurement. + * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. + * + * @note The trigger interval should not be smaller than the sampling time of the SAR ADC. + * @param cycle The clock cycle (trigger interval) of the measurement. Range: 30 ~ 4095. + */ +static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle) +{ + ADC.ctrl2.timer_target = cycle; +} + +/** + * Set DMA eof num of adc digital controller. + * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated. + * + * @param num eof num of DMA. + */ +static inline void adc_ll_digi_dma_set_eof_num(uint32_t num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.dma_conf, apb_adc_eof_num, num); +} + +/** + * Enable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_enable(void) +{ + ADC.dma_conf.apb_adc_trans = 1; +} + +/** + * Disable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_disable(void) +{ + ADC.dma_conf.apb_adc_trans = 0; +} + +/** + * Reset adc digital controller. + */ +static inline void adc_ll_digi_reset(void) +{ + ADC.dma_conf.apb_adc_reset_fsm = 1; + ADC.dma_conf.apb_adc_reset_fsm = 0; +} + +/** + * Enable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_enable(void) +{ + ADC.ctrl2.timer_sel = 1; + ADC.ctrl2.timer_en = 1; +} + +/** + * Disable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_disable(void) +{ + ADC.ctrl2.timer_en = 0; +} + +/*--------------------------------------------------------------- + PWDET(Power detect) controller setting +---------------------------------------------------------------*/ + +/** + * Set adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @param cct Range: 0 ~ 7. + */ +static inline void adc_ll_pwdet_set_cct(uint32_t cct) +{ + /* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */ + LP_ADC.meas2_mux.sar2_pwdet_cct = cct; +} + +/** + * Get adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @return cct Range: 0 ~ 7. + */ +static inline uint32_t adc_ll_pwdet_get_cct(void) +{ + /* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */ + return LP_ADC.meas2_mux.sar2_pwdet_cct; +} + +/*--------------------------------------------------------------- + Common setting +---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + HP_SYS_CLKRST.soc_clk_ctrl2.reg_adc_apb_clk_en = enable; + HP_SYS_CLKRST.peri_clk_ctrl23.reg_adc_clk_en = enable; +} +// HP_SYS_CLKRST.soc_clk_ctrl2 are shared registers, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_adc = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_adc = 0; +} +// HP_SYS_CLKRST.hp_rst_en2 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + + + +/** + * Set ADC digital controller power management. + * + * @param adc_n ADC unit. + * @param manage Set ADC power status. + */ +static inline void adc_ll_digi_set_power_manage(adc_unit_t adc_n, adc_ll_power_t manage) +{ + if (adc_n == ADC_UNIT_1) { + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + ADC.ctrl_reg.sar_clk_gated = 1; + ADC.ctrl_reg.xpd_sar1_force = LP_ADC_FORCE_XPD_SAR_PU; + } else if (manage == ADC_LL_POWER_BY_FSM) { + ADC.ctrl_reg.sar_clk_gated = 1; + ADC.ctrl_reg.xpd_sar1_force = LP_ADC_FORCE_XPD_SAR_FSM; + } else if (manage == ADC_LL_POWER_SW_OFF) { + ADC.ctrl_reg.sar_clk_gated = 0; + ADC.ctrl_reg.xpd_sar1_force = LP_ADC_FORCE_XPD_SAR_PD; + } + } else { + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + ADC.ctrl_reg.sar_clk_gated = 1; + ADC.ctrl_reg.xpd_sar2_force = LP_ADC_FORCE_XPD_SAR_PU; + } else if (manage == ADC_LL_POWER_BY_FSM) { + ADC.ctrl_reg.sar_clk_gated = 1; + ADC.ctrl_reg.xpd_sar2_force = LP_ADC_FORCE_XPD_SAR_FSM; + } else if (manage == ADC_LL_POWER_SW_OFF) { + ADC.ctrl_reg.sar_clk_gated = 0; + ADC.ctrl_reg.xpd_sar2_force = LP_ADC_FORCE_XPD_SAR_PD; + } + } +} + +/** + * Set ADC module power management. + * + * @param adc_n ADC unit. + * @param manage Set ADC power status. + */ +static inline void adc_ll_set_power_manage(adc_unit_t adc_n, adc_ll_power_t manage) +{ + adc_ll_digi_set_power_manage(adc_n, manage); + if (adc_n == ADC_UNIT_1) { + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + LPPERI.clk_en.ck_en_lp_adc = 1; + LP_ADC.force_wpd_sar.force_xpd_sar1 = LP_ADC_FORCE_XPD_SAR_PU; + } else if (manage == ADC_LL_POWER_BY_FSM) { + LPPERI.clk_en.ck_en_lp_adc = 1; + LP_ADC.force_wpd_sar.force_xpd_sar1 = LP_ADC_FORCE_XPD_SAR_FSM; + } else if (manage == ADC_LL_POWER_SW_OFF) { + LP_ADC.force_wpd_sar.force_xpd_sar1 = LP_ADC_FORCE_XPD_SAR_PD; + LPPERI.clk_en.ck_en_lp_adc = 0; + } + } else { + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + LPPERI.clk_en.ck_en_lp_adc = 1; + LP_ADC.force_wpd_sar.force_xpd_sar2 = LP_ADC_FORCE_XPD_SAR_PU; + } else if (manage == ADC_LL_POWER_BY_FSM) { + LPPERI.clk_en.ck_en_lp_adc = 1; + LP_ADC.force_wpd_sar.force_xpd_sar2 = LP_ADC_FORCE_XPD_SAR_FSM; + } else if (manage == ADC_LL_POWER_SW_OFF) { + LP_ADC.force_wpd_sar.force_xpd_sar2 = LP_ADC_FORCE_XPD_SAR_PD; + LPPERI.clk_en.ck_en_lp_adc = 0; + } + } +} + + +/** + * Set ADC module controller. + * There are five SAR ADC controllers: + * Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes; + * Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep; + * the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2. + * + * @param adc_n ADC unit. + * @param ctrl ADC controller. + */ +__attribute__((always_inline)) +static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t ctrl) +{ + if (adc_n == ADC_UNIT_1) { + switch (ctrl) { + case ADC_LL_CTRL_RTC: + LP_ADC.meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + case ADC_LL_CTRL_ULP: + LP_ADC.meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas1_ctrl2.meas1_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas1_ctrl2.sar1_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + case ADC_LL_CTRL_DIG: + LP_ADC.meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + default: + break; + } + } else { // adc_n == ADC_UNIT_2 + switch (ctrl) { + case ADC_LL_CTRL_RTC: + LP_ADC.meas2_mux.sar2_rtc_force = 1; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + case ADC_LL_CTRL_ULP: + LP_ADC.meas2_mux.sar2_rtc_force = 0; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas2_ctrl2.meas2_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas2_ctrl2.sar2_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + case ADC_LL_CTRL_DIG: + LP_ADC.meas2_mux.sar2_rtc_force = 0; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + default: + break; + } + } +} + +/*--------------------------------------------------------------- + Oneshot Read +---------------------------------------------------------------*/ + +static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, bool en) +{ + abort(); +} + +/** + * Set adc output data format for RTC controller. + * + * @note ESP32P4 RTC controller only support 12bit. + * @param adc_n ADC unit. + * @param bits Output data bits width option. + */ +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) +{ + //ESP32P4 only supports 12bit, leave here for compatibility + HAL_ASSERT(bits == ADC_BITWIDTH_12 || bits == ADC_BITWIDTH_DEFAULT); +} + +/** + * Enable adc channel to start convert. + * + * @note Only one channel can be selected for once measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.meas1_ctrl2.sar1_en_pad = (1 << channel); //only one channel is selected. + } else { // adc_n == ADC_UNIT_2 + LP_ADC.meas2_ctrl2.sar2_en_pad = (1 << ((channel + 2))); //only one channel is selected. + } +} + +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected. + } else { // adc_n == ADC_UNIT_2 + LP_ADC.meas2_ctrl2.sar2_en_pad = 0; //only one channel is selected. + } +} + +/** + * Start conversion once by software for RTC controller. + * + * @note It may be block to wait conversion idle for ADC1. + * + * @param adc_n ADC unit. + */ +static inline void adc_oneshot_ll_start(adc_unit_t adc_n) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.meas1_ctrl2.meas1_start_sar = 0; + LP_ADC.meas1_ctrl2.meas1_start_sar = 1; + } else { // adc_n == ADC_UNIT_2 + LP_ADC.meas2_ctrl2.meas2_start_sar = 0; + LP_ADC.meas2_ctrl2.meas2_start_sar = 1; + } +} + +/** + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event_mask) +{ + // ADC.int_clr.val |= event_mask; +} + +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event + * + * @return + * -true : The conversion process is finish. + * -false : The conversion process is not finish. + */ +static inline bool adc_oneshot_ll_get_event(uint32_t event) +{ + bool ret = true; + if (event == ADC_LL_EVENT_ADC1_ONESHOT_DONE) { + ret = (bool)LP_ADC.meas1_ctrl2.meas1_done_sar; + } else if (event == ADC_LL_EVENT_ADC2_ONESHOT_DONE) { + ret = (bool)LP_ADC.meas2_ctrl2.meas2_done_sar; + } else { + HAL_ASSERT(false); + } + return ret; +} + +/** + * Get the converted value for each ADCn for RTC controller. + * + * @param adc_n ADC unit. + * @return + * - Converted value. + */ +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) +{ + uint32_t ret_val = 0; + if (adc_n == ADC_UNIT_1) { + ret_val = HAL_FORCE_READ_U32_REG_FIELD(LP_ADC.meas1_ctrl2, meas1_data_sar); + } else { // adc_n == ADC_UNIT_2 + ret_val = HAL_FORCE_READ_U32_REG_FIELD(LP_ADC.meas2_ctrl2, meas2_data_sar); + } + return ret_val; +} + +/** + * Analyze whether the obtained raw data is correct. + * + * @param adc_n ADC unit. + * @param raw ADC raw data input (convert value). + * @return + * - true: raw data is valid + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw) +{ + /* No arbiter, don't need check data */ + return true; +} + +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert + } else { // adc_n == ADC_UNIT_2 + LP_ADC.reader2_ctrl.sar2_data_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Enable oneshot conversion trigger + * + * @param adc_n ADC unit + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + (void)adc_n; + //For compatibility +} + +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) +{ + //For compatibility +} + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ +/** + * ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`. + * + * @param div Division factor. + */ +static inline void adc_ll_set_sar_clk_div(adc_unit_t adc_n, uint32_t div) +{ + if (adc_n == ADC_UNIT_1) { + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ADC.reader1_ctrl, sar1_clk_div, div); + } else { // adc_n == ADC_UNIT_2 + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ADC.reader2_ctrl, sar2_clk_div, div); + } +} + +/** + * Reset RTC controller FSM. + */ +static inline void adc_ll_rtc_reset(void) +{ + LPPERI.reset_en.rst_en_lp_adc = 1; + LPPERI.reset_en.rst_en_lp_adc = 0; +} + + +/** + * Set the attenuation of a particular channel on ADCn. + * + * @note For any given channel, this function must be called before the first time conversion. + * + * The default ADC full-scale voltage is 1.1V. To read higher voltages (up to the pin maximum voltage, + * usually 3.3V) requires setting >0dB signal attenuation for that ADC channel. + * + * When VDD_A is 3.3V: + * + * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V + * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V + * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V + * - 11dB attenuation (ADC_ATTEN_DB_12) gives full-scale voltage 3.9V (see note below) + * + * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured + * bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.) + * + * @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. + * + * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: + * + * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV + * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV + * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV + * - 11dB attenuation (ADC_ATTEN_DB_12) between 150 to 2450mV + * + * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. + * + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @param atten The attenuation option. + */ +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.atten1.sar1_atten = ( LP_ADC.atten1.sar1_atten & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2)); + } else { // adc_n == ADC_UNIT_2 + LP_ADC.atten2.sar2_atten = ( LP_ADC.atten2.sar2_atten & ~(0x3 << ((channel + 2) * 2)) ) | ((atten & 0x3) << ((channel + 2) * 2)); + } +} + +/** + * Get the attenuation of a particular channel on ADCn. + * + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @return atten The attenuation option. + */ +__attribute__((always_inline)) +static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t channel) +{ + if (adc_n == ADC_UNIT_1) { + return (adc_atten_t)((LP_ADC.atten1.sar1_atten >> (channel * 2)) & 0x3); + } else { + return (adc_atten_t)((LP_ADC.atten2.sar2_atten >> ((channel + 2) * 2)) & 0x3); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/sar_ctrl_ll.h b/components/hal/esp32p4/include/hal/sar_ctrl_ll.h index 60f26337cd..8c0b02bc6d 100644 --- a/components/hal/esp32p4/include/hal/sar_ctrl_ll.h +++ b/components/hal/esp32p4/include/hal/sar_ctrl_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include #include #include "soc/soc.h" +#include "soc/lp_adc_struct.h" #ifdef __cplusplus extern "C" { @@ -39,6 +40,27 @@ typedef enum { /*--------------------------------------------------------------- SAR power control ---------------------------------------------------------------*/ + +/** + * Set SAR power mode + * + * @param mode See `sar_ctrl_ll_power_t` + */ +__attribute__((always_inline)) +static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode) +{ + if (mode == SAR_CTRL_LL_POWER_FSM) { + LP_ADC.force_wpd_sar.force_xpd_sar1 = 0x0; + LP_ADC.force_wpd_sar.force_xpd_sar2 = 0x0; + } else if (mode == SAR_CTRL_LL_POWER_ON) { + LP_ADC.force_wpd_sar.force_xpd_sar1 = 0x3; + LP_ADC.force_wpd_sar.force_xpd_sar2 = 0x3; + } else { + LP_ADC.force_wpd_sar.force_xpd_sar1 = 0x2; + LP_ADC.force_wpd_sar.force_xpd_sar2 = 0x2; + } +} + /** * @brief Set SAR power mode when controlled by PWDET * diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index 1344a64970..d0b558cc61 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,8 @@ #include "soc/clk_tree_defs.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" +#include "soc/system_reg.h" +#include "soc/dport_reg.h" #ifdef __cplusplus extern "C" { @@ -40,6 +42,7 @@ extern "C" { #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) +#define ADC_LL_RTC_GPIO_SUPPORTED (1) /*--------------------------------------------------------------- DMA @@ -917,6 +920,32 @@ static inline void adc_oneshot_ll_disable_all_unit(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); + reg_val = reg_val & (~DPORT_APB_SARADC_CLK_EN); + reg_val = reg_val | (enable << DPORT_APB_SARADC_CLK_EN_S); + WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_val); +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_APB_SARADC_RST); + CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_APB_SARADC_RST); +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index 7e0f405e1f..ec8180c048 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include "soc/rtc_cntl_reg.h" #include "soc/regi2c_defs.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" @@ -43,6 +44,7 @@ extern "C" { #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) +#define ADC_LL_RTC_GPIO_SUPPORTED (1) /*--------------------------------------------------------------- DMA @@ -611,6 +613,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32s3/include/hal/rtc_io_ll.h b/components/hal/esp32s3/include/hal/rtc_io_ll.h index 1a988c000c..86d483b217 100644 --- a/components/hal/esp32s3/include/hal/rtc_io_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_io_ll.h @@ -19,6 +19,7 @@ #include "soc/io_mux_reg.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "soc/sens_struct.h" #ifdef __cplusplus extern "C" { @@ -27,7 +28,7 @@ extern "C" { #define RTCIO_LL_PIN_FUNC 0 typedef enum { - RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controled by RTC module. */ + RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */ RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ } rtcio_ll_func_t; diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index 063e3ab3c4..b37689afe8 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -191,7 +191,7 @@ typedef struct { }; } adc_digi_output_data_t; -#elif CONFIG_IDF_TARGET_ESP32S3 +#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4 /** * @brief ADC digital controller (DMA mode) output data format. * Used to analyze the acquired ADC (DMA) data. diff --git a/components/idf_test/include/esp32p4/idf_performance_target.h b/components/idf_test/include/esp32p4/idf_performance_target.h index a312d550f9..90ad9b1e3a 100644 --- a/components/idf_test/include/esp32p4/idf_performance_target.h +++ b/components/idf_test/include/esp32p4/idf_performance_target.h @@ -10,3 +10,11 @@ /* Solicited yields (portYIELD() or taskYIELD()) take longer on esp32p4. TODO: IDF-2809 */ #define IDF_PERFORMANCE_MAX_SCHEDULING_TIME 3200 + +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64 10 +#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3 10 diff --git a/components/soc/esp32p4/adc_periph.c b/components/soc/esp32p4/adc_periph.c index 47081cfc68..fe4445b44e 100644 --- a/components/soc/esp32p4/adc_periph.c +++ b/components/soc/esp32p4/adc_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,4 +7,15 @@ #include "soc/adc_periph.h" /* Store IO number corresponding to the ADC channel number. */ -const int adc_channel_io_map[SOC_ADC_PERIPH_NUM][SOC_ADC_MAX_CHANNEL_NUM] = {}; +const int adc_channel_io_map[SOC_ADC_PERIPH_NUM][SOC_ADC_MAX_CHANNEL_NUM] = { + /* ADC1 */ + { + ADC1_CHANNEL_0_GPIO_NUM, ADC1_CHANNEL_1_GPIO_NUM, ADC1_CHANNEL_2_GPIO_NUM, ADC1_CHANNEL_3_GPIO_NUM, + ADC1_CHANNEL_4_GPIO_NUM, ADC1_CHANNEL_5_GPIO_NUM, ADC1_CHANNEL_6_GPIO_NUM, ADC1_CHANNEL_7_GPIO_NUM + }, + /* ADC2 */ + { + ADC2_CHANNEL_0_GPIO_NUM, ADC2_CHANNEL_1_GPIO_NUM, ADC2_CHANNEL_2_GPIO_NUM, + ADC2_CHANNEL_3_GPIO_NUM, ADC2_CHANNEL_4_GPIO_NUM, ADC2_CHANNEL_5_GPIO_NUM + } +}; diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index ab97a343da..ebee09a5d9 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -3,6 +3,10 @@ # using gen_soc_caps_kconfig.py, do not edit manually ##################################################### +config SOC_ADC_SUPPORTED + bool + default y + config SOC_ANA_CMPR_SUPPORTED bool default y @@ -307,13 +311,25 @@ config SOC_AES_SUPPORT_AES_256 bool default y +config SOC_ADC_RTC_CTRL_SUPPORTED + bool + default y + +config SOC_ADC_DIG_CTRL_SUPPORTED + bool + default y + +config SOC_ADC_DMA_SUPPORTED + bool + default y + config SOC_ADC_PERIPH_NUM int - default 1 + default 2 config SOC_ADC_MAX_CHANNEL_NUM int - default 7 + default 8 config SOC_ADC_ATTEN_NUM int @@ -321,11 +337,11 @@ config SOC_ADC_ATTEN_NUM config SOC_ADC_DIGI_CONTROLLER_NUM int - default 1 + default 2 config SOC_ADC_PATT_LEN_MAX int - default 8 + default 16 config SOC_ADC_DIGI_MAX_BITWIDTH int @@ -371,6 +387,10 @@ config SOC_ADC_CALIBRATION_V1_SUPPORTED bool default n +config SOC_ADC_SHARED_POWER + bool + default y + config SOC_APB_BACKUP_DMA bool default n diff --git a/components/soc/esp32p4/include/soc/adc_channel.h b/components/soc/esp32p4/include/soc/adc_channel.h index d2aa55b41e..1d95c0d19a 100644 --- a/components/soc/esp32p4/include/soc/adc_channel.h +++ b/components/soc/esp32p4/include/soc/adc_channel.h @@ -1,7 +1,49 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once + +#define ADC1_GPIO16_CHANNEL 0 +#define ADC1_CHANNEL_0_GPIO_NUM 16 + +#define ADC1_GPIO17_CHANNEL 1 +#define ADC1_CHANNEL_1_GPIO_NUM 17 + +#define ADC1_GPIO18_CHANNEL 2 +#define ADC1_CHANNEL_2_GPIO_NUM 18 + +#define ADC1_GPIO19_CHANNEL 3 +#define ADC1_CHANNEL_3_GPIO_NUM 19 + +#define ADC1_GPIO20_CHANNEL 4 +#define ADC1_CHANNEL_4_GPIO_NUM 20 + +#define ADC1_GPIO21_CHANNEL 5 +#define ADC1_CHANNEL_5_GPIO_NUM 21 + +#define ADC1_GPIO22_CHANNEL 6 +#define ADC1_CHANNEL_6_GPIO_NUM 22 + +#define ADC1_GPIO23_CHANNEL 7 +#define ADC1_CHANNEL_7_GPIO_NUM 23 + +#define ADC2_GPIO49_CHANNEL 0 +#define ADC2_CHANNEL_0_GPIO_NUM 49 + +#define ADC2_GPIO50_CHANNEL 1 +#define ADC2_CHANNEL_1_GPIO_NUM 50 + +#define ADC2_GPIO51_CHANNEL 2 +#define ADC2_CHANNEL_2_GPIO_NUM 51 + +#define ADC2_GPIO52_CHANNEL 3 +#define ADC2_CHANNEL_3_GPIO_NUM 52 + +#define ADC2_GPIO53_CHANNEL 4 +#define ADC2_CHANNEL_4_GPIO_NUM 53 + +#define ADC2_GPIO54_CHANNEL 5 +#define ADC2_CHANNEL_5_GPIO_NUM 54 diff --git a/components/soc/esp32p4/include/soc/adc_reg.h b/components/soc/esp32p4/include/soc/adc_reg.h index 1247201710..c495c57bf6 100644 --- a/components/soc/esp32p4/include/soc/adc_reg.h +++ b/components/soc/esp32p4/include/soc/adc_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -195,6 +195,26 @@ extern "C" { #define ADC_FILTER_FACTOR0_V 0x00000007U #define ADC_FILTER_FACTOR0_S 29 +#define ADC_FSM_WAIT_REG (DR_REG_ADC_BASE + 0xC) +/* ADC_STANDBY_WAIT : R/W ;bitpos:[23:16] ;default: 8'd255 ; */ +/*description: need_des.*/ +#define ADC_STANDBY_WAIT 0x000000FF +#define ADC_STANDBY_WAIT_M ((ADC_STANDBY_WAIT_V)<<(ADC_STANDBY_WAIT_S)) +#define ADC_STANDBY_WAIT_V 0xFF +#define ADC_STANDBY_WAIT_S 16 +/* ADC_RSTB_WAIT : R/W ;bitpos:[15:8] ;default: 8'd8 ; */ +/*description: need_des.*/ +#define ADC_RSTB_WAIT 0x000000FF +#define ADC_RSTB_WAIT_M ((ADC_RSTB_WAIT_V)<<(ADC_RSTB_WAIT_S)) +#define ADC_RSTB_WAIT_V 0xFF +#define ADC_RSTB_WAIT_S 8 +/* ADC_XPD_WAIT : R/W ;bitpos:[7:0] ;default: 8'd8 ; */ +/*description: need_des.*/ +#define ADC_XPD_WAIT 0x000000FF +#define ADC_XPD_WAIT_M ((ADC_XPD_WAIT_V)<<(ADC_XPD_WAIT_S)) +#define ADC_XPD_WAIT_V 0xFF +#define ADC_XPD_WAIT_S 0 + /** ADC_SAR1_PATT_TAB1_REG register * Register */ diff --git a/components/soc/esp32p4/include/soc/adc_struct.h b/components/soc/esp32p4/include/soc/adc_struct.h index 54f7a7af02..c534937c36 100644 --- a/components/soc/esp32p4/include/soc/adc_struct.h +++ b/components/soc/esp32p4/include/soc/adc_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -137,117 +137,46 @@ typedef union { uint32_t val; } adc_filter_ctrl1_reg_t; -/** Type of sar1_patt_tab1 register +/** Type of filter_ctrl1 register * Register */ typedef union { struct { - /** sar1_patt_tab1 : R/W; bitpos: [23:0]; default: 0; + uint32_t xpd_wait:8; + uint32_t rstb_wait:8; + uint32_t standby_wait:8; + uint32_t reserved24:8; + }; + uint32_t val; +} adc_fsm_wait_reg_t; + +/** Type of sar1_patt_tab register + * Register + */ +typedef union { + struct { + /** sar1_patt_tab : R/W; bitpos: [23:0]; default: 0; * item 0 ~ 3 for pattern table 1 (each item one byte) */ - uint32_t sar1_patt_tab1:24; + uint32_t sar1_patt_tab:24; uint32_t reserved_24:8; }; uint32_t val; -} adc_sar1_patt_tab1_reg_t; - -/** Type of sar1_patt_tab2 register - * Register - */ -typedef union { - struct { - /** sar1_patt_tab2 : R/W; bitpos: [23:0]; default: 0; - * Item 4 ~ 7 for pattern table 1 (each item one byte) - */ - uint32_t sar1_patt_tab2:24; - uint32_t reserved_24:8; - }; - uint32_t val; -} adc_sar1_patt_tab2_reg_t; - -/** Type of sar1_patt_tab3 register - * Register - */ -typedef union { - struct { - /** sar1_patt_tab3 : R/W; bitpos: [23:0]; default: 0; - * Item 8 ~ 11 for pattern table 1 (each item one byte) - */ - uint32_t sar1_patt_tab3:24; - uint32_t reserved_24:8; - }; - uint32_t val; -} adc_sar1_patt_tab3_reg_t; - -/** Type of sar1_patt_tab4 register - * Register - */ -typedef union { - struct { - /** sar1_patt_tab4 : R/W; bitpos: [23:0]; default: 0; - * Item 12 ~ 15 for pattern table 1 (each item one byte) - */ - uint32_t sar1_patt_tab4:24; - uint32_t reserved_24:8; - }; - uint32_t val; -} adc_sar1_patt_tab4_reg_t; +} adc_sar1_patt_tab_reg_t; /** Type of sar2_patt_tab1 register * Register */ typedef union { struct { - /** sar2_patt_tab1 : R/W; bitpos: [23:0]; default: 0; + /** sar2_patt_tab : R/W; bitpos: [23:0]; default: 0; * item 0 ~ 3 for pattern table 2 (each item one byte) */ - uint32_t sar2_patt_tab1:24; + uint32_t sar2_patt_tab:24; uint32_t reserved_24:8; }; uint32_t val; -} adc_sar2_patt_tab1_reg_t; - -/** Type of sar2_patt_tab2 register - * Register - */ -typedef union { - struct { - /** sar2_patt_tab2 : R/W; bitpos: [23:0]; default: 0; - * Item 4 ~ 7 for pattern table 2 (each item one byte) - */ - uint32_t sar2_patt_tab2:24; - uint32_t reserved_24:8; - }; - uint32_t val; -} adc_sar2_patt_tab2_reg_t; - -/** Type of sar2_patt_tab3 register - * Register - */ -typedef union { - struct { - /** sar2_patt_tab3 : R/W; bitpos: [23:0]; default: 0; - * Item 8 ~ 11 for pattern table 2 (each item one byte) - */ - uint32_t sar2_patt_tab3:24; - uint32_t reserved_24:8; - }; - uint32_t val; -} adc_sar2_patt_tab3_reg_t; - -/** Type of sar2_patt_tab4 register - * Register - */ -typedef union { - struct { - /** sar2_patt_tab4 : R/W; bitpos: [23:0]; default: 0; - * Item 12 ~ 15 for pattern table 2 (each item one byte) - */ - uint32_t sar2_patt_tab4:24; - uint32_t reserved_24:8; - }; - uint32_t val; -} adc_sar2_patt_tab4_reg_t; +} adc_sar2_patt_tab_reg_t; /** Type of arb_ctrl register * Register @@ -655,15 +584,10 @@ typedef struct { volatile adc_ctrl_reg_reg_t ctrl_reg; volatile adc_ctrl2_reg_t ctrl2; volatile adc_filter_ctrl1_reg_t filter_ctrl1; - uint32_t reserved_00c[3]; - volatile adc_sar1_patt_tab1_reg_t sar1_patt_tab1; - volatile adc_sar1_patt_tab2_reg_t sar1_patt_tab2; - volatile adc_sar1_patt_tab3_reg_t sar1_patt_tab3; - volatile adc_sar1_patt_tab4_reg_t sar1_patt_tab4; - volatile adc_sar2_patt_tab1_reg_t sar2_patt_tab1; - volatile adc_sar2_patt_tab2_reg_t sar2_patt_tab2; - volatile adc_sar2_patt_tab3_reg_t sar2_patt_tab3; - volatile adc_sar2_patt_tab4_reg_t sar2_patt_tab4; + volatile adc_fsm_wait_reg_t fsm_wait; + uint32_t reserved_00c[2]; + volatile adc_sar1_patt_tab_reg_t sar1_patt_tab[4]; + volatile adc_sar2_patt_tab_reg_t sar2_patt_tab[4]; volatile adc_arb_ctrl_reg_t arb_ctrl; volatile adc_filter_ctrl0_reg_t filter_ctrl0; volatile adc_sar1_data_status_reg_t sar1_data_status; @@ -684,6 +608,7 @@ typedef struct { volatile adc_ctrl_date_reg_t ctrl_date; } adc_dev_t; +extern adc_dev_t ADC; #ifndef __cplusplus _Static_assert(sizeof(adc_dev_t) == 0x400, "Invalid size of adc_dev_t structure"); diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index 5679247b50..59da431669 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -589,6 +589,34 @@ typedef enum { //////////////////////////////////////////////////ADC/////////////////////////////////////////////////////////////////// +/** + * @brief Array initializer for all supported clock sources of ADC digital controller + */ +#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST} + +/** + * @brief ADC digital controller clock source + */ +typedef enum { + ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + ADC_DIGI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */ + ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */ +} soc_periph_adc_digi_clk_src_t; + +/** + * @brief Array initializer for all supported clock sources of ADC RTC controller + */ +#define SOC_ADC_RTC_CLKS {SOC_MOD_CLK_RC_FAST} + +/** + * @brief ADC RTC controller clock source + */ +typedef enum { + ADC_RTC_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the default clock choice */ +} soc_periph_adc_rtc_clk_src_t; + //////////////////////////////////////////////////MWDT///////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32p4/include/soc/rtcadc_reg.h b/components/soc/esp32p4/include/soc/lp_adc_reg.h similarity index 100% rename from components/soc/esp32p4/include/soc/rtcadc_reg.h rename to components/soc/esp32p4/include/soc/lp_adc_reg.h diff --git a/components/soc/esp32p4/include/soc/rtcadc_struct.h b/components/soc/esp32p4/include/soc/lp_adc_struct.h similarity index 96% rename from components/soc/esp32p4/include/soc/rtcadc_struct.h rename to components/soc/esp32p4/include/soc/lp_adc_struct.h index be919a948b..0886d6ba2a 100644 --- a/components/soc/esp32p4/include/soc/rtcadc_struct.h +++ b/components/soc/esp32p4/include/soc/lp_adc_struct.h @@ -259,11 +259,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_raw:1; /** cocpu_saradc1_error_int_raw : R/WTC/SS; bitpos: [2]; default: 0; - * An errro occurs from ADC1, int raw. + * An error occurs from ADC1, int raw. */ uint32_t cocpu_saradc1_error_int_raw:1; /** cocpu_saradc2_error_int_raw : R/WTC/SS; bitpos: [3]; default: 0; - * An errro occurs from ADC2, int raw. + * An error occurs from ADC2, int raw. */ uint32_t cocpu_saradc2_error_int_raw:1; /** cocpu_saradc1_wake_int_raw : R/WTC/SS; bitpos: [4]; default: 0; @@ -293,11 +293,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_ena:1; /** cocpu_saradc1_error_int_ena : R/WTC; bitpos: [2]; default: 0; - * An errro occurs from ADC1, int enable. + * An error occurs from ADC1, int enable. */ uint32_t cocpu_saradc1_error_int_ena:1; /** cocpu_saradc2_error_int_ena : R/WTC; bitpos: [3]; default: 0; - * An errro occurs from ADC2, int enable. + * An error occurs from ADC2, int enable. */ uint32_t cocpu_saradc2_error_int_ena:1; /** cocpu_saradc1_wake_int_ena : R/WTC; bitpos: [4]; default: 0; @@ -327,11 +327,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_st:1; /** cocpu_saradc1_error_int_st : RO; bitpos: [2]; default: 0; - * An errro occurs from ADC1, int status. + * An error occurs from ADC1, int status. */ uint32_t cocpu_saradc1_error_int_st:1; /** cocpu_saradc2_error_int_st : RO; bitpos: [3]; default: 0; - * An errro occurs from ADC2, int status. + * An error occurs from ADC2, int status. */ uint32_t cocpu_saradc2_error_int_st:1; /** cocpu_saradc1_wake_int_st : RO; bitpos: [4]; default: 0; @@ -361,11 +361,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_clr:1; /** cocpu_saradc1_error_int_clr : WT; bitpos: [2]; default: 0; - * An errro occurs from ADC1, int clear. + * An error occurs from ADC1, int clear. */ uint32_t cocpu_saradc1_error_int_clr:1; /** cocpu_saradc2_error_int_clr : WT; bitpos: [3]; default: 0; - * An errro occurs from ADC2, int clear. + * An error occurs from ADC2, int clear. */ uint32_t cocpu_saradc2_error_int_clr:1; /** cocpu_saradc1_wake_int_clr : WT; bitpos: [4]; default: 0; @@ -395,11 +395,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_ena_w1ts:1; /** cocpu_saradc1_error_int_ena_w1ts : WT; bitpos: [2]; default: 0; - * An errro occurs from ADC1, write 1 to assert int enable. + * An error occurs from ADC1, write 1 to assert int enable. */ uint32_t cocpu_saradc1_error_int_ena_w1ts:1; /** cocpu_saradc2_error_int_ena_w1ts : WT; bitpos: [3]; default: 0; - * An errro occurs from ADC2, write 1 to assert int enable. + * An error occurs from ADC2, write 1 to assert int enable. */ uint32_t cocpu_saradc2_error_int_ena_w1ts:1; /** cocpu_saradc1_wake_int_ena_w1ts : WT; bitpos: [4]; default: 0; @@ -429,11 +429,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_ena_w1tc:1; /** cocpu_saradc1_error_int_ena_w1tc : WT; bitpos: [2]; default: 0; - * An errro occurs from ADC1, write 1 to deassert int enable. + * An error occurs from ADC1, write 1 to deassert int enable. */ uint32_t cocpu_saradc1_error_int_ena_w1tc:1; /** cocpu_saradc2_error_int_ena_w1tc : WT; bitpos: [3]; default: 0; - * An errro occurs from ADC2, write 1 to deassert int enable. + * An error occurs from ADC2, write 1 to deassert int enable. */ uint32_t cocpu_saradc2_error_int_ena_w1tc:1; /** cocpu_saradc1_wake_int_ena_w1tc : WT; bitpos: [4]; default: 0; @@ -592,6 +592,7 @@ typedef struct { volatile rtcadc_sar2_hw_wakeup_reg_t sar2_hw_wakeup; } rtcadc_dev_t; +extern rtcadc_dev_t LP_ADC; #ifndef __cplusplus _Static_assert(sizeof(rtcadc_dev_t) == 0x74, "Invalid size of rtcadc_dev_t structure"); diff --git a/components/soc/esp32p4/include/soc/reg_base.h b/components/soc/esp32p4/include/soc/reg_base.h index f6a845a421..f851cb5c74 100644 --- a/components/soc/esp32p4/include/soc/reg_base.h +++ b/components/soc/esp32p4/include/soc/reg_base.h @@ -43,7 +43,7 @@ #define DR_REG_REGDMA_BASE (DR_REG_HPPERIPH0_BASE + 0x82000) #define DR_REG_SDMMC_BASE (DR_REG_HPPERIPH0_BASE + 0x83000) #define DR_REG_H264_CORE_BASE (DR_REG_HPPERIPH0_BASE + 0x84000) -#define DR_REG_AHB_PDMA_BASE (DR_REG_HPPERIPH0_BASE + 0x85000) +#define DR_REG_AHB_DMA_BASE (DR_REG_HPPERIPH0_BASE + 0x85000) #define DR_REG_JPEG_BASE (DR_REG_HPPERIPH0_BASE + 0x86000) #define DR_REG_PPA_BASE (DR_REG_HPPERIPH0_BASE + 0x87000) #define DR_REG_DMA2D_BASE (DR_REG_HPPERIPH0_BASE + 0x88000) diff --git a/components/soc/esp32p4/include/soc/regi2c_saradc.h b/components/soc/esp32p4/include/soc/regi2c_saradc.h index b784a26a3e..88fa3640bc 100644 --- a/components/soc/esp32p4/include/soc/regi2c_saradc.h +++ b/components/soc/esp32p4/include/soc/regi2c_saradc.h @@ -37,3 +37,44 @@ #define I2C_SAR_ADC_DTEST_VDD_GRP1 9 #define I2C_SAR_ADC_DTEST_VDD_GRP1_MSB 3 #define I2C_SAR_ADC_DTEST_VDD_GRP1_LSB 0 + +#define ADC_SAR1_SAMPLE_CYCLE_ADDR 0x2 +#define ADC_SAR1_SAMPLE_CYCLE_ADDR_MSB 0x2 +#define ADC_SAR1_SAMPLE_CYCLE_ADDR_LSB 0x0 + +#define ADC_SAR1_DREF_ADDR 0x2 +#define ADC_SAR1_DREF_ADDR_MSB 0x6 +#define ADC_SAR1_DREF_ADDR_LSB 0x4 + +#define ADC_SAR2_INITIAL_CODE_LOW_ADDR 0x3 +#define ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB 0x7 +#define ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB 0x0 + +#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR 0x4 +#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB 0x3 +#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB 0x0 + + +#define ADC_SAR2_SAMPLE_CYCLE_ADDR 0x5 +#define ADC_SAR2_SAMPLE_CYCLE_ADDR_MSB 0x2 +#define ADC_SAR2_SAMPLE_CYCLE_ADDR_LSB 0x0 + +#define ADC_SAR2_DREF_ADDR 0x5 +#define ADC_SAR2_DREF_ADDR_MSB 0x6 +#define ADC_SAR2_DREF_ADDR_LSB 0x4 + +#define ADC_SAR1_ENCAL_REF_ADDR 0x7 +#define ADC_SAR1_ENCAL_REF_ADDR_MSB 4 +#define ADC_SAR1_ENCAL_REF_ADDR_LSB 4 + +#define ADC_SAR1_ENCAL_GND_ADDR 0x7 +#define ADC_SAR1_ENCAL_GND_ADDR_MSB 5 +#define ADC_SAR1_ENCAL_GND_ADDR_LSB 5 + +#define ADC_SAR2_ENCAL_REF_ADDR 0x7 +#define ADC_SAR2_ENCAL_REF_ADDR_MSB 6 +#define ADC_SAR2_ENCAL_REF_ADDR_LSB 6 + +#define ADC_SAR2_ENCAL_GND_ADDR 0x7 +#define ADC_SAR2_ENCAL_GND_ADDR_MSB 7 +#define ADC_SAR2_ENCAL_GND_ADDR_LSB 7 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index e277bd8297..a9e6c7b67a 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -17,7 +17,7 @@ #pragma once /*-------------------------- COMMON CAPS ---------------------------------------*/ -// #define SOC_ADC_SUPPORTED 1 //TODO: IDF-6496 +#define SOC_ADC_SUPPORTED 1 #define SOC_ANA_CMPR_SUPPORTED 1 #define SOC_DEDICATED_GPIO_SUPPORTED 1 #define SOC_UART_SUPPORTED 1 @@ -108,19 +108,20 @@ /*-------------------------- ADC CAPS -------------------------------*/ /*!< SAR ADC Module*/ -// #define SOC_ADC_DIG_CTRL_SUPPORTED 1 //TODO: IDF-6496, TODO: IDF-6497 +#define SOC_ADC_RTC_CTRL_SUPPORTED 1 +#define SOC_ADC_DIG_CTRL_SUPPORTED 1 // #define SOC_ADC_DIG_IIR_FILTER_SUPPORTED 1 // #define SOC_ADC_MONITOR_SUPPORTED 1 #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) 1 //Digital controller supported ADC unit -// #define SOC_ADC_DMA_SUPPORTED 1 -#define SOC_ADC_PERIPH_NUM (1U) -#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (7) -#define SOC_ADC_MAX_CHANNEL_NUM (7) +#define SOC_ADC_DMA_SUPPORTED 1 +#define SOC_ADC_PERIPH_NUM (2) +#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 6: 8) +#define SOC_ADC_MAX_CHANNEL_NUM (8) #define SOC_ADC_ATTEN_NUM (4) /*!< Digital */ -#define SOC_ADC_DIGI_CONTROLLER_NUM (1U) -#define SOC_ADC_PATT_LEN_MAX (8) /*!< Two pattern tables, each contains 4 items. Each item takes 1 byte */ +#define SOC_ADC_DIGI_CONTROLLER_NUM (2) +#define SOC_ADC_PATT_LEN_MAX (16) /*!< Four pattern tables, each contains 4 items. Each item takes 1 byte */ #define SOC_ADC_DIGI_MAX_BITWIDTH (12) #define SOC_ADC_DIGI_MIN_BITWIDTH (12) #define SOC_ADC_DIGI_IIR_FILTER_NUM (2) @@ -138,6 +139,9 @@ /*!< Calibration */ #define SOC_ADC_CALIBRATION_V1_SUPPORTED (0) /*!< support HW offset calibration version 1*/ +/*!< ADC power control is shared by PWDET, TempSensor */ +#define SOC_ADC_SHARED_POWER 1 + // ESP32P4-TODO: Copy from esp32c6, need check /*-------------------------- APB BACKUP DMA CAPS -------------------------------*/ #define SOC_APB_BACKUP_DMA (0) diff --git a/components/soc/esp32p4/ld/esp32p4.peripherals.ld b/components/soc/esp32p4/ld/esp32p4.peripherals.ld index f937560b0a..0b293ba89e 100644 --- a/components/soc/esp32p4/ld/esp32p4.peripherals.ld +++ b/components/soc/esp32p4/ld/esp32p4.peripherals.ld @@ -82,6 +82,7 @@ PROVIDE ( LP_I2C = 0x50122000 ); PROVIDE ( LP_SPI = 0x50123000 ); PROVIDE ( LP_WDT = 0x50116000 ); PROVIDE ( LP_I2S = 0x50125000 ); +PROVIDE ( LP_ADC = 0x50127000 ); PROVIDE ( LP_TOUCH = 0x50128000 ); PROVIDE ( LP_GPIO = 0x5012A000 ); PROVIDE ( LP_PERI_PMS = 0x5012E000 ); diff --git a/components/soc/include/soc/rtc_io_periph.h b/components/soc/include/soc/rtc_io_periph.h index 19c4959a57..b8c23f0e06 100644 --- a/components/soc/include/soc/rtc_io_periph.h +++ b/components/soc/include/soc/rtc_io_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,11 +13,6 @@ #if SOC_RTCIO_PIN_COUNT > 0 #include "soc/rtc_io_channel.h" #endif - -#if SOC_ADC_RTC_CTRL_SUPPORTED -#include "soc/sens_struct.h" -#endif - #include "soc/io_mux_reg.h" #ifdef __cplusplus diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 59a9dadd8e..7397280ae0 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -10,11 +10,19 @@ examples/peripherals/adc/continuous_read: disable: - if: SOC_ADC_DMA_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: lack of runners, TODO IDF-9573 <<: *adc_dependencies examples/peripherals/adc/oneshot_read: disable: - if: SOC_ADC_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: lack of runner, TODO IDF-9573 <<: *adc_dependencies examples/peripherals/analog_comparator: diff --git a/examples/peripherals/adc/continuous_read/README.md b/examples/peripherals/adc/continuous_read/README.md index 94ecfd9889..e02022f3c1 100644 --- a/examples/peripherals/adc/continuous_read/README.md +++ b/examples/peripherals/adc/continuous_read/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # ADC DMA Example diff --git a/examples/peripherals/adc/oneshot_read/README.md b/examples/peripherals/adc/oneshot_read/README.md index cc872ff214..15404c47ee 100644 --- a/examples/peripherals/adc/oneshot_read/README.md +++ b/examples/peripherals/adc/oneshot_read/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # ADC Single Read Example diff --git a/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py b/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py index 9d5ad5058a..8bb86e3c00 100644 --- a/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py +++ b/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded.dut import Dut