From 904c94ba3a1e4d5e112d79db2346ccf9be7a585b Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Wed, 26 Nov 2025 14:03:50 +0800 Subject: [PATCH] feat(esp32s31): Add esp_hw_support component and header ci support --- .gitlab/ci/host-test.yml | 1 + components/esp_adc/esp32s31/include/.gitkeep | 0 .../esp32s31/include/adc_cali_schemes.h | 16 + .../esp32s31/include/hal/timer_ll.h | 27 + .../port/esp32s31/CMakeLists.txt | 12 + .../port/esp32s31/Kconfig.hw_support | 58 +++ .../esp_hw_support/port/esp32s31/Kconfig.xtal | 16 + .../esp_hw_support/port/esp32s31/chip_info.c | 18 + .../port/esp32s31/cpu_region_protect.c | 43 ++ .../port/esp32s31/esp_clk_tree.c | 99 ++++ .../port/esp32s31/esp_cpu_intr.c | 24 + .../port/esp32s31/include/soc/rtc.h | 473 ++++++++++++++++++ .../esp_hw_support/port/esp32s31/io_mux.c | 7 + .../esp_hw_support/port/esp32s31/rtc_clk.c | 339 +++++++++++++ .../esp_hw_support/port/esp32s31/rtc_time.c | 234 +++++++++ .../esp_hw_support/port/esp32s31/systimer.c | 24 + .../esp32s31/include/esp32s31/rom/cache.h | 2 - .../esp32s31/include/esp32s31/rom/gpio.h | 4 + .../hal/esp32s31/include/hal/cache_ll.h | 4 +- .../hal/esp32s31/include/hal/clk_tree_ll.h | 6 +- .../esp32s31/include/soc/Kconfig.soc_caps.in | 8 + .../soc/esp32s31/include/soc/soc_caps.h | 5 + .../soc/esp32s31/include/soc/soc_pins.h | 1 - .../include/soc/system_periph_retention.h | 16 +- .../soc/esp32s31/register/soc/ds_struct.h | 2 +- .../soc/esp32s31/register/soc/gmac_struct.h | 6 +- .../soc/esp32s31/register/soc/huk_struct.h | 6 +- .../soc/esp32s31/register/soc/keymng_struct.h | 8 +- .../soc/esp32s31/register/soc/sha_struct.h | 24 +- .../env_caps/esp32s31/Kconfig.env_caps | 15 + 30 files changed, 1459 insertions(+), 39 deletions(-) delete mode 100644 components/esp_adc/esp32s31/include/.gitkeep create mode 100644 components/esp_adc/esp32s31/include/adc_cali_schemes.h create mode 100644 components/esp_hal_timg/esp32s31/include/hal/timer_ll.h create mode 100644 components/esp_hw_support/port/esp32s31/Kconfig.hw_support create mode 100644 components/esp_hw_support/port/esp32s31/Kconfig.xtal create mode 100644 components/esp_hw_support/port/esp32s31/chip_info.c create mode 100644 components/esp_hw_support/port/esp32s31/include/soc/rtc.h create mode 100644 components/esp_hw_support/port/esp32s31/rtc_clk.c create mode 100644 components/esp_hw_support/port/esp32s31/rtc_time.c create mode 100644 components/esp_hw_support/port/esp32s31/systimer.c create mode 100644 examples/common_components/env_caps/esp32s31/Kconfig.env_caps diff --git a/.gitlab/ci/host-test.yml b/.gitlab/ci/host-test.yml index e328c7d659..453e167784 100644 --- a/.gitlab/ci/host-test.yml +++ b/.gitlab/ci/host-test.yml @@ -37,6 +37,7 @@ check_public_headers: - IDF_TARGET=esp32c61 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf- - IDF_TARGET=esp32h21 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf- - IDF_TARGET=esp32h4 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf- + - IDF_TARGET=esp32s31 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf- test_nvs_coverage: extends: diff --git a/components/esp_adc/esp32s31/include/.gitkeep b/components/esp_adc/esp32s31/include/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/esp_adc/esp32s31/include/adc_cali_schemes.h b/components/esp_adc/esp32s31/include/adc_cali_schemes.h new file mode 100644 index 0000000000..66fb23192d --- /dev/null +++ b/components/esp_adc/esp32s31/include/adc_cali_schemes.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/** + * @file adc_cali_schemes.h + * + * @brief Supported calibration schemes + */ + +//TODO: [ESP32H31] +// #define ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED 1 diff --git a/components/esp_hal_timg/esp32s31/include/hal/timer_ll.h b/components/esp_hal_timg/esp32s31/include/hal/timer_ll.h new file mode 100644 index 0000000000..cc69b7df3e --- /dev/null +++ b/components/esp_hal_timg/esp32s31/include/hal/timer_ll.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "hal/timer_types.h" +#include "hal/timg_ll.h" +#include "soc/timer_group_struct.h" + +#define TIMER_LL_GPTIMERS_TOTAL (TIMG_LL_INST_NUM * TIMG_LL_GPTIMERS_PER_INST) + +#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1)) + +// Bit width of GPTIMER counter +#define TIMER_LL_COUNTER_BIT_WIDTH 54 + +// Get alarm interrupt mask with the given timer ID +#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) + +// Support RC_FAST as function clock +#define TIMER_LL_FUNC_CLOCK_SUPPORT_RC_FAST 1 diff --git a/components/esp_hw_support/port/esp32s31/CMakeLists.txt b/components/esp_hw_support/port/esp32s31/CMakeLists.txt index e69de29bb2..8858f89a59 100644 --- a/components/esp_hw_support/port/esp32s31/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32s31/CMakeLists.txt @@ -0,0 +1,12 @@ +target_include_directories(${COMPONENT_LIB} PUBLIC .) + +set(srcs + "rtc_clk.c" + "rtc_time.c" + "chip_info.c" + ) + +add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") + +target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") +target_include_directories(${COMPONENT_LIB} PUBLIC . include private_include) diff --git a/components/esp_hw_support/port/esp32s31/Kconfig.hw_support b/components/esp_hw_support/port/esp32s31/Kconfig.hw_support new file mode 100644 index 0000000000..6cb0de995c --- /dev/null +++ b/components/esp_hw_support/port/esp32s31/Kconfig.hw_support @@ -0,0 +1,58 @@ +choice ESP32S31_REV_MIN + prompt "Minimum Supported ESP32-S31 Revision" + default ESP32S31_REV_MIN_0 + help + Required minimum chip revision. ESP-IDF will check for it and + reject to boot if the chip revision fails the check. + This ensures the chip used will have some modifications (features, or bugfixes). + + The complied binary will only support chips above this revision, + this will also help to reduce binary size. + + config ESP32S31_REV_MIN_0 + bool "Rev v0.0" +endchoice + +config ESP32S31_REV_MIN_FULL + int + default 0 if ESP32S31_REV_MIN_0 + +config ESP_REV_MIN_FULL + int + default ESP32S31_REV_MIN_FULL + + # + # MAX Revision + # + + comment "Maximum Supported ESP32-S31 Revision (Rev v1.99)" + # Maximum revision that IDF supports. + # It can not be changed by user. + # Only Espressif can change it when a new version will be supported in IDF. + # Supports all chips starting from ESP32S31_REV_MIN_FULL to ESP32S31_REV_MAX_FULL + +config ESP32S31_REV_MAX_FULL + int + default 99 + # keep in sync the "Maximum Supported Revision" description with this value + +config ESP_REV_MAX_FULL + int + default ESP32S31_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-S31 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32-S31 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32s31/Kconfig.xtal b/components/esp_hw_support/port/esp32s31/Kconfig.xtal new file mode 100644 index 0000000000..64e10afc9a --- /dev/null +++ b/components/esp_hw_support/port/esp32s31/Kconfig.xtal @@ -0,0 +1,16 @@ +choice XTAL_FREQ + prompt "Main XTAL frequency" + default XTAL_FREQ_40 + help + This option selects the operating frequency of the XTAL (crystal) clock used to drive the ESP target. + The selected value MUST reflect the frequency of the given hardware. + + config XTAL_FREQ_40 + bool "40 MHz" +endchoice + +# soc_xtal_freq_t enum in soc/clk_tree_defs.h lists the XTAL frequencies can be supported +# SOC_XTAL_SUPPORT_XXX in soc_caps.h lists the XTAL frequencies already supported +config XTAL_FREQ + int + default 40 if XTAL_FREQ_40 diff --git a/components/esp_hw_support/port/esp32s31/chip_info.c b/components/esp_hw_support/port/esp32s31/chip_info.c new file mode 100644 index 0000000000..ce86fc3f5d --- /dev/null +++ b/components/esp_hw_support/port/esp32s31/chip_info.c @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_chip_info.h" +#include "hal/efuse_hal.h" + +void esp_chip_info(esp_chip_info_t *out_info) +{ + memset(out_info, 0, sizeof(*out_info)); + out_info->model = CHIP_ESP32S31; + out_info->revision = efuse_hal_chip_revision(); + out_info->cores = 2; + out_info->features = CHIP_FEATURE_WIFI_BGN | CHIP_FEATURE_BLE | CHIP_FEATURE_IEEE802154 | CHIP_FEATURE_EMB_PSRAM; +} diff --git a/components/esp_hw_support/port/esp32s31/cpu_region_protect.c b/components/esp_hw_support/port/esp32s31/cpu_region_protect.c index e69de29bb2..eabf5ffb0b 100644 --- a/components/esp_hw_support/port/esp32s31/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32s31/cpu_region_protect.c @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "soc/soc.h" +#include "esp_cpu.h" +#include "esp_fault.h" +#include "hal/cache_ll.h" +#include "riscv/csr.h" +#if CONFIG_SPIRAM +#include "esp_private/esp_psram_extram.h" +#endif /* CONFIG_SPIRAM */ + +/* TODO: [ESP32S31] IDF-14655 */ + +#ifdef BOOTLOADER_BUILD +// Without L bit set +#define CONDITIONAL_NONE 0x0 +#define CONDITIONAL_R PMP_R +#define CONDITIONAL_RX PMP_R | PMP_X +#define CONDITIONAL_RW PMP_R | PMP_W +#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X +#else +// With L bit set +#define CONDITIONAL_NONE NONE +#define CONDITIONAL_R R +#define CONDITIONAL_RX RX +#define CONDITIONAL_RW RW +#define CONDITIONAL_RWX RWX +#endif + +#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1)) +#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1)) +#define ALIGN_UP(addr, align) ((addr) & ~((align) - 1)) + +void esp_cpu_configure_region_protection(void) +{ + /* TODO: [ESP32S31] IDF-14655 */ +} diff --git a/components/esp_hw_support/port/esp32s31/esp_clk_tree.c b/components/esp_hw_support/port/esp32s31/esp_clk_tree.c index e69de29bb2..4d2ba579a7 100644 --- a/components/esp_hw_support/port/esp32s31/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32s31/esp_clk_tree.c @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_clk_tree.h" +#include "esp_err.h" +#include "esp_check.h" +#include "soc/rtc.h" +#include "hal/clk_tree_hal.h" +#include "hal/clk_tree_ll.h" +#include "esp_private/esp_clk_tree_common.h" +#include "esp_private/periph_ctrl.h" + +static const char *TAG = "esp_clk_tree"; + +/* TODO: [ESP32S31] IDF-14733 */ + +void esp_clk_tree_initialize(void) +{ + /* TODO: [ESP32S31] IDF-14733 */ +} + +esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision, + uint32_t *freq_value) +{ + ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src"); + ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision"); + ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer"); + + uint32_t clk_src_freq = 0; + switch (clk_src) { + case SOC_MOD_CLK_CPU: + clk_src_freq = clk_hal_cpu_get_freq_hz(); + break; + case SOC_MOD_CLK_XTAL: + clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ; + break; + case SOC_MOD_CLK_PLL_F20M: + clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ / clk_ll_pll_f20m_get_divider() * MHZ; + break; + case SOC_MOD_CLK_PLL_F80M: + clk_src_freq = CLK_LL_PLL_80M_FREQ_MHZ * MHZ; + break; + case SOC_MOD_CLK_PLL_F160M: + clk_src_freq = CLK_LL_PLL_160M_FREQ_MHZ * MHZ; + break; + case SOC_MOD_CLK_PLL_F240M: + clk_src_freq = CLK_LL_PLL_240M_FREQ_MHZ * MHZ; + break; + case SOC_MOD_CLK_CPLL: + clk_src_freq = clk_ll_cpll_get_freq_mhz(clk_hal_xtal_get_freq_mhz()) * MHZ; + break; + case SOC_MOD_CLK_SPLL: + clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ * MHZ; + break; + case SOC_MOD_CLK_MPLL: + clk_src_freq = clk_ll_mpll_get_freq_mhz(clk_hal_xtal_get_freq_mhz()) * MHZ; + break; + case SOC_MOD_CLK_SDIO_PLL: + clk_src_freq = CLK_LL_PLL_SDIO_FREQ_MHZ * MHZ; + break; + case SOC_MOD_CLK_RTC_SLOW: + clk_src_freq = esp_clk_tree_lp_slow_get_freq_hz(precision); + break; + case SOC_MOD_CLK_RTC_FAST: + case SOC_MOD_CLK_LP_DYN_FAST: // This clock can be derived from RTC_SLOW_CLK or RTC_FAST_CLK depending on the chip’s power mode. + // However, this function is only supposed to run under active mode, so its frequency is the same as RTC_FAST_CLK. + clk_src_freq = esp_clk_tree_lp_fast_get_freq_hz(precision); + break; + case SOC_MOD_CLK_RC_FAST: + clk_src_freq = esp_clk_tree_rc_fast_get_freq_hz(precision); + break; + case SOC_MOD_CLK_XTAL32K: + clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision); + break; + case SOC_MOD_CLK_XTAL_D2: + clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1; + break; + case SOC_MOD_CLK_LP_PLL: + clk_src_freq = clk_ll_lp_pll_get_freq_mhz() * MHZ; + break; + default: + break; + } + + ESP_RETURN_ON_FALSE(clk_src_freq, ESP_FAIL, TAG, + "freq shouldn't be 0, calibration failed"); + *freq_value = clk_src_freq; + return ESP_OK; +} + +esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) +{ + /* TODO: [ESP32S31] IDF-14733 */ + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32s31/esp_cpu_intr.c b/components/esp_hw_support/port/esp32s31/esp_cpu_intr.c index e69de29bb2..f8fc9177ce 100644 --- a/components/esp_hw_support/port/esp32s31/esp_cpu_intr.c +++ b/components/esp_hw_support/port/esp32s31/esp_cpu_intr.c @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_cpu.h" +#include "esp_riscv_intr.h" + +// TODO: [ESP32S31] IDF-14665 + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + /* On targets that uses CLIC as the interrupt controller, the first 16 lines (0..15) are reserved for software + * interrupts, all the other lines starting from 16 and above can be used by external peripheral. + * + * Only interrupt line 6 is reserved at the moment since it is used for disabling interrupts in the + * interrupt allocator (INT_MUX_DISABLED_INTNO) */ + const uint32_t rsvd_mask = BIT(6); + + intr_desc_ret->priority = 1; + intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; + intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); +} diff --git a/components/esp_hw_support/port/esp32s31/include/soc/rtc.h b/components/esp_hw_support/port/esp32s31/include/soc/rtc.h new file mode 100644 index 0000000000..ec0c06c1ac --- /dev/null +++ b/components/esp_hw_support/port/esp32s31/include/soc/rtc.h @@ -0,0 +1,473 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include +#include "soc/soc.h" +#include "soc/clk_tree_defs.h" +#include "hal/hal_utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// TODO: [ESP32S31] IDF-14678 + +/************************************************************************************/ +/***************** THIS FILE IS CONSIDERED AS A PRIVATE HEADER FILE *****************/ +/*** IT IS NOT RECOMMENDED TO USE THE APIS IN THIS FILE DIRECTLY IN APPLICATIONS ****/ +/************************************************************************************/ + +/** + * @file rtc.h + * @brief Low-level RTC power, clock functions. + * + * Functions in this file facilitate configuration of ESP32S31's RTC_CNTL peripheral. + * RTC_CNTL peripheral handles many functions: + * - enables/disables clocks and power to various parts of the chip; this is + * done using direct register access (forcing power up or power down) or by + * allowing state machines to control power and clocks automatically + * - handles sleep and wakeup functions + * - maintains a 48-bit counter which can be used for timekeeping + * + * These functions are not thread safe, and should not be viewed as high level + * APIs. For example, while this file provides a function which can switch + * CPU frequency, this function is on its own is not sufficient to implement + * frequency switching in ESP-IDF context: some coordination with RTOS, + * peripheral drivers, and WiFi/BT stacks is also required. + * + * These functions will normally not be used in applications directly. + * ESP-IDF provides, or will provide, drivers and other facilities to use + * RTC subsystem functionality. + * + * The functions are loosely split into the following groups: + * - rtc_clk: clock switching, calibration + * - rtc_time: reading RTC counter, conversion between counter values and time + */ + +#define MHZ (1000000) + +#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100 +#define RTC_CNTL_SCK_DCAP_DEFAULT 128 +#define RTC_CNTL_RC32K_DFREQ_DEFAULT 700 + +/* +The follow value is used to get a reasonable rtc voltage dbias value according to digital dbias & some other value +storing in efuse (based on ATE 5k ECO3 chips) +*/ +#define K_RTC_MID_MUL10000 215 +#define K_DIG_MID_MUL10000 213 +#define V_RTC_MID_MUL10000 10800 +#define V_DIG_MID_MUL10000 10860 + +/** + * @brief CPU clock configuration structure + */ +typedef struct rtc_cpu_freq_config_s { + soc_cpu_clk_src_t source; //!< The clock from which CPU clock is derived + uint32_t source_freq_mhz; //!< Source clock frequency + hal_utils_clk_div_t div; //!< Divider, freq_mhz = SOC_ROOT_CLK freq_mhz / div + uint32_t freq_mhz; //!< CPU clock frequency +} rtc_cpu_freq_config_t; + +#define RTC_CLK_CAL_FRACT 19 //!< Number of fractional bits in values returned by rtc_clk_cal + +#define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO +#define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO + +/** + * @brief Clock source to be calibrated using rtc_clk_cal function + * + * @note On ESP32S31, the enum values somehow reflects the register field values of HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_SRC_SEL. + */ +typedef enum { + RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK + RTC_CAL_MPLL = 0, //!< 500MHz MSPI_PLL_CLK + RTC_CAL_SPLL = 1, //!< 480MHz SYS_PLL_CLK + RTC_CAL_CPLL = 2, //!< 400MHz CPU_PLL_CLK + RTC_CAL_APLL = 3, //!< AUDIO_PLL_CLK + RTC_CAL_SDIO_PLL0 = 4, //!< SDIO_PLL0_CLK + RTC_CAL_SDIO_PLL1 = 5, //!< SDIO_PLL1_CLK + RTC_CAL_SDIO_PLL2 = 6, //!< SDIO_PLL2_CLK + RTC_CAL_RC_FAST = 7, //!< Internal 20MHz RC oscillator + RTC_CAL_RC_SLOW = 8, //!< Internal 150kHz RC oscillator + RTC_CAL_RC32K = 9, //!< Internal 32kHz RC oscillator, as one type of 32k clock + RTC_CAL_32K_XTAL = 10, //!< External 32kHz XTAL, as one type of 32k clock + RTC_CAL_LP_PLL = 11, //!< 8MHz LP_PLL_CLK + RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate +} rtc_cal_sel_t; + +/** + * Initialization parameters for rtc_clk_init + */ +typedef struct { + soc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency + uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz + soc_rtc_fast_clk_src_t fast_clk_src : 2; //!< RTC_FAST_CLK clock source to choose + soc_rtc_slow_clk_src_t slow_clk_src : 3; //!< RTC_SLOW_CLK clock source to choose + uint32_t clk_rtc_clk_div : 8; + uint32_t clk_8m_clk_div : 3; //!< RC_FAST clock divider (division is by clk_8m_div+1, i.e. 0 means ~20MHz frequency) + uint32_t slow_clk_dcap : 8; //!< RC_SLOW clock adjustment parameter (higher value leads to lower frequency) + uint32_t clk_8m_dfreq : 8; //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency) + uint32_t rc32k_dfreq : 10; //!< Internal RC32K clock adjustment parameter (higher value leads to higher frequency) +} rtc_clk_config_t; + +/** + * Default initializer for rtc_clk_config_t + */ +#define RTC_CLK_CONFIG_DEFAULT() { \ + .xtal_freq = CONFIG_XTAL_FREQ, \ + .cpu_freq_mhz = 90, \ + .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ + .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ + .clk_rtc_clk_div = 0, \ + .clk_8m_clk_div = 0, \ + .slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \ + .clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \ + .rc32k_dfreq = RTC_CNTL_RC32K_DFREQ_DEFAULT, \ +} + +/** + * Initialize clocks and set CPU frequency + * + * @param cfg clock configuration as rtc_clk_config_t + */ +void rtc_clk_init(rtc_clk_config_t cfg); + +/** + * @brief Get main XTAL frequency + * + * This is the value stored in RTC register RTC_XTAL_FREQ_REG by the bootloader. As passed to + * rtc_clk_init function + * + * @return XTAL frequency, one of soc_xtal_freq_t + */ +soc_xtal_freq_t rtc_clk_xtal_freq_get(void); + +/** + * @brief Update XTAL frequency + * + * Updates the XTAL value stored in RTC_XTAL_FREQ_REG. Usually this value is ignored + * after startup. + * + * @param xtal_freq New frequency value + */ +void rtc_clk_xtal_freq_update(soc_xtal_freq_t xtal_freq); + +/** + * @brief Enable or disable 32 kHz XTAL oscillator + * @param en true to enable, false to disable + */ +void rtc_clk_32k_enable(bool en); + +/** + * @brief Get the state of 32k XTAL oscillator + * @return true if 32k XTAL oscillator has been enabled + */ +bool rtc_clk_32k_enabled(void); + +/** + * @brief Enable 32k oscillator, configuring it for fast startup time. + * Note: to achieve higher frequency stability, rtc_clk_32k_enable function + * must be called one the 32k XTAL oscillator has started up. This function + * will initially disable the 32k XTAL oscillator, so it should not be called + * when the system is using 32k XTAL as RTC_SLOW_CLK. + * + * @param cycle Number of 32kHz cycles to bootstrap external crystal. + * If 0, no square wave will be used to bootstrap crystal oscillation. + */ +void rtc_clk_32k_bootstrap(uint32_t cycle); + +/** + * @brief Enable or disable 32 kHz internal rc oscillator + * @param en true to enable, false to disable + */ +void rtc_clk_rc32k_enable(bool enable); + +/** + * @brief Enable or disable 8 MHz internal oscillator + * + * @param clk_8m_en true to enable 8MHz generator + */ +void rtc_clk_8m_enable(bool clk_8m_en); + +/** + * @brief Get the state of 8 MHz internal oscillator + * @return true if the oscillator is enabled + */ +bool rtc_clk_8m_enabled(void); + +/** + * @brief Enable or disable LP_PLL_CLK + * Note that to be able to use LP_PLL clock, besides turn on the power for LP_PLL, also needs to turn on the power for + * the LP_PLL clock source (either XTAL32K or RC32K). + * @param enable true to enable, false to disable + */ +void rtc_clk_lp_pll_enable(bool enable); + +/** + * @brief Select clock source for LP_PLL_CLK + * @param clk_src clock source (one of soc_lp_pll_clk_src_t values) + */ +void rtc_clk_lp_pll_src_set(soc_lp_pll_clk_src_t clk_src); + +/** + * @brief Select source for RTC_SLOW_CLK + * @param clk_src clock source (one of soc_rtc_slow_clk_src_t values) + */ +void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src); + +/** + * @brief Get the RTC_SLOW_CLK source + * @return currently selected clock source (one of soc_rtc_slow_clk_src_t values) + */ +soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void); + +/** + * @brief Get the approximate frequency of RTC_SLOW_CLK, in Hz + * + * - if SOC_RTC_SLOW_CLK_SRC_RC_SLOW is selected, returns 136000 + * - if SOC_RTC_SLOW_CLK_SRC_XTAL32K is selected, returns 32768 + * - if SOC_RTC_SLOW_CLK_SRC_RC32K is selected, returns 32768 + * + * rtc_clk_cal function can be used to get more precise value by comparing + * RTC_SLOW_CLK frequency to the frequency of main XTAL. + * + * @return RTC_SLOW_CLK frequency, in Hz + */ +uint32_t rtc_clk_slow_freq_get_hz(void); + +/** + * @brief Select source for RTC_FAST_CLK + * @param clk_src clock source (one of soc_rtc_fast_clk_src_t values) + */ +void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src); + +/** + * @brief Get the RTC_FAST_CLK source + * @return currently selected clock source (one of soc_rtc_fast_clk_src_t values) + */ +soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void); + +/** + * @brief Get CPU frequency config for a given frequency + * @param freq_mhz Frequency in MHz + * @param[out] out_config Output, CPU frequency configuration structure + * @return true if frequency can be obtained, false otherwise + */ +bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config); + +/** + * @brief Switch CPU frequency + * + * This function sets CPU frequency according to the given configuration + * structure. It enables PLLs, if necessary. + * + * @note This function in not intended to be called by applications in FreeRTOS + * environment. This is because it does not adjust various timers based on the + * new CPU frequency. + * + * @param config CPU frequency configuration structure + */ +void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config); + +/** + * @brief Switch CPU frequency (optimized for speed) + * + * This function is a faster equivalent of rtc_clk_cpu_freq_set_config. + * It works faster because it does not disable PLLs when switching from PLL to + * XTAL and does not enabled them when switching back. If PLL is not already + * enabled when this function is called to switch from XTAL to PLL frequency, + * or the PLL which is enabled is the wrong one, this function will fall back + * to calling rtc_clk_cpu_freq_set_config. + * + * Unlike rtc_clk_cpu_freq_set_config, this function relies on static data, + * so it is less safe to use it e.g. from a panic handler (when memory might + * be corrupted). + * + * @note This function in not intended to be called by applications in FreeRTOS + * environment. This is because it does not adjust various timers based on the + * new CPU frequency. + * + * @param config CPU frequency configuration structure + */ +void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config); + +/** + * @brief Get the currently used CPU frequency configuration + * @param[out] out_config Output, CPU frequency configuration structure + */ +void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config); + +/** + * @brief Switch CPU clock source to XTAL + * + * Short form for filling in rtc_cpu_freq_config_t structure and calling + * rtc_clk_cpu_freq_set_config when a switch to XTAL is needed. + * Assumes that XTAL frequency has been determined — don't call in startup code. + * + * @note On ESP32S31, this function always disables CPLL after switching the CPU clock source to XTAL, + * since there is no peripheral relies on CPLL clock (except Flash/PSRAM if their clock source selects CPLL). + */ +void rtc_clk_cpu_freq_set_xtal(void); + +/** + * @brief Get the current APB frequency. + * @return The calculated APB frequency value, in Hz. + */ +uint32_t rtc_clk_apb_freq_get(void); + +/** + * @brief Clock calibration function used by rtc_clk_cal + * + * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. + * This feature counts the number of XTAL clock cycles within a given number of + * RTC_SLOW_CLK cycles. + * + * Slow clock calibration feature has two modes of operation: one-off and cycling. + * In cycling mode (which is enabled by default on SoC reset), counting of XTAL + * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled + * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed + * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is + * enabled using TIMG_RTC_CALI_START bit. + * + * @param cal_clk which clock to calibrate + * @param slowclk_cycles number of slow clock cycles to count + * @return number of XTAL clock cycles within the given number of slow clock cycles + */ +uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles); + +/** + * @brief Measure RTC slow clock's period, based on main XTAL frequency + * + * This function will time out and return 0 if the time for the given number + * of cycles to be counted exceeds the expected time twice. This may happen if + * 32k XTAL is being calibrated, but the oscillator has not started up (due to + * incorrect loading capacitance, board design issue, or lack of 32 XTAL on board). + * + * @note When 32k CLK is being calibrated, this function will check the accuracy + * of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if + * the check fails, then consider this an invalid 32k clock and return 0. This + * check can filter some jamming signal. + * + * @param cal_clk clock to be measured + * @param slow_clk_cycles number of slow clock cycles to average + * @return average slow clock period in microseconds, Q13.19 fixed point format, + * or 0 if calibration has timed out + */ +uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles); + +/** + * @brief Convert time interval from microseconds to RTC_SLOW_CLK cycles + * @param time_in_us Time interval in microseconds + * @param slow_clk_period Period of slow clock in microseconds, Q13.19 + * fixed point format (as returned by rtc_slowck_cali). + * @return number of slow clock cycles + */ +uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period); + +/** + * @brief Convert time interval from RTC_SLOW_CLK to microseconds + * @param time_in_us Time interval in RTC_SLOW_CLK cycles + * @param slow_clk_period Period of slow clock in microseconds, Q13.19 + * fixed point format (as returned by rtc_slowck_cali). + * @return time interval in microseconds + */ +uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period); + +/** + * @brief Get current value of RTC counter + * + * RTC has a 48-bit counter which is incremented by 2 every 2 RTC_SLOW_CLK + * cycles. Counter value is not writable by software. The value is not adjusted + * when switching to a different RTC_SLOW_CLK source. + * + * Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute + * + * @return current value of RTC counter + */ +uint64_t rtc_time_get(void); + +/** + * @brief Enable the rtc digital 8M clock + * + * This function is used to enable the digital rtc 8M clock to support peripherals. + * For enabling the analog 8M clock, using `rtc_clk_8M_enable` function above. + */ +void rtc_dig_clk8m_enable(void); + +/** + * @brief Disable the rtc digital 8M clock + * + * This function is used to disable the digital rtc 8M clock, which is only used to support peripherals. + */ +void rtc_dig_clk8m_disable(void); + +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + +/** + * @brief Calculate the real clock value after the clock calibration + * + * @param cal_val Average slow clock period in microseconds, fixed point value as returned from `rtc_clk_cal` + * @return Frequency of the clock in Hz + */ +uint32_t rtc_clk_freq_cal(uint32_t cal_val); + +/** + * @brief Calculate the slow clock period value by slow clock frequency + * + * @param freq_hz Frequency of the slow clock in Hz + * @return Fixed point value of slow clock period in microseconds + */ +uint32_t rtc_clk_freq_to_period(uint32_t freq_hz); + +/** + * @brief Enable or disable APLL + * + * Output frequency is given by the formula: + * apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2) + * + * The dividend in this expression should be in the range of 240 - 600 MHz. + * + * In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0. + * + * @param enable true to enable, false to disable + */ +void rtc_clk_apll_enable(bool enable); + +/** + * @brief Calculate APLL clock coeffifcients + * + * @param freq expected APLL frequency + * @param o_div frequency divider, 0..31 + * @param sdm0 frequency adjustment parameter, 0..255 + * @param sdm1 frequency adjustment parameter, 0..255 + * @param sdm2 frequency adjustment parameter, 0..63 + * + * @return + * - 0 Failed + * - else Success + */ +uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm0, uint32_t *_sdm1, uint32_t *_sdm2); + +/** + * @brief Set APLL clock coeffifcients + * + * @param o_div frequency divider, 0..31 + * @param sdm0 frequency adjustment parameter, 0..255 + * @param sdm1 frequency adjustment parameter, 0..255 + * @param sdm2 frequency adjustment parameter, 0..63 + */ +void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/port/esp32s31/io_mux.c b/components/esp_hw_support/port/esp32s31/io_mux.c index e69de29bb2..a7c43e70b4 100644 --- a/components/esp_hw_support/port/esp32s31/io_mux.c +++ b/components/esp_hw_support/port/esp32s31/io_mux.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// TODO: [ESP32S31] IDF-14780 diff --git a/components/esp_hw_support/port/esp32s31/rtc_clk.c b/components/esp_hw_support/port/esp32s31/rtc_clk.c new file mode 100644 index 0000000000..ce23b1a963 --- /dev/null +++ b/components/esp_hw_support/port/esp32s31/rtc_clk.c @@ -0,0 +1,339 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp32s31/rom/rtc.h" +#include "soc/rtc.h" +#include "esp_private/rtc_clk.h" +#include "esp_attr.h" +#include "esp_hw_log.h" +#include "esp_rom_sys.h" +#include "hal/clk_tree_ll.h" +#include "hal/regi2c_ctrl_ll.h" +#include "hal/gpio_ll.h" +#include "soc/io_mux_reg.h" +#include "esp_private/sleep_event.h" +#include "esp_private/regi2c_ctrl.h" + +static const char *TAG = "rtc_clk"; + +// TODO: [ESP32S31] IDF-14678 + +// CPLL frequency option, in 360/400MHz. Zero if CPLL is not enabled. +static int s_cur_cpll_freq = 0; + +// MPLL frequency option, 400MHz. Zero if MPLL is not enabled. +static TCM_DRAM_ATTR uint32_t s_cur_mpll_freq = 0; + +void rtc_clk_32k_enable(bool enable) +{ + if (enable) { + clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL); + } else { + clk_ll_xtal32k_disable(); + } +} + +void rtc_clk_32k_bootstrap(uint32_t cycle) +{ + /* No special bootstrapping needed for ESP32-P4, 'cycle' argument is to keep the signature + * same as for the ESP32. Just enable the XTAL here. + */ + (void)cycle; + rtc_clk_32k_enable(true); +} + +bool rtc_clk_32k_enabled(void) +{ + return clk_ll_xtal32k_is_enabled(); +} + +void rtc_clk_rc32k_enable(bool enable) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +void rtc_clk_8m_enable(bool clk_8m_en) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +bool rtc_clk_8m_enabled(void) +{ + return clk_ll_rc_fast_is_enabled(); +} + +void rtc_clk_lp_pll_enable(bool enable) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +void rtc_clk_lp_pll_src_set(soc_lp_pll_clk_src_t clk_src) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void) +{ + return clk_ll_rtc_slow_get_src(); +} + +uint32_t rtc_clk_slow_freq_get_hz(void) +{ + // TODO: ["ESP32S31"] IDF-14678 + switch (rtc_clk_slow_src_get()) { + case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX; + default: return 0; + } +} + +void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void) +{ + return clk_ll_rtc_fast_get_src(); +} + +static void rtc_clk_cpll_disable(void) +{ + clk_ll_cpll_disable(); + s_cur_cpll_freq = 0; +} + +/** + * Switch to use XTAL as the CPU clock source. + * Must satisfy: cpu_freq = XTAL_FREQ / div. + * Does not disable the PLL. + * + * If to_default is set, then will configure CPU - MEM - SYS - APB frequencies back to power-on reset configuration (40 - 20 - 20 - 10) + * If to_default is not set, then will configure to 40 - 40 - 40 - 40 + */ +static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div, bool to_default) +{ + // TODO: ["ESP32S31"] IDF-14678 + // let f_cpu = f_mem = f_sys = f_apb + uint32_t mem_divider = 1; + uint32_t sys_divider = 1; + uint32_t apb_divider = 1; + if (to_default) { + // f_cpu = 2 * f_mem = 2 * f_sys = 4 * f_apb + mem_divider = 2; + apb_divider = 2; + } + // Update bit does not control CPU clock sel mux. Therefore, there will be a middle state during the switch (CPU falls) + // Since before the switch, the clock source is CPLL, there is divider value constraints. + // Setting the new dividers first is unguaranteed (hardware could automatically modify the real dividers) + // Therefore, we will switch cpu clock source first, and then set the desired dividers. + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL); + clk_ll_cpu_set_divider(div, 0, 0); + clk_ll_mem_set_divider(mem_divider); + clk_ll_sys_set_divider(sys_divider); + clk_ll_apb_set_divider(apb_divider); + clk_ll_bus_update(); + esp_rom_set_cpu_ticks_per_us(cpu_freq); +} + +bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config) +{ + // TODO: ["ESP32S31"] IDF-14678 + return true; +} + +__attribute__((weak)) void rtc_clk_set_cpu_switch_to_pll(int event_id) +{ +} + +void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +static uint32_t rtc_clk_hp_root_get_freq_mhz(soc_cpu_clk_src_t clk_src) +{ + uint32_t source_freq_mhz = 0; + // TODO: ["ESP32S31"] IDF-14678 + return source_freq_mhz; +} + +void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +void rtc_clk_cpu_freq_set_xtal(void) +{ + int freq_mhz = (int)rtc_clk_xtal_freq_get(); + + rtc_clk_cpu_freq_to_xtal(freq_mhz, 1, false); + rtc_clk_cpll_disable(); +} + +void rtc_clk_cpu_set_to_default_config(void) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +void rtc_clk_cpu_freq_set_xtal_for_sleep(void) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +soc_xtal_freq_t rtc_clk_xtal_freq_get(void) +{ + uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz(); + if (xtal_freq_mhz == 0) { + ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz"); + return SOC_XTAL_FREQ_40M; + } + return (soc_xtal_freq_t)xtal_freq_mhz; +} + +void rtc_clk_xtal_freq_update(soc_xtal_freq_t xtal_freq) +{ + clk_ll_xtal_store_freq_mhz(xtal_freq); +} + +uint32_t rtc_clk_apb_freq_get(void) +{ + soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); + uint32_t source_freq_mhz = rtc_clk_hp_root_get_freq_mhz(source); + uint32_t integer, numerator, denominator; + clk_ll_cpu_get_divider(&integer, &numerator, &denominator); + if (denominator == 0) { + denominator = 1; + numerator = 0; + } + uint32_t cpu_freq_hz = source_freq_mhz * MHZ * denominator / (integer * denominator + numerator); + uint32_t mem_freq_hz = cpu_freq_hz / clk_ll_mem_get_divider(); + uint32_t sys_freq_hz = mem_freq_hz / clk_ll_sys_get_divider(); + return sys_freq_hz / clk_ll_apb_get_divider(); +} + +void rtc_clk_apll_enable(bool enable) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm0, uint32_t *_sdm1, uint32_t *_sdm2) +{ + uint32_t rtc_xtal_freq = (uint32_t)rtc_clk_xtal_freq_get(); + if (rtc_xtal_freq == 0) { + // xtal_freq has not set yet + ESP_HW_LOGE(TAG, "Get xtal clock frequency failed, it has not been set yet"); + abort(); + } + /* Reference formula: apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) / ((o_div + 2) * 2) + * ---------------------------------------------- ----------------- + * 350 MHz <= Numerator <= 500 MHz Denominator + */ + int o_div = 0; // range: 0~31 + int sdm0 = 0; // range: 0~255 + int sdm1 = 0; // range: 0~255 + int sdm2 = 0; // range: 0~63 + /* Firstly try to satisfy the condition that the operation frequency of numerator should be greater than 350 MHz, + * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz, '+1' in the following code is to get the ceil value. + * With this condition, as we know the 'o_div' can't be greater than 31, then we can calculate the APLL minimum support frequency is + * 350 MHz / ((31 + 2) * 2) = 5303031 Hz (for ceil) */ + o_div = (int)(CLK_LL_APLL_MULTIPLIER_MIN_HZ / (float)(freq * 2) + 1) - 2; + if (o_div > 31) { + ESP_HW_LOGE(TAG, "Expected frequency is too small"); + return 0; + } + if (o_div < 0) { + /* Try to satisfy the condition that the operation frequency of numerator should be smaller than 500 MHz, + * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz, we need to get the floor value in the following code. + * With this condition, as we know the 'o_div' can't be smaller than 0, then we can calculate the APLL maximum support frequency is + * 500 MHz / ((0 + 2) * 2) = 125000000 Hz */ + o_div = (int)(CLK_LL_APLL_MULTIPLIER_MAX_HZ / (float)(freq * 2)) - 2; + if (o_div < 0) { + ESP_HW_LOGE(TAG, "Expected frequency is too big"); + return 0; + } + } + // sdm2 = (int)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4 + sdm2 = (int)(((o_div + 2) * 2 * freq) / (rtc_xtal_freq * MHZ)) - 4; + // numrator = (((o_div + 2) * 2) * apll_freq / xtal_freq) - 4 - sdm2 + float numrator = (((o_div + 2) * 2 * freq) / ((float)rtc_xtal_freq * MHZ)) - 4 - sdm2; + // If numrator is bigger than 255/256 + 255/65536 + (1/65536)/2 = 1 - (1 / 65536)/2, carry bit to sdm2 + if (numrator > 1.0 - (1.0 / 65536.0) / 2.0) { + sdm2++; + } + // If numrator is smaller than (1/65536)/2, keep sdm0 = sdm1 = 0, otherwise calculate sdm0 and sdm1 + else if (numrator > (1.0 / 65536.0) / 2.0) { + // Get the closest sdm1 + sdm1 = (int)(numrator * 65536.0 + 0.5) / 256; + // Get the closest sdm0 + sdm0 = (int)(numrator * 65536.0 + 0.5) % 256; + } + uint32_t real_freq = (uint32_t)(rtc_xtal_freq * MHZ * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) / (((float)o_div + 2) * 2)); + *_o_div = o_div; + *_sdm0 = sdm0; + *_sdm1 = sdm1; + *_sdm2 = sdm2; + return real_freq; +} + +void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +void rtc_dig_clk8m_enable(void) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +void rtc_dig_clk8m_disable(void) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +bool rtc_dig_8m_enabled(void) +{ + return clk_ll_rc_fast_digi_is_enabled(); +} + +//------------------------------------MPLL-------------------------------------// +IRAM_ATTR void rtc_clk_mpll_disable(void) +{ + clk_ll_mpll_disable(); + s_cur_mpll_freq = 0; +} + +IRAM_ATTR void rtc_clk_mpll_enable(void) +{ + clk_ll_mpll_enable(); +} + +void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq, bool thread_safe) +{ + // TODO: ["ESP32S31"] IDF-14678 +} + +IRAM_ATTR uint32_t rtc_clk_mpll_get_freq(void) +{ + return s_cur_mpll_freq; +} diff --git a/components/esp_hw_support/port/esp32s31/rtc_time.c b/components/esp_hw_support/port/esp32s31/rtc_time.c new file mode 100644 index 0000000000..b20a306965 --- /dev/null +++ b/components/esp_hw_support/port/esp32s31/rtc_time.c @@ -0,0 +1,234 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp32s31/rom/ets_sys.h" +#include "soc/rtc.h" +#include "hal/lp_timer_hal.h" +#include "hal/clk_tree_ll.h" +// #include "hal/timer_ll.h" +#include "soc/hp_sys_clkrst_reg.h" +#include "soc/timer_group_reg.h" +#include "esp_rom_sys.h" +#include "esp_private/periph_ctrl.h" + +// TODO: [ESP32S31] IDF-14678 + +__attribute__((unused)) static const char *TAG = "rtc_time"; + +/* Calibration of clock frequency is performed using a special feature of TIMG0. + * This feature counts the number of XTAL clock cycles within a given number of + * clock cycles. + */ + +#define CLK_CAL_TIMEOUT_THRES(cal_clk, cycles) ((cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL) ? (cycles << 12) : (cycles << 10)) + +// Calibration can only be performed on relatively slow speed clock signal. Therefore, for high-speed clocks, +// calibration is performed on their DIV_CLKs. The divider is configurable. We set: +#define CLK_CAL_DIV_VAL(cal_clk) \ + ((cal_clk == RTC_CAL_RC_SLOW || cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL) ? 1 : \ + (cal_clk == RTC_CAL_LP_PLL) ? 25 : \ + (cal_clk == RTC_CAL_RC_FAST) ? 50 : \ + (cal_clk == RTC_CAL_APLL) ? 200 : \ + 4000) + +// CLK_CAL_FREQ_APPROX = CLK_FREQ_APPROX / CLK_CAL_DIV_VAL +#define CLK_CAL_FREQ_APPROX(cal_clk) \ + ((cal_clk == RTC_CAL_MPLL) ? (CLK_LL_PLL_500M_FREQ_MHZ * MHZ / 4000) : \ + (cal_clk == RTC_CAL_SPLL) ? (CLK_LL_PLL_480M_FREQ_MHZ * MHZ / 4000) : \ + (cal_clk == RTC_CAL_CPLL) ? (CLK_LL_PLL_400M_FREQ_MHZ * MHZ / 4000) : \ + (cal_clk == RTC_CAL_APLL) ? (105 * MHZ / 200) : \ + (cal_clk == RTC_CAL_SDIO_PLL0 || cal_clk == RTC_CAL_SDIO_PLL1 || cal_clk == RTC_CAL_SDIO_PLL2) ? (200 * MHZ / 4000) : \ + (cal_clk == RTC_CAL_RC_FAST) ? (SOC_CLK_RC_FAST_FREQ_APPROX / 50) : \ + (cal_clk == RTC_CAL_RC_SLOW) ? (SOC_CLK_RC_SLOW_FREQ_APPROX) : \ + (cal_clk == RTC_CAL_RC32K) ? (SOC_CLK_RC32K_FREQ_APPROX) : \ + (cal_clk == RTC_CAL_32K_XTAL) ? (SOC_CLK_XTAL32K_FREQ_APPROX) : \ + (cal_clk == RTC_CAL_LP_PLL) ? (CLK_LL_PLL_8M_FREQ_MHZ * MHZ / 25) : \ + 0) + +uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) +{ + assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V); + + if (cal_clk == RTC_CAL_RTC_MUX) { + soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); + if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) { + cal_clk = RTC_CAL_RC_SLOW; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + cal_clk = RTC_CAL_32K_XTAL; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { + cal_clk = RTC_CAL_RC32K; + } + } + if (cal_clk < 0 || cal_clk >= RTC_CAL_INVALID_CLK) { + ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated"); + return 0; + } + + /* Enable requested clock (some clocks are always on) */ + // All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock + // Only enable if originally was disabled, and set back to the disable state after calibration is done + // If the clock is already on, then do nothing + bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); + if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { + clk_ll_xtal32k_digi_enable(); + } + + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); + if (cal_clk == RTC_CAL_RC_FAST) { + if (!rc_fast_enabled) { + rtc_clk_8m_enable(true); + } + if (!dig_rc_fast_enabled) { + rtc_dig_clk8m_enable(); + } + } + + bool rc32k_enabled = clk_ll_rc32k_is_enabled(); + bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); + if (cal_clk == RTC_CAL_RC32K) { + if (!rc32k_enabled) { + rtc_clk_rc32k_enable(true); + } + if (!dig_rc32k_enabled) { + clk_ll_rc32k_digi_enable(); + } + } + + /* There may be another calibration process already running during we call this function, + * so we should wait the last process is done. + */ + if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) { + /** + * Set a small timeout threshold to accelerate the generation of timeout. + * The internal circuit will be reset when the timeout occurs and will not affect the next calibration. + */ + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1); + while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY) + && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)); + } + + /* Prepare calibration */ + REG_SET_FIELD(HP_SYS_CLKRST_TIMERGRP0_TGRT_CTRL0_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_SRC_SEL, cal_clk); + uint32_t clk_cal_divider = CLK_CAL_DIV_VAL(cal_clk); + REG_SET_FIELD(HP_SYS_CLKRST_TIMERGRP0_TGRT_CTRL0_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_DIV_NUM, clk_cal_divider - 1); + CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); + REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); + /* Figure out how long to wait for calibration to finish */ + + /* Set timeout reg and expect time delay*/ + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles)); + uint32_t expected_freq = CLK_CAL_FREQ_APPROX(cal_clk); + assert(expected_freq); + uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); + /* Start calibration */ + CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + + /* Wait for calibration to finish up to another us_time_estimate */ + esp_rom_delay_us(us_time_estimate); + uint32_t cal_val; + while (true) { + if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) { + cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE); + cal_val /= clk_cal_divider; + break; + } + if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) { + cal_val = 0; + break; + } + } + CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_TIMERGRP0_TGRT_CTRL0_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_DIV_NUM_M); + + /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ + if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { + clk_ll_xtal32k_digi_disable(); + } + + if (cal_clk == RTC_CAL_RC_FAST) { + if (!dig_rc_fast_enabled) { + rtc_dig_clk8m_disable(); + } + if (!rc_fast_enabled) { + rtc_clk_8m_enable(false); + } + } + + if (cal_clk == RTC_CAL_RC32K) { + if (!dig_rc32k_enabled) { + clk_ll_rc32k_digi_disable(); + } + if (!rc32k_enabled) { + rtc_clk_rc32k_enable(false); + } + } + + return cal_val; +} + +static bool rtc_clk_cal_32k_valid(uint32_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles) +{ + uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768 + uint64_t delta = expected_xtal_cycles / 2000; // 5/10000 = 0.05% error range + return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta)); +} + +uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) +{ + slowclk_cycles /= (cal_clk == RTC_CAL_RTC_MUX) ? 1 : CLK_CAL_DIV_VAL(cal_clk); + assert(slowclk_cycles); + soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); + uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); + + if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid((uint32_t)xtal_freq, slowclk_cycles, xtal_cycles)) { + return 0; + } + + uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles; + uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider; + uint32_t period = (uint32_t)(period_64 & UINT32_MAX); + return period; +} + +uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) +{ + assert(period); + if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) { + return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period; + } + return (time_in_us << RTC_CLK_CAL_FRACT) / period; +} + +uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period) +{ + return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT; +} + +uint64_t rtc_time_get(void) +{ + return 0;// TODO: ["ESP32S31"] IDF-14678 +} + +uint32_t rtc_clk_freq_cal(uint32_t cal_val) +{ + if (cal_val == 0) { + return 0; // cal_val will be denominator, return 0 as the symbol of failure. + } + return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val; +} + +uint32_t rtc_clk_freq_to_period(uint32_t) __attribute__((alias("rtc_clk_freq_cal"))); + +/// @brief if the calibration is used, we need to enable the timer group0 first +__attribute__((constructor)) +static void enable_timer_group0_for_calibration(void) +{ + // TODO: ["ESP32S31"] IDF-14871 +} diff --git a/components/esp_hw_support/port/esp32s31/systimer.c b/components/esp_hw_support/port/esp32s31/systimer.c new file mode 100644 index 0000000000..fd6987f3df --- /dev/null +++ b/components/esp_hw_support/port/esp32s31/systimer.c @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/systimer.h" + +// TODO: [ESP32S31] IDF-14693 + +/** + * @brief systimer's clock source is fixed to XTAL (40MHz), and has a fixed fractional divider (2.5). + * So the resolution of the systimer is 40MHz/2.5 = 16MHz. + * + */ +uint64_t systimer_ticks_to_us(uint64_t ticks) +{ + return ticks / 16; +} + +uint64_t systimer_us_to_ticks(uint64_t us) +{ + return us * 16; +} diff --git a/components/esp_rom/esp32s31/include/esp32s31/rom/cache.h b/components/esp_rom/esp32s31/include/esp32s31/rom/cache.h index afe2380d91..e116547d88 100644 --- a/components/esp_rom/esp32s31/include/esp32s31/rom/cache.h +++ b/components/esp_rom/esp32s31/include/esp32s31/rom/cache.h @@ -51,8 +51,6 @@ extern "C" { #define MAX_L1_DTAG_BANK_WAY_SIZE (MAX_L1_DTAG_BANK_WAY_ITEMS * TAG_SIZE) #define MAX_CACHE_WAY 2 -_Static_assert(MAX_CACHE_WAY >= MAX_L1_ICACHE_WAY && MAX_CACHE_WAY >= MAX_L1_DCACHE_WAY, - "MAX_CACHE_WAY should be defined to the max of (L1 ICache way, L1 DCache way)"); typedef enum { CACHE_L1_ICACHE0 = 0, diff --git a/components/esp_rom/esp32s31/include/esp32s31/rom/gpio.h b/components/esp_rom/esp32s31/include/esp32s31/rom/gpio.h index 23a7739d9f..8e94126256 100644 --- a/components/esp_rom/esp32s31/include/esp32s31/rom/gpio.h +++ b/components/esp_rom/esp32s31/include/esp32s31/rom/gpio.h @@ -7,6 +7,10 @@ #ifndef _ROM_GPIO_H_ #define _ROM_GPIO_H_ +#include +#include +#include "soc/gpio_reg.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/components/hal/esp32s31/include/hal/cache_ll.h b/components/hal/esp32s31/include/hal/cache_ll.h index 38cbc5646f..2a8f850f5c 100644 --- a/components/hal/esp32s31/include/hal/cache_ll.h +++ b/components/hal/esp32s31/include/hal/cache_ll.h @@ -955,7 +955,7 @@ __attribute__((always_inline)) static inline cache_bus_mask_t cache_ll_l2_get_bus(uint32_t cache_id, uint32_t vaddr_start, uint32_t len) { //not used, for compatibility - return 0; + return CACHE_BUS_IBUS0; } /** @@ -1071,7 +1071,7 @@ static inline uint32_t cache_ll_l2_get_access_error_intr_status(uint32_t cache_i __attribute__((always_inline)) static inline cache_bus_mask_t cache_ll_l1_get_enabled_bus(uint32_t cache_id) { - return 0; + return CACHE_BUS_IBUS0; } #ifdef __cplusplus diff --git a/components/hal/esp32s31/include/hal/clk_tree_ll.h b/components/hal/esp32s31/include/hal/clk_tree_ll.h index 65365039e1..74143a9bc8 100644 --- a/components/hal/esp32s31/include/hal/clk_tree_ll.h +++ b/components/hal/esp32s31/include/hal/clk_tree_ll.h @@ -662,7 +662,7 @@ static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rt static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void) { // TODO: [ESP32S31] IDF-14733 - return 0; + return SOC_RTC_SLOW_CLK_SRC_RC_SLOW; } /** @@ -683,7 +683,7 @@ static inline __attribute__((always_inline)) void clk_ll_lp_pll_set_src(soc_lp_p static inline __attribute__((always_inline)) soc_lp_pll_clk_src_t clk_ll_lp_pll_get_src(void) { // TODO: [ESP32S31] IDF-14733 - return 0; + return SOC_LP_PLL_CLK_SRC_RC32K; } /** @@ -716,7 +716,7 @@ static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rt static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void) { // TODO: [ESP32S31] IDF-14733 - return 0; + return SOC_RTC_FAST_CLK_SRC_RC_FAST; } /** diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index 9999083d56..b9f6a3fdc9 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -31,6 +31,14 @@ config SOC_XTAL_SUPPORT_40M bool default y +config SOC_ADC_MAX_CHANNEL_NUM + int + default 10 + +config SOC_ADC_PERIPH_NUM + int + default 2 + config SOC_SHARED_IDCACHE_SUPPORTED bool default y diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 7058a012de..33fcafde94 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -96,6 +96,11 @@ /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 +/*-------------------------- ADC CAPS ----------------------------------------*/ +/*!< SAR ADC Module*/ +#define SOC_ADC_MAX_CHANNEL_NUM (10) +#define SOC_ADC_PERIPH_NUM (2) + /*-------------------------- CACHE CAPS --------------------------------------*/ // TODO: [ESP32S31] IDF-14651 #define SOC_SHARED_IDCACHE_SUPPORTED 1 //Shared Cache for both instructions and data diff --git a/components/soc/esp32s31/include/soc/soc_pins.h b/components/soc/esp32s31/include/soc/soc_pins.h index 19bc82d6d8..fd55809fa8 100644 --- a/components/soc/esp32s31/include/soc/soc_pins.h +++ b/components/soc/esp32s31/include/soc/soc_pins.h @@ -14,4 +14,3 @@ #include "soc/gpio_pins.h" #include "soc/spi_pins.h" -#include "soc/sdmmc_pins.h" diff --git a/components/soc/esp32s31/include/soc/system_periph_retention.h b/components/soc/esp32s31/include/soc/system_periph_retention.h index 32e48d5d38..40fec604cc 100644 --- a/components/soc/esp32s31/include/soc/system_periph_retention.h +++ b/components/soc/esp32s31/include/soc/system_periph_retention.h @@ -23,7 +23,7 @@ extern "C" * useful for external use. */ #define INT_MTX_RETENTION_LINK_LEN 2 -extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN]; +// extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN]; /** * @brief Provide access to cache configuration registers retention @@ -33,7 +33,7 @@ extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTIO * useful for external use. */ #define CACHE_RETENTION_LINK_LEN 8 -extern const regdma_entries_config_t cache_regs_retention[CACHE_RETENTION_LINK_LEN]; +// extern const regdma_entries_config_t cache_regs_retention[CACHE_RETENTION_LINK_LEN]; /** * @brief Provide access to hp_system configuration registers retention @@ -43,7 +43,7 @@ extern const regdma_entries_config_t cache_regs_retention[CACHE_RETENTION_LINK_L * useful for external use. */ #define HP_SYSTEM_RETENTION_LINK_LEN 1 -extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN]; +// extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN]; /** * @brief Provide access to IOMUX configuration registers retention @@ -53,7 +53,7 @@ extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTIO * useful for external use. */ #define IOMUX_RETENTION_LINK_LEN 6 -extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN]; +// extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN]; /** * @brief Provide access to FLASH spimem configuration registers retention @@ -63,7 +63,7 @@ extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_L * useful for external use. */ #define SPIMEM_FLASH_RETENTION_LINK_LEN 8 -extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_FLASH_RETENTION_LINK_LEN]; +// extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_FLASH_RETENTION_LINK_LEN]; /** * @brief Provide access to PSRAM spimem configuration registers retention @@ -73,7 +73,7 @@ extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_FLASH_RE * useful for external use. */ #define SPIMEM_PSRAM_RETENTION_LINK_LEN 14 -extern const regdma_entries_config_t psram_spimem_regs_retention[SPIMEM_PSRAM_RETENTION_LINK_LEN]; +// extern const regdma_entries_config_t psram_spimem_regs_retention[SPIMEM_PSRAM_RETENTION_LINK_LEN]; /** * @brief Provide access to systimer configuration registers retention @@ -83,7 +83,7 @@ extern const regdma_entries_config_t psram_spimem_regs_retention[SPIMEM_PSRAM_RE * useful for external use. */ #define SYSTIMER_RETENTION_LINK_LEN 19 -extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN]; +// extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN]; /** * @brief Provide access to pau configuration registers retention @@ -93,7 +93,7 @@ extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_ * useful for external use. */ #define PAU_RETENTION_LINK_LEN 1 -extern const regdma_entries_config_t pau_regs_retention[PAU_RETENTION_LINK_LEN]; +// extern const regdma_entries_config_t pau_regs_retention[PAU_RETENTION_LINK_LEN]; #ifdef __cplusplus } diff --git a/components/soc/esp32s31/register/soc/ds_struct.h b/components/soc/esp32s31/register/soc/ds_struct.h index 99fa5e07fc..24ac950ad1 100644 --- a/components/soc/esp32s31/register/soc/ds_struct.h +++ b/components/soc/esp32s31/register/soc/ds_struct.h @@ -184,7 +184,7 @@ typedef struct { volatile ds_query_busy_reg_t query_busy; volatile ds_query_key_wrong_reg_t query_key_wrong; volatile ds_query_check_reg_t query_check; - volatile ds_static_reg_t static; + volatile ds_static_reg_t sta; uint32_t reserved_e1c; volatile ds_date_reg_t date; volatile ds_timeout_limit_reg_t timeout_limit; diff --git a/components/soc/esp32s31/register/soc/gmac_struct.h b/components/soc/esp32s31/register/soc/gmac_struct.h index d3678132e1..c60d023318 100644 --- a/components/soc/esp32s31/register/soc/gmac_struct.h +++ b/components/soc/esp32s31/register/soc/gmac_struct.h @@ -128,7 +128,7 @@ typedef union { * not applicable if the MAC is operating in the fullduplex mode This bit is reserved * _RO with default value_ if the MAC is configured for the fullduplexonly operation */ - uint32_t do:1; + uint32_t dro:1; /** fes : R/W; bitpos: [14]; default: 0; * Speed This bit selects the speed in the MII, RMII, SMII, RGMII, SGMII, or RevMII * interface: 0: 10 Mbps 1: 100 Mbps This bit is reserved _RO_ by default and is @@ -1469,11 +1469,11 @@ typedef union { */ uint32_t ran:1; uint32_t reserved_10:2; - /** and : R/W; bitpos: [12]; default: 0; + /** auto_negotiation : R/W; bitpos: [12]; default: 0; * AutoNegotiation Enable When set, this bit enables the MAC to perform * autonegotiation with the link partner Clearing this bit disables the autonegotiation */ - uint32_t and:1; + uint32_t auto_negotiation:1; uint32_t reserved_13:1; /** ele : R/W; bitpos: [14]; default: 0; * External Loopback Enable When set, this bit causes the PHY to loopback the transmit diff --git a/components/soc/esp32s31/register/soc/huk_struct.h b/components/soc/esp32s31/register/soc/huk_struct.h index 493057a313..b93a1c9f85 100644 --- a/components/soc/esp32s31/register/soc/huk_struct.h +++ b/components/soc/esp32s31/register/soc/huk_struct.h @@ -146,13 +146,13 @@ typedef union { typedef union { struct { /** start : WT; bitpos: [0]; default: 0; - * Write 1 to continue HUK Generator operation at LOAD/GAIN state. + * Write 1 to ctn HUK Generator operation at LOAD/GAIN state. */ uint32_t start:1; - /** continue : WT; bitpos: [1]; default: 0; + /** ctn : WT; bitpos: [1]; default: 0; * Write 1 to start HUK Generator at IDLE state. */ - uint32_t continue:1; + uint32_t ctn:1; uint32_t reserved_2:30; }; uint32_t val; diff --git a/components/soc/esp32s31/register/soc/keymng_struct.h b/components/soc/esp32s31/register/soc/keymng_struct.h index c5f470fdfb..5462f9f94f 100644 --- a/components/soc/esp32s31/register/soc/keymng_struct.h +++ b/components/soc/esp32s31/register/soc/keymng_struct.h @@ -234,13 +234,13 @@ typedef union { typedef union { struct { /** start : WT; bitpos: [0]; default: 0; - * Write 1 to continue Key Manager operation at LOAD/GAIN state. + * Write 1 to ctn Key Manager operation at LOAD/GAIN state. */ uint32_t start:1; - /** continue : WT; bitpos: [1]; default: 0; + /** ctn : WT; bitpos: [1]; default: 0; * Write 1 to start Key Manager at IDLE state. */ - uint32_t continue:1; + uint32_t ctn:1; uint32_t reserved_2:30; }; uint32_t val; @@ -377,7 +377,7 @@ typedef struct { volatile keymng_int_st_reg_t int_st; volatile keymng_int_ena_reg_t int_ena; volatile keymng_int_clr_reg_t int_clr; - volatile keymng_static_reg_t static; + volatile keymng_static_reg_t sta; volatile keymng_lock_reg_t lock; volatile keymng_conf_reg_t conf; volatile keymng_start_reg_t start; diff --git a/components/soc/esp32s31/register/soc/sha_struct.h b/components/soc/esp32s31/register/soc/sha_struct.h index e73b38f492..84e0d4fe35 100644 --- a/components/soc/esp32s31/register/soc/sha_struct.h +++ b/components/soc/esp32s31/register/soc/sha_struct.h @@ -73,10 +73,10 @@ typedef union { */ typedef union { struct { - /** continue : WO; bitpos: [0]; default: 0; + /** ctn : WO; bitpos: [0]; default: 0; * Write 1 to continue Typical SHA calculation. */ - uint32_t continue:1; + uint32_t ctn:1; uint32_t reserved_1:31; }; uint32_t val; @@ -140,19 +140,19 @@ typedef union { /** Group: Configuration Register */ -/** Type of 3_shake_length register +/** Type of shake_length_3 register * DMA configuration register 3. */ typedef union { struct { - /** 3_shake_length : R/W; bitpos: [20:0]; default: 50; + /** shake_length_3 : R/W; bitpos: [20:0]; default: 50; * SHAKE output hash word length */ - uint32_t 3_shake_length:21; + uint32_t shake_length_3:21; uint32_t reserved_21:11; }; uint32_t val; -} sha_3_shake_length_reg_t; +} sha_shake_length_3_reg_t; /** Group: Status Registers */ @@ -244,7 +244,7 @@ typedef struct { uint32_t reserved_004[2]; volatile sha_dma_block_num_reg_t dma_block_num; volatile sha_start_reg_t start; - volatile sha_continue_reg_t continue; + volatile sha_continue_reg_t ctn; volatile sha_busy_reg_t busy; volatile sha_dma_start_reg_t dma_start; volatile sha_dma_continue_reg_t dma_continue; @@ -254,12 +254,12 @@ typedef struct { volatile sha_dma_rx_reset_reg_t dma_rx_reset; volatile sha_dma_tx_reset_reg_t dma_tx_reset; volatile sha_free_reg_t free; - volatile sha_3_shake_length_reg_t 3_shake_length; - volatile uint32_t 2_sm_3_h[16]; - volatile uint32_t 2_sm_3_m[32]; - volatile uint32_t 3_h[50]; + volatile sha_shake_length_3_reg_t shake_length_3; + volatile uint32_t sm_2_h_3[16]; + volatile uint32_t sm_2_m_3[32]; + volatile uint32_t h_3[50]; uint32_t reserved_1c8[14]; - volatile uint32_t 3_m[50]; + volatile uint32_t m_3[50]; } sha_dev_t; diff --git a/examples/common_components/env_caps/esp32s31/Kconfig.env_caps b/examples/common_components/env_caps/esp32s31/Kconfig.env_caps new file mode 100644 index 0000000000..c89ee9c091 --- /dev/null +++ b/examples/common_components/env_caps/esp32s31/Kconfig.env_caps @@ -0,0 +1,15 @@ +config ENV_GPIO_RANGE_MIN + int + default 0 + +config ENV_GPIO_RANGE_MAX + int + default 62 + +config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + +config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX