feat(esp32s31): Add esp_hw_support component and header ci support

This commit is contained in:
C.S.M
2025-11-26 14:03:50 +08:00
parent 551b264193
commit 904c94ba3a
30 changed files with 1459 additions and 39 deletions
+1
View File
@@ -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=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=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=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: test_nvs_coverage:
extends: extends:
@@ -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
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#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
@@ -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)
@@ -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
@@ -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
@@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#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;
}
@@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#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 */
}
@@ -0,0 +1,99 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#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 chips 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;
}
@@ -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);
}
@@ -0,0 +1,473 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#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
@@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// TODO: [ESP32S31] IDF-14780
@@ -0,0 +1,339 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#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;
}
@@ -0,0 +1,234 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <assert.h>
#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
}
@@ -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;
}
@@ -51,8 +51,6 @@ extern "C" {
#define MAX_L1_DTAG_BANK_WAY_SIZE (MAX_L1_DTAG_BANK_WAY_ITEMS * TAG_SIZE) #define MAX_L1_DTAG_BANK_WAY_SIZE (MAX_L1_DTAG_BANK_WAY_ITEMS * TAG_SIZE)
#define MAX_CACHE_WAY 2 #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 { typedef enum {
CACHE_L1_ICACHE0 = 0, CACHE_L1_ICACHE0 = 0,
@@ -7,6 +7,10 @@
#ifndef _ROM_GPIO_H_ #ifndef _ROM_GPIO_H_
#define _ROM_GPIO_H_ #define _ROM_GPIO_H_
#include <stdint.h>
#include <stdbool.h>
#include "soc/gpio_reg.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -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) 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 //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)) __attribute__((always_inline))
static inline cache_bus_mask_t cache_ll_l1_get_enabled_bus(uint32_t cache_id) static inline cache_bus_mask_t cache_ll_l1_get_enabled_bus(uint32_t cache_id)
{ {
return 0; return CACHE_BUS_IBUS0;
} }
#ifdef __cplusplus #ifdef __cplusplus
@@ -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) static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
{ {
// TODO: [ESP32S31] IDF-14733 // 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) static inline __attribute__((always_inline)) soc_lp_pll_clk_src_t clk_ll_lp_pll_get_src(void)
{ {
// TODO: [ESP32S31] IDF-14733 // 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) static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
{ {
// TODO: [ESP32S31] IDF-14733 // TODO: [ESP32S31] IDF-14733
return 0; return SOC_RTC_FAST_CLK_SRC_RC_FAST;
} }
/** /**
@@ -31,6 +31,14 @@ config SOC_XTAL_SUPPORT_40M
bool bool
default y default y
config SOC_ADC_MAX_CHANNEL_NUM
int
default 10
config SOC_ADC_PERIPH_NUM
int
default 2
config SOC_SHARED_IDCACHE_SUPPORTED config SOC_SHARED_IDCACHE_SUPPORTED
bool bool
default y default y
@@ -96,6 +96,11 @@
/*-------------------------- XTAL CAPS ---------------------------------------*/ /*-------------------------- XTAL CAPS ---------------------------------------*/
#define SOC_XTAL_SUPPORT_40M 1 #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 --------------------------------------*/ /*-------------------------- CACHE CAPS --------------------------------------*/
// TODO: [ESP32S31] IDF-14651 // TODO: [ESP32S31] IDF-14651
#define SOC_SHARED_IDCACHE_SUPPORTED 1 //Shared Cache for both instructions and data #define SOC_SHARED_IDCACHE_SUPPORTED 1 //Shared Cache for both instructions and data
@@ -14,4 +14,3 @@
#include "soc/gpio_pins.h" #include "soc/gpio_pins.h"
#include "soc/spi_pins.h" #include "soc/spi_pins.h"
#include "soc/sdmmc_pins.h"
@@ -23,7 +23,7 @@ extern "C"
* useful for external use. * useful for external use.
*/ */
#define INT_MTX_RETENTION_LINK_LEN 2 #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 * @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. * useful for external use.
*/ */
#define CACHE_RETENTION_LINK_LEN 8 #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 * @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. * useful for external use.
*/ */
#define HP_SYSTEM_RETENTION_LINK_LEN 1 #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 * @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. * useful for external use.
*/ */
#define IOMUX_RETENTION_LINK_LEN 6 #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 * @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. * useful for external use.
*/ */
#define SPIMEM_FLASH_RETENTION_LINK_LEN 8 #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 * @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. * useful for external use.
*/ */
#define SPIMEM_PSRAM_RETENTION_LINK_LEN 14 #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 * @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. * useful for external use.
*/ */
#define SYSTIMER_RETENTION_LINK_LEN 19 #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 * @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. * useful for external use.
*/ */
#define PAU_RETENTION_LINK_LEN 1 #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 #ifdef __cplusplus
} }
@@ -184,7 +184,7 @@ typedef struct {
volatile ds_query_busy_reg_t query_busy; volatile ds_query_busy_reg_t query_busy;
volatile ds_query_key_wrong_reg_t query_key_wrong; volatile ds_query_key_wrong_reg_t query_key_wrong;
volatile ds_query_check_reg_t query_check; volatile ds_query_check_reg_t query_check;
volatile ds_static_reg_t static; volatile ds_static_reg_t sta;
uint32_t reserved_e1c; uint32_t reserved_e1c;
volatile ds_date_reg_t date; volatile ds_date_reg_t date;
volatile ds_timeout_limit_reg_t timeout_limit; volatile ds_timeout_limit_reg_t timeout_limit;
@@ -128,7 +128,7 @@ typedef union {
* not applicable if the MAC is operating in the fullduplex mode This bit is reserved * 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 * _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; /** fes : R/W; bitpos: [14]; default: 0;
* Speed This bit selects the speed in the MII, RMII, SMII, RGMII, SGMII, or RevMII * 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 * 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 ran:1;
uint32_t reserved_10:2; 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 Enable When set, this bit enables the MAC to perform
* autonegotiation with the link partner Clearing this bit disables the autonegotiation * 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; uint32_t reserved_13:1;
/** ele : R/W; bitpos: [14]; default: 0; /** ele : R/W; bitpos: [14]; default: 0;
* External Loopback Enable When set, this bit causes the PHY to loopback the transmit * External Loopback Enable When set, this bit causes the PHY to loopback the transmit
@@ -146,13 +146,13 @@ typedef union {
typedef union { typedef union {
struct { struct {
/** start : WT; bitpos: [0]; default: 0; /** 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; 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. * Write 1 to start HUK Generator at IDLE state.
*/ */
uint32_t continue:1; uint32_t ctn:1;
uint32_t reserved_2:30; uint32_t reserved_2:30;
}; };
uint32_t val; uint32_t val;
@@ -234,13 +234,13 @@ typedef union {
typedef union { typedef union {
struct { struct {
/** start : WT; bitpos: [0]; default: 0; /** 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; 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. * Write 1 to start Key Manager at IDLE state.
*/ */
uint32_t continue:1; uint32_t ctn:1;
uint32_t reserved_2:30; uint32_t reserved_2:30;
}; };
uint32_t val; uint32_t val;
@@ -377,7 +377,7 @@ typedef struct {
volatile keymng_int_st_reg_t int_st; volatile keymng_int_st_reg_t int_st;
volatile keymng_int_ena_reg_t int_ena; volatile keymng_int_ena_reg_t int_ena;
volatile keymng_int_clr_reg_t int_clr; 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_lock_reg_t lock;
volatile keymng_conf_reg_t conf; volatile keymng_conf_reg_t conf;
volatile keymng_start_reg_t start; volatile keymng_start_reg_t start;
@@ -73,10 +73,10 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
/** continue : WO; bitpos: [0]; default: 0; /** ctn : WO; bitpos: [0]; default: 0;
* Write 1 to continue Typical SHA calculation. * Write 1 to continue Typical SHA calculation.
*/ */
uint32_t continue:1; uint32_t ctn:1;
uint32_t reserved_1:31; uint32_t reserved_1:31;
}; };
uint32_t val; uint32_t val;
@@ -140,19 +140,19 @@ typedef union {
/** Group: Configuration Register */ /** Group: Configuration Register */
/** Type of 3_shake_length register /** Type of shake_length_3 register
* DMA configuration register 3. * DMA configuration register 3.
*/ */
typedef union { typedef union {
struct { 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 * SHAKE output hash word length
*/ */
uint32_t 3_shake_length:21; uint32_t shake_length_3:21;
uint32_t reserved_21:11; uint32_t reserved_21:11;
}; };
uint32_t val; uint32_t val;
} sha_3_shake_length_reg_t; } sha_shake_length_3_reg_t;
/** Group: Status Registers */ /** Group: Status Registers */
@@ -244,7 +244,7 @@ typedef struct {
uint32_t reserved_004[2]; uint32_t reserved_004[2];
volatile sha_dma_block_num_reg_t dma_block_num; volatile sha_dma_block_num_reg_t dma_block_num;
volatile sha_start_reg_t start; 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_busy_reg_t busy;
volatile sha_dma_start_reg_t dma_start; volatile sha_dma_start_reg_t dma_start;
volatile sha_dma_continue_reg_t dma_continue; 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_rx_reset_reg_t dma_rx_reset;
volatile sha_dma_tx_reset_reg_t dma_tx_reset; volatile sha_dma_tx_reset_reg_t dma_tx_reset;
volatile sha_free_reg_t free; volatile sha_free_reg_t free;
volatile sha_3_shake_length_reg_t 3_shake_length; volatile sha_shake_length_3_reg_t shake_length_3;
volatile uint32_t 2_sm_3_h[16]; volatile uint32_t sm_2_h_3[16];
volatile uint32_t 2_sm_3_m[32]; volatile uint32_t sm_2_m_3[32];
volatile uint32_t 3_h[50]; volatile uint32_t h_3[50];
uint32_t reserved_1c8[14]; uint32_t reserved_1c8[14];
volatile uint32_t 3_m[50]; volatile uint32_t m_3[50];
} sha_dev_t; } sha_dev_t;
@@ -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