mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(clk): support for esp32s31 clock tree
This commit is contained in:
@@ -50,7 +50,6 @@ __attribute__((weak)) void esp_rtc_init(void)
|
||||
__attribute__((weak)) void esp_clk_init(void)
|
||||
{
|
||||
#if !CONFIG_IDF_ENV_FPGA
|
||||
pmu_init();
|
||||
assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_32M);
|
||||
|
||||
rtc_clk_8m_enable(true);
|
||||
|
||||
@@ -138,11 +138,8 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
|
||||
* will time out, returning 0.
|
||||
*/
|
||||
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
|
||||
soc_clk_freq_calculation_src_t cal_sel = -1;
|
||||
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
rtc_clk_32k_enable(true);
|
||||
cal_sel = CLK_CAL_32K_XTAL;
|
||||
}
|
||||
rtc_clk_32k_enable(true);
|
||||
soc_clk_freq_calculation_src_t cal_sel = CLK_CAL_32K_XTAL;
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(cal_sel, SLOW_CLK_CAL_CYCLES);
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
choice ESP_DEFAULT_CPU_FREQ_MHZ
|
||||
prompt "CPU frequency"
|
||||
default ESP_DEFAULT_CPU_FREQ_MHZ_40 if IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
|
||||
default ESP_DEFAULT_CPU_FREQ_MHZ_320
|
||||
help
|
||||
CPU frequency to be set on application startup.
|
||||
|
||||
config ESP_DEFAULT_CPU_FREQ_MHZ_40
|
||||
bool "40 MHz"
|
||||
depends on IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
|
||||
config ESP_DEFAULT_CPU_FREQ_MHZ_240
|
||||
bool "240 MHz"
|
||||
config ESP_DEFAULT_CPU_FREQ_MHZ_320
|
||||
bool "320 MHz"
|
||||
endchoice
|
||||
|
||||
config ESP_DEFAULT_CPU_FREQ_MHZ
|
||||
int
|
||||
default 40 if ESP_DEFAULT_CPU_FREQ_MHZ_40
|
||||
default 240 if ESP_DEFAULT_CPU_FREQ_MHZ_240
|
||||
default 320 if ESP_DEFAULT_CPU_FREQ_MHZ_320
|
||||
|
||||
@@ -18,17 +18,7 @@
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "soc/hp_sys_clkrst_reg.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "soc/hp_sys_clkrst_reg.h"
|
||||
#include "soc/lp_clkrst_reg.h"
|
||||
#include "soc/lp_system_reg.h"
|
||||
#include "soc/spi_mem_c_reg.h"
|
||||
#include "soc/spi_mem_s_reg.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "soc/hp_alive_sys_reg.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#if SOC_WDT_SUPPORTED || SOC_RTC_WDT_SUPPORTED
|
||||
#include "hal/wdt_hal.h"
|
||||
#endif
|
||||
@@ -39,22 +29,21 @@
|
||||
#include "esp_rom_serial_output.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
// TODO: ["ESP32S31"] IDF-14733
|
||||
|
||||
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
|
||||
* Larger values increase startup delay. Smaller values may cause false positive
|
||||
* detection (i.e. oscillator runs for a few cycles and then stops).
|
||||
*/
|
||||
#define SLOW_CLK_CAL_CYCLES CONFIG_RTC_CLK_CAL_CYCLES
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src);
|
||||
|
||||
static const char *TAG = "clk";
|
||||
ESP_LOG_ATTR_TAG(TAG, "clk");
|
||||
|
||||
void IRAM_ATTR esp_rtc_init(void)
|
||||
__attribute__((weak)) void IRAM_ATTR esp_rtc_init(void)
|
||||
{
|
||||
#if SOC_PMU_SUPPORTED
|
||||
#if SOC_PMU_SUPPORTED && !CONFIG_IDF_ENV_FPGA
|
||||
pmu_init();
|
||||
#endif //SOC_PMU_SUPPORTED
|
||||
}
|
||||
@@ -64,6 +53,7 @@ __attribute__((weak)) void esp_clk_init(void)
|
||||
assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M);
|
||||
|
||||
rtc_clk_8m_enable(true);
|
||||
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_WDT_ENABLE) && SOC_RTC_WDT_SUPPORTED
|
||||
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.
|
||||
@@ -123,8 +113,11 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
|
||||
/* number of times to repeat 32k XTAL calibration
|
||||
* before giving up and switching to the internal RC
|
||||
*/
|
||||
int retry_32k_xtal = 3;
|
||||
|
||||
soc_rtc_slow_clk_src_t old_rtc_slow_clk_src = rtc_clk_slow_src_get();
|
||||
do {
|
||||
bool revoke_32k_enable = false;
|
||||
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
/* 32k XTAL oscillator needs to be enabled and running before it can
|
||||
* be used. Hardware doesn't have a direct way of checking if the
|
||||
@@ -134,24 +127,47 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
|
||||
* will time out, returning 0.
|
||||
*/
|
||||
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
|
||||
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
rtc_clk_32k_enable(true);
|
||||
rtc_clk_32k_enable(true);
|
||||
soc_clk_freq_calculation_src_t cal_sel = CLK_CAL_32K_XTAL;
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(cal_sel, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0) {
|
||||
if (retry_32k_xtal-- > 0) {
|
||||
continue;
|
||||
}
|
||||
ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 136 kHz oscillator");
|
||||
rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||
revoke_32k_enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
|
||||
rtc_clk_rc32k_enable(true);
|
||||
}
|
||||
rtc_clk_slow_src_set(rtc_slow_clk_src);
|
||||
|
||||
// Disable unused clock sources after clock source switching is complete.
|
||||
// Regardless of the clock source selection, the internal 136K clock source will always keep on.
|
||||
if (rtc_slow_clk_src != SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
if (revoke_32k_enable || \
|
||||
((old_rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) && rtc_slow_clk_src != SOC_RTC_SLOW_CLK_SRC_XTAL32K)) {
|
||||
rtc_clk_32k_enable(false);
|
||||
}
|
||||
if (rtc_slow_clk_src != SOC_RTC_SLOW_CLK_SRC_RC32K) {
|
||||
rtc_clk_rc32k_enable(false);
|
||||
}
|
||||
// We have enabled all LP clock power in pmu_init, re-initialize the LP clock power based on the slow clock source after selection.
|
||||
pmu_lp_power_t lp_clk_power = {
|
||||
.xpd_xtal32k = (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K),
|
||||
.xpd_rc32k = 0,
|
||||
.xpd_fosc = 1,
|
||||
.pd_osc = 0
|
||||
};
|
||||
pmu_ll_lp_set_clk_power(&PMU, PMU_MODE_LP_ACTIVE, lp_clk_power.val);
|
||||
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
/* TODO: 32k XTAL oscillator has some frequency drift at startup.
|
||||
* Improve calibration routine to wait until the frequency is stable.
|
||||
*/
|
||||
cal_val = rtc_clk_cal(CLK_CAL_RTC_SLOW, SLOW_CLK_CAL_CYCLES);
|
||||
} else {
|
||||
const uint64_t cal_dividend = (1ULL << RTC_CLK_CAL_FRACT) * 1000000ULL;
|
||||
cal_val = (uint32_t)(cal_dividend / rtc_clk_slow_freq_get_hz());
|
||||
}
|
||||
} while (cal_val == 0);
|
||||
ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %" PRIu32, cal_val);
|
||||
esp_clk_slowclk_cal_set(cal_val);
|
||||
|
||||
Reference in New Issue
Block a user