mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp32s31): Add esp_hw_support component and header ci support
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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 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;
|
||||
}
|
||||
|
||||
@@ -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_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,
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#ifndef _ROM_GPIO_H_
|
||||
#define _ROM_GPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/gpio_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#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)
|
||||
{
|
||||
//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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,4 +14,3 @@
|
||||
|
||||
#include "soc/gpio_pins.h"
|
||||
#include "soc/spi_pins.h"
|
||||
#include "soc/sdmmc_pins.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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user