clk_tree: Add a general API to get the frequency of different clocks

Add basic clk_tree driver and hal implementation.
This commit is contained in:
Song Ruo Jing 2022-12-28 15:04:51 +08:00
parent 1bf040e0b6
commit 2c9aa4559c
58 changed files with 1800 additions and 24 deletions

View File

@ -26,7 +26,9 @@ if(NOT BOOTLOADER_BUILD)
"sleep_mac_bb.c"
"regi2c_ctrl.c"
"adc_share_hw_ctrl.c"
"port/${target}/io_mux.c")
"port/${target}/io_mux.c"
"port/${target}/clk_tree.c"
"port/clk_tree_common.c")
if(NOT CONFIG_IDF_TARGET_ESP32 AND NOT CONFIG_IDF_TARGET_ESP32S2)
list(APPEND srcs "sleep_retention.c")
@ -86,6 +88,7 @@ if(NOT BOOTLOADER_BUILD)
if(CONFIG_IDF_TARGET_ESP32H2)
list(REMOVE_ITEM srcs
"adc_share_hw_ctrl.c" # TODO: IDF-6215
"port/clk_tree_common.c" # TODO: IDF-6265
)
endif()
else()

View File

@ -7,6 +7,7 @@
#include <freertos/FreeRTOS.h>
#include "clk_ctrl_os.h"
#include "soc/rtc.h"
#include "esp_private/clk_tree_common.h"
#include "esp_check.h"
static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
@ -27,14 +28,9 @@ bool periph_rtc_dig_clk8m_enable(void)
if (s_periph_ref_counts == 0) {
rtc_dig_clk8m_enable();
#if SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
#if SOC_CLK_RC_FAST_D256_SUPPORTED
// If RC_FAST_D256 clock exists, calibration on a slow freq clock is much faster (less slow clock cycles need to wait)
s_rc_fast_freq = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_8MD256, 100)) << 8; // f_[rc_fast] = f_[rc_fast_d256] * 256;
#else
// Calibrate directly on the RC_FAST clock requires much more slow clock cycles to get an accurate freq value
s_rc_fast_freq = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_RC_FAST, 10000));
#endif
s_rc_fast_freq = clk_tree_rc_fast_get_freq_hz(CLK_TREE_SRC_FREQ_PRECISION_EXACT);
if (s_rc_fast_freq == 0) {
rtc_dig_clk8m_disable();
portEXIT_CRITICAL(&periph_spinlock);
return false;
}

View File

@ -0,0 +1,47 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_err.h"
#include "soc/clk_tree_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Degree of precision of frequency value to be returned by clk_tree_src_get_freq_hz()
*/
typedef enum {
CLK_TREE_SRC_FREQ_PRECISION_CACHED, /*< Get value from the data cached by the driver; If the data is 0, then a calibration will be performed */
CLK_TREE_SRC_FREQ_PRECISION_APPROX, /*< Get its approxiamte frequency value */
CLK_TREE_SRC_FREQ_PRECISION_EXACT, /*< Always perform a calibration */
CLK_TREE_SRC_FREQ_PRECISION_INVALID, /*< Invalid degree of precision */
} clk_tree_src_freq_precision_t;
/**
* @brief Get frequency of module clock source
*
* @param[in] clk_src Clock source available to modules, in soc_module_clk_t
* @param[in] precision Degree of precision, one of clk_tree_src_freq_precision_t values
* This arg only applies to the clock sources that their frequencies can vary:
* SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_RTC_SLOW, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_RC_FAST_D256,
* SOC_MOD_CLK_XTAL32K
* For other clock sources, this field is ignored.
* @param[out] freq_value Frequency of the clock source, in Hz
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_FAIL Calibration failed
*/
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, clk_tree_src_freq_precision_t precision,
uint32_t *freq_value);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,79 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "clk_tree.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_CLK_RC_FAST_D256_SUPPORTED
/**
* @brief Get frequency of RC_FAST_D256_CLK
*
* @param precision Degree of precision of the returned frequency value, one of clk_tree_src_freq_precision_t values
*
* @return RC_FAST_D256 clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed.
*/
uint32_t clk_tree_rc_fast_d256_get_freq_hz(clk_tree_src_freq_precision_t precision);
#endif
#if SOC_CLK_XTAL32K_SUPPORTED
/**
* @brief Get frequency of XTAL32K_CLK
*
* @param precision Degree of precision of the returned frequency value, one of clk_tree_src_freq_precision_t values
*
* @return XTAL32K clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed.
*/
uint32_t clk_tree_xtal32k_get_freq_hz(clk_tree_src_freq_precision_t precision);
#endif
#if SOC_CLK_OSC_SLOW_SUPPORTED
/**
* @brief Get frequency of OSC_SLOW_CLK
*
* @param precision Degree of precision of the returned frequency value, one of clk_tree_src_freq_precision_t values
*
* @return OSC_SLOW clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed.
*/
uint32_t clk_tree_osc_slow_get_freq_hz(clk_tree_src_freq_precision_t precision);
#endif
/**
* @brief Get frequency of RC_FAST_CLK
*
* @param precision Degree of precision of the returned frequency value, one of clk_tree_src_freq_precision_t values
*
* @return RC_FAST clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed.
*/
uint32_t clk_tree_rc_fast_get_freq_hz(clk_tree_src_freq_precision_t precision);
/**
* @brief Get frequency of LP_SLOW_CLK (i.e. RTC_SLOW_CLK)
*
* @param precision Degree of precision of the returned frequency value, one of clk_tree_src_freq_precision_t values
*
* @return LP_SLOW clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed.
*/
uint32_t clk_tree_lp_slow_get_freq_hz(clk_tree_src_freq_precision_t precision);
/**
* @brief Get frequency of LP_FAST_CLK (i.e. RTC_FAST_CLK)
*
* @param precision Degree of precision of the returned frequency value, one of clk_tree_src_freq_precision_t values
*
* @return LP_FAST clock frequency, in Hz. Returns 0 if degree of precision is invalid or calibration failed.
*/
uint32_t clk_tree_lp_fast_get_freq_hz(clk_tree_src_freq_precision_t precision);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,190 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_private/clk_tree_common.h"
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "esp_private/esp_clk.h"
#include "soc/clk_tree_defs.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#include "esp_hw_log.h"
static const char *TAG = "clk_tree_common";
typedef struct clk_tree_calibrated_freq_t clk_tree_calibrated_freq_t;
struct clk_tree_calibrated_freq_t {
#if SOC_CLK_RC_FAST_D256_SUPPORTED
uint32_t rc_fast_d256;
#elif SOC_CLK_RC_FAST_SUPPORT_CALIBRATION // && !SOC_CLK_RC_FAST_D256_SUPPORTED
uint32_t rc_fast;
#endif
#if SOC_CLK_XTAL32K_SUPPORTED
uint32_t xtal32k;
#endif
#if SOC_CLK_OSC_SLOW_SUPPORTED
uint32_t osc_slow;
#endif
};
// TODO: Better to implement a spinlock for the static variables
static clk_tree_calibrated_freq_t s_calibrated_freq = {};
/* Number of cycles for RTC_SLOW_CLK calibration */
#define RTC_SLOW_CLK_CAL_CYCLES CONFIG_RTC_CLK_CAL_CYCLES
/* Number of cycles for ~32kHz clocks calibration (rc_fast_d256, xtal32k, osc_slow, rc32k) */
#define DEFAULT_32K_CLK_CAL_CYCLES 100
/* Number of cycles for RC_FAST calibration */
#define DEFAULT_RC_FAST_CAL_CYCLES 10000 // RC_FAST has a higher frequency, therefore, requires more cycles to get an accurate value
/**
* Performs a frequency calibration to RTC slow clock
*
* slowclk_cycles Number of slow clock cycles to count.
* If slowclk_cycles = 0, calibration will not be performed. Clock's theoretical value will be used.
*
* Returns the number of XTAL clock cycles within the given number of slow clock cycles
* It returns 0 if calibration failed, i.e. clock is not running
*/
static uint32_t clk_tree_rtc_slow_calibration(uint32_t slowclk_cycles)
{
uint32_t cal_val = 0;
if (slowclk_cycles > 0) {
cal_val = rtc_clk_cal(RTC_CAL_RTC_MUX, slowclk_cycles);
} else {
const uint64_t cal_dividend = (1ULL << RTC_CLK_CAL_FRACT) * 1000000ULL;
uint32_t source_approx_freq = clk_hal_lp_slow_get_freq_hz();
assert(source_approx_freq);
cal_val = (uint32_t)(cal_dividend / source_approx_freq);
}
if (cal_val) {
ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val);
// Update the calibration value of RTC_SLOW_CLK
esp_clk_slowclk_cal_set(cal_val);
}
return cal_val;
}
#if SOC_CLK_RC_FAST_D256_SUPPORTED
uint32_t clk_tree_rc_fast_d256_get_freq_hz(clk_tree_src_freq_precision_t precision)
{
switch (precision) {
case CLK_TREE_SRC_FREQ_PRECISION_APPROX:
return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
case CLK_TREE_SRC_FREQ_PRECISION_CACHED:
if (!s_calibrated_freq.rc_fast_d256) {
s_calibrated_freq.rc_fast_d256 = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_8MD256, DEFAULT_32K_CLK_CAL_CYCLES));
}
return s_calibrated_freq.rc_fast_d256;
case CLK_TREE_SRC_FREQ_PRECISION_EXACT:
s_calibrated_freq.rc_fast_d256 = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_8MD256, DEFAULT_32K_CLK_CAL_CYCLES));
return s_calibrated_freq.rc_fast_d256;
default:
return 0;
}
}
#endif
#if SOC_CLK_XTAL32K_SUPPORTED
uint32_t clk_tree_xtal32k_get_freq_hz(clk_tree_src_freq_precision_t precision)
{
switch (precision) {
case CLK_TREE_SRC_FREQ_PRECISION_APPROX:
return SOC_CLK_XTAL32K_FREQ_APPROX;
case CLK_TREE_SRC_FREQ_PRECISION_CACHED:
if (!s_calibrated_freq.xtal32k) {
s_calibrated_freq.xtal32k = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_32K_XTAL, DEFAULT_32K_CLK_CAL_CYCLES));
}
return s_calibrated_freq.xtal32k;
case CLK_TREE_SRC_FREQ_PRECISION_EXACT:
s_calibrated_freq.xtal32k = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_32K_XTAL, DEFAULT_32K_CLK_CAL_CYCLES));
return s_calibrated_freq.xtal32k;
default:
return 0;
}
}
#endif
#if SOC_CLK_OSC_SLOW_SUPPORTED
uint32_t clk_tree_osc_slow_get_freq_hz(clk_tree_src_freq_precision_t precision)
{
switch (precision) {
case CLK_TREE_SRC_FREQ_PRECISION_APPROX:
return SOC_CLK_OSC_SLOW_FREQ_APPROX;
case CLK_TREE_SRC_FREQ_PRECISION_CACHED:
if (!s_calibrated_freq.osc_slow) {
s_calibrated_freq.osc_slow = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_32K_OSC_SLOW, DEFAULT_32K_CLK_CAL_CYCLES));
}
return s_calibrated_freq.osc_slow;
case CLK_TREE_SRC_FREQ_PRECISION_EXACT:
s_calibrated_freq.osc_slow = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_32K_OSC_SLOW, DEFAULT_32K_CLK_CAL_CYCLES));
return s_calibrated_freq.osc_slow;
default:
return 0;
}
}
#endif
uint32_t clk_tree_lp_slow_get_freq_hz(clk_tree_src_freq_precision_t precision)
{
switch (precision) {
case CLK_TREE_SRC_FREQ_PRECISION_CACHED:
// This returns calibrated (if CONFIG_xxx_RTC_CLK_CAL_CYCLES) value stored in RTC storage register
return rtc_clk_freq_cal(clk_ll_rtc_slow_load_cal());
case CLK_TREE_SRC_FREQ_PRECISION_APPROX:
return clk_hal_lp_slow_get_freq_hz();
case CLK_TREE_SRC_FREQ_PRECISION_EXACT:
return rtc_clk_freq_cal(clk_tree_rtc_slow_calibration(RTC_SLOW_CLK_CAL_CYCLES));
default:
return 0;
}
}
uint32_t clk_tree_rc_fast_get_freq_hz(clk_tree_src_freq_precision_t precision)
{
#if SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
if (precision == CLK_TREE_SRC_FREQ_PRECISION_APPROX) {
return SOC_CLK_RC_FAST_FREQ_APPROX;
}
#if SOC_CLK_RC_FAST_D256_SUPPORTED
// If RC_FAST_D256 clock exists, calibration on a slow freq clock is much faster (less slow clock cycles need to wait)
return clk_tree_rc_fast_d256_get_freq_hz(precision) << 8;
#else
// Calibrate directly on the RC_FAST clock requires much more slow clock cycles to get an accurate freq value
if (precision != CLK_TREE_SRC_FREQ_PRECISION_CACHED || !s_calibrated_freq.rc_fast) {
s_calibrated_freq.rc_fast = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_RC_FAST, DEFAULT_RC_FAST_CAL_CYCLES));
}
return s_calibrated_freq.rc_fast;
#endif //SOC_CLK_RC_FAST_D256_SUPPORTED
#else //!SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
if (precision != CLK_TREE_SRC_FREQ_PRECISION_APPROX) {
// No way of getting exact rc_fast freq
ESP_HW_LOGW(TAG, "unable to get the exact freq of rc_fast_clk, returning its approx. freq value");
}
return SOC_CLK_RC_FAST_FREQ_APPROX;
#endif //SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
}
uint32_t clk_tree_lp_fast_get_freq_hz(clk_tree_src_freq_precision_t precision)
{
switch (clk_ll_rtc_fast_get_src()) {
case SOC_RTC_FAST_CLK_SRC_XTAL_DIV:
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 //SOC_RTC_FAST_CLK_SRC_XTAL_D4
return clk_hal_xtal_get_freq_mhz() * MHZ >> 2;
#else //SOC_RTC_FAST_CLK_SRC_XTAL_D2
return clk_hal_xtal_get_freq_mhz() * MHZ >> 1;
#endif
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
return clk_tree_rc_fast_get_freq_hz(precision) / clk_ll_rc_fast_get_divider();
default:
// Invalid clock source
assert(false);
return 0;
}
}

View File

@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "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/clk_tree_common.h"
static const char *TAG = "clk_tree";
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, 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 < 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_APB:
clk_src_freq = clk_hal_apb_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_D2:
clk_src_freq = (clk_ll_bbpll_get_freq_mhz() * MHZ) >> 1;
break;
case SOC_MOD_CLK_PLL_F160M:
clk_src_freq = CLK_LL_PLL_160M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_RTC_SLOW:
clk_src_freq = clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
clk_src_freq = clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST_D256:
clk_src_freq = clk_tree_rc_fast_d256_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = clk_tree_xtal32k_get_freq_hz(precision);
break;
case SOC_MOD_CLK_REF_TICK:
clk_src_freq = 1 * MHZ;
break;
case SOC_MOD_CLK_APLL:
clk_src_freq = clk_hal_apll_get_freq_hz();
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;
}

View File

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "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/clk_tree_common.h"
static const char *TAG = "clk_tree";
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, 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 < 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_F40M:
clk_src_freq = CLK_LL_PLL_40M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F60M:
clk_src_freq = CLK_LL_PLL_60M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F80M:
clk_src_freq = CLK_LL_PLL_80M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_RTC_SLOW:
clk_src_freq = clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
clk_src_freq = clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST_D256:
clk_src_freq = clk_tree_rc_fast_d256_get_freq_hz(precision);
break;
case SOC_MOD_CLK_OSC_SLOW:
clk_src_freq = clk_tree_osc_slow_get_freq_hz(precision);
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;
}

View File

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "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/clk_tree_common.h"
static const char *TAG = "clk_tree";
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, 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 < 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_APB:
clk_src_freq = clk_hal_apb_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_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_RTC_SLOW:
clk_src_freq = clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
clk_src_freq = clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST_D256:
clk_src_freq = clk_tree_rc_fast_d256_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = clk_tree_xtal32k_get_freq_hz(precision);
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;
}

View File

@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "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/clk_tree_common.h"
static const char *TAG = "clk_tree";
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, 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 < 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_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_RTC_SLOW:
clk_src_freq = clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
clk_src_freq = clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = clk_tree_xtal32k_get_freq_hz(precision);
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;
}

View File

@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "clk_tree.h"
#include "esp_err.h"
#include "esp_check.h"
#include "soc/rtc.h"
static const char *TAG = "clk_tree";
// TODO: IDF-6265
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, 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 < 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_XTAL:
clk_src_freq = 32 * 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;
}

View File

@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "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/clk_tree_common.h"
static const char *TAG = "clk_tree";
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, 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 < 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_AHB:
clk_src_freq = clk_hal_ahb_get_freq_hz();
break;
case SOC_MOD_CLK_APB:
clk_src_freq = clk_hal_apb_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:
clk_src_freq = clk_ll_bbpll_get_freq_mhz() * MHZ;
break;
case SOC_MOD_CLK_RTC_SLOW:
clk_src_freq = clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
clk_src_freq = clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = clk_tree_xtal32k_get_freq_hz(precision);
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;
}

View File

@ -0,0 +1,69 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "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/clk_tree_common.h"
static const char *TAG = "clk_tree";
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, 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 < 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_APB:
clk_src_freq = clk_hal_apb_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_F160M:
clk_src_freq = CLK_LL_PLL_160M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_RTC_SLOW:
clk_src_freq = clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
case SOC_MOD_CLK_TEMP_SENSOR:
clk_src_freq = clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST_D256:
clk_src_freq = clk_tree_rc_fast_d256_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = clk_tree_xtal32k_get_freq_hz(precision);
break;
case SOC_MOD_CLK_REF_TICK:
clk_src_freq = 1 * MHZ;
break;
case SOC_MOD_CLK_APLL:
clk_src_freq = clk_hal_apll_get_freq_hz();
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;
}

View File

@ -0,0 +1,69 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "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/clk_tree_common.h"
static const char *TAG = "clk_tree";
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, 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 < 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_APB:
clk_src_freq = clk_hal_apb_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_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_D2:
clk_src_freq = (clk_ll_bbpll_get_freq_mhz() * MHZ) >> 1;
break;
case SOC_MOD_CLK_RTC_SLOW:
clk_src_freq = clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
case SOC_MOD_CLK_TEMP_SENSOR:
clk_src_freq = clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST_D256:
clk_src_freq = clk_tree_rc_fast_d256_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = clk_tree_xtal32k_get_freq_hz(precision);
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;
}

View File

@ -39,7 +39,8 @@ if(NOT BOOTLOADER_BUILD)
"spi_flash_hal_iram.c"
"spi_flash_encrypt_hal_iram.c"
"adc_hal_common.c"
"adc_oneshot_hal.c")
"adc_oneshot_hal.c"
"${target}/clk_tree_hal.c")
if(CONFIG_SOC_SYSTIMER_SUPPORTED AND NOT CONFIG_HAL_SYSTIMER_USE_ROM_IMPL)
list(APPEND srcs "systimer_hal.c")
@ -209,6 +210,7 @@ if(NOT BOOTLOADER_BUILD)
"adc_oneshot_hal.c" # TODO: IDF-6214
"adc_hal_common.c" # TODO: IDF-6215
"esp32h2/rtc_cntl_hal.c"
"esp32h2/clk_tree_hal.c"
)
endif()
endif()

View File

@ -0,0 +1,108 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
case SOC_CPU_CLK_SRC_APLL:
return clk_hal_apll_get_freq_hz() / MHZ;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
switch (source) {
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_cpu_get_freq_mhz_from_pll() * MHZ;
case SOC_CPU_CLK_SRC_APLL: {
uint32_t apll_freq_hz = clk_hal_apll_get_freq_hz();
uint32_t divider = clk_ll_cpu_get_divider_from_apll();
if (divider == 0) {
HAL_LOGE(CLK_HAL_TAG, "Invalid cpu config");
return 0;
}
return apll_freq_hz / divider;
}
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {
case SOC_CPU_CLK_SRC_PLL:
// AHB_CLK is a fixed value when CPU_CLK is clocked from PLL
return CLK_LL_AHB_MAX_FREQ_MHZ * MHZ;
case SOC_CPU_CLK_SRC_APLL:
return clk_hal_cpu_get_freq_hz() >> 1;
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_cpu_get_freq_hz();
}
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_ahb_get_freq_hz();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
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_RC_FAST_D256:
return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
return (uint32_t)RTC_XTAL_FREQ_AUTO;
}
return freq;
}
uint32_t clk_hal_apll_get_freq_hz(void)
{
uint32_t xtal_freq_mhz = clk_hal_xtal_get_freq_mhz();
uint32_t o_div = 0;
uint32_t sdm0 = 0;
uint32_t sdm1 = 0;
uint32_t sdm2 = 0;
clk_ll_apll_get_config(&o_div, &sdm0, &sdm1, &sdm2);
uint32_t apll_freq_hz = (uint32_t)(xtal_freq_mhz * MHZ * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) /
(((float)o_div + 2) * 2));
return apll_freq_hz;
}

View File

@ -33,6 +33,8 @@ extern "C" {
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_AHB_MAX_FREQ_MHZ CLK_LL_PLL_80M_FREQ_MHZ
/* BBPLL configuration parameters at reset */
#define CLK_LL_BBPLL_IR_CAL_DELAY_VAL 0x18
#define CLK_LL_BBPLL_IR_CAL_EXT_CAP_VAL 0x20
@ -150,6 +152,22 @@ static inline bool clk_ll_apll_is_fpd(void)
return REG_GET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
}
/**
* @brief Get APLL configuration which can be used to calculate APLL frequency
*
* @param[out] o_div Frequency divider, 0..31
* @param[out] sdm0 Frequency adjustment parameter, 0..255
* @param[out] sdm1 Frequency adjustment parameter, 0..255
* @param[out] sdm2 Frequency adjustment parameter, 0..63
*/
static inline void clk_ll_apll_get_config(uint32_t *o_div, uint32_t *sdm0, uint32_t *sdm1, uint32_t *sdm2)
{
*o_div = REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV);
*sdm0 = REGI2C_READ_MASK(I2C_APLL, I2C_APLL_DSDM0);
*sdm1 = REGI2C_READ_MASK(I2C_APLL, I2C_APLL_DSDM1);
*sdm2 = REGI2C_READ_MASK(I2C_APLL, I2C_APLL_DSDM2);
}
/**
* @brief Set APLL configuration
*
@ -618,6 +636,26 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
return REG_GET_FIELD(SYSCON_SYSCLK_CONF_REG, SYSCON_PRE_DIV_CNT) + 1;
}
/**
* @brief Get CPU_CLK's APLL clock source path divider
*
* @return Divider. Returns 0 means invalid.
*/
static inline uint32_t clk_ll_cpu_get_divider_from_apll(void)
{
// APLL path divider choice shares the same register with CPUPERIOD_SEL
uint32_t cpu_freq_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL);
switch (cpu_freq_sel) {
case 0:
return 4;
case 1:
return 2;
default:
// Invalid CPUPERIOD_SEL value if APLL is the clock source
return 0;
}
}
/**
* @brief Set REF_TICK divider to make REF_TICK frequency at 1MHz
*

View File

@ -0,0 +1,83 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "sdkconfig.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
switch (source) {
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_cpu_get_freq_mhz_from_pll() * MHZ;
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {
case SOC_CPU_CLK_SRC_PLL:
// AHB_CLK is a fixed value when CPU_CLK is clocked from PLL
return CLK_LL_AHB_MAX_FREQ_MHZ * MHZ;
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_cpu_get_freq_hz();
}
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_ahb_get_freq_hz();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
return SOC_CLK_RC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
return SOC_CLK_OSC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256:
return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume %dMHz", CONFIG_XTAL_FREQ);
return CONFIG_XTAL_FREQ;
}
return freq;
}

View File

@ -24,11 +24,15 @@ extern "C" {
#define MHZ (1000000)
#define CLK_LL_PLL_40M_FREQ_MHZ (40)
#define CLK_LL_PLL_60M_FREQ_MHZ (60)
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
#define CLK_LL_PLL_120M_FREQ_MHZ (120)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_AHB_MAX_FREQ_MHZ CLK_LL_PLL_40M_FREQ_MHZ
/**
* @brief XTAL32K_CLK enable modes
*/

View File

@ -0,0 +1,83 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
switch (source) {
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_cpu_get_freq_mhz_from_pll() * MHZ;
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {
case SOC_CPU_CLK_SRC_PLL:
// AHB_CLK is a fixed value when CPU_CLK is clocked from PLL
return CLK_LL_AHB_MAX_FREQ_MHZ * MHZ;
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_cpu_get_freq_hz();
}
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_ahb_get_freq_hz();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
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_RC_FAST_D256:
return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
return (uint32_t)RTC_XTAL_FREQ_40M;
}
return freq;
}

View File

@ -30,6 +30,8 @@ extern "C" {
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_AHB_MAX_FREQ_MHZ CLK_LL_PLL_80M_FREQ_MHZ
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
.dac = 3, \
.dres = 3, \

View File

@ -0,0 +1,76 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_cpu_get_hs_divider() : clk_ll_cpu_get_ls_divider();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider;
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_ahb_get_hs_divider() : clk_ll_ahb_get_ls_divider();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider;
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_ahb_get_freq_hz() / clk_ll_apb_get_divider();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
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_OSC_SLOW:
return SOC_CLK_OSC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC32K:
return SOC_CLK_RC32K_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
return (uint32_t)RTC_XTAL_FREQ_40M;
}
return freq;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -28,6 +28,7 @@ extern "C" {
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
#define CLK_LL_PLL_120M_FREQ_MHZ (120)
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
#define CLK_LL_PLL_240M_FREQ_MHZ (240)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)

View File

@ -0,0 +1,74 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_ahb_get_divider();
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_ahb_get_freq_hz() / clk_ll_apb_get_divider();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
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_OSC_SLOW:
return SOC_CLK_OSC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC32K:
return SOC_CLK_RC32K_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 32MHz");
return (uint32_t)RTC_XTAL_FREQ_32M;
}
return freq;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

View File

@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
case SOC_CPU_CLK_SRC_XTAL_D2:
return clk_hal_xtal_get_freq_mhz() >> 1;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
return clk_hal_cpu_get_freq_hz() / clk_ll_ahb_get_divider();
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_ahb_get_freq_hz() / clk_ll_apb_get_divider();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
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:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 32MHz");
return (uint32_t)RTC_XTAL_FREQ_32M;
}
return freq;
}

View File

@ -341,7 +341,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
*
* @param divider Divider. AHB_DIV_NUM = divider - 1.
*/
static inline void clk_ll_ahb_set_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_ahb_set_divider(uint32_t divider)
{
HAL_ASSERT(divider > 0);
REG_SET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM, divider - 1);
@ -352,7 +352,7 @@ static inline void clk_ll_ahb_set_divider(uint32_t divider)
*
* @return Divider. Divider = (AHB_DIV_NUM + 1).
*/
static inline uint32_t clk_ll_ahb_get_divider(void)
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_divider(void)
{
return REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM) + 1;
}
@ -362,7 +362,7 @@ static inline uint32_t clk_ll_ahb_get_divider(void)
*
* @param divider Divider. APB_DIV_NUM = divider - 1.
*/
static inline void clk_ll_apb_set_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider)
{
HAL_ASSERT(divider > 0);
REG_SET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM, divider - 1);
@ -373,7 +373,7 @@ static inline void clk_ll_apb_set_divider(uint32_t divider)
*
* @return Divider. Divider = (APB_DIV_NUM + 1).
*/
static inline uint32_t clk_ll_apb_get_divider(void)
static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void)
{
return REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM) + 1;
}

View File

@ -0,0 +1,112 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
case SOC_CPU_CLK_SRC_APLL:
return clk_hal_apll_get_freq_hz() / MHZ;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
switch (source) {
case SOC_CPU_CLK_SRC_PLL: {
// PLL 320MHz, CPU 240MHz is an undetermined state
uint32_t pll_freq_mhz = clk_ll_bbpll_get_freq_mhz();
uint32_t cpu_freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
if (pll_freq_mhz == CLK_LL_PLL_320M_FREQ_MHZ && cpu_freq_mhz == CLK_LL_PLL_240M_FREQ_MHZ) {
HAL_LOGE(CLK_HAL_TAG, "Invalid cpu config");
return 0;
}
return cpu_freq_mhz * MHZ;
}
case SOC_CPU_CLK_SRC_APLL: {
uint32_t apll_freq_hz = clk_hal_apll_get_freq_hz();
uint32_t divider = clk_ll_cpu_get_divider_from_apll();
if (divider == 0) {
HAL_LOGE(CLK_HAL_TAG, "Invalid cpu config");
return 0;
}
return apll_freq_hz / divider;
}
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {
case SOC_CPU_CLK_SRC_PLL:
// AHB_CLK is a fixed value when CPU_CLK is clocked from PLL
return CLK_LL_AHB_MAX_FREQ_MHZ * MHZ;
case SOC_CPU_CLK_SRC_APLL:
return clk_hal_cpu_get_freq_hz() >> 1;
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_cpu_get_freq_hz();
}
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_ahb_get_freq_hz();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
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_RC_FAST_D256:
return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
// ESP32S2's supported XTAL frequency is fixed, didn't save in the RTC storage register
return CLK_LL_XTAL_FREQ_MHZ;
}
uint32_t clk_hal_apll_get_freq_hz(void)
{
uint32_t xtal_freq_mhz = clk_hal_xtal_get_freq_mhz();
uint32_t o_div = 0;
uint32_t sdm0 = 0;
uint32_t sdm1 = 0;
uint32_t sdm2 = 0;
clk_ll_apll_get_config(&o_div, &sdm0, &sdm1, &sdm2);
uint32_t apll_freq_hz = (uint32_t)(xtal_freq_mhz * MHZ * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) /
(((float)o_div + 2) * 2));
return apll_freq_hz;
}

View File

@ -32,6 +32,8 @@ extern "C" {
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_AHB_MAX_FREQ_MHZ CLK_LL_PLL_80M_FREQ_MHZ
// ESP32S2 only supports 40MHz crystal
#define CLK_LL_XTAL_FREQ_MHZ (40)
@ -107,6 +109,22 @@ static inline void clk_ll_apll_disable(void)
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU);
}
/**
* @brief Get APLL configuration which can be used to calculate APLL frequency
*
* @param[out] o_div Frequency divider, 0..31
* @param[out] sdm0 Frequency adjustment parameter, 0..255
* @param[out] sdm1 Frequency adjustment parameter, 0..255
* @param[out] sdm2 Frequency adjustment parameter, 0..63
*/
static inline void clk_ll_apll_get_config(uint32_t *o_div, uint32_t *sdm0, uint32_t *sdm1, uint32_t *sdm2)
{
*o_div = REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV);
*sdm0 = REGI2C_READ_MASK(I2C_APLL, I2C_APLL_DSDM0);
*sdm1 = REGI2C_READ_MASK(I2C_APLL, I2C_APLL_DSDM1);
*sdm2 = REGI2C_READ_MASK(I2C_APLL, I2C_APLL_DSDM2);
}
/**
* @brief Set APLL configuration
*
@ -542,6 +560,26 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
return REG_GET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_PRE_DIV_CNT) + 1;
}
/**
* @brief Get CPU_CLK's APLL clock source path divider
*
* @return Divider. Returns 0 means invalid.
*/
static inline uint32_t clk_ll_cpu_get_divider_from_apll(void)
{
// APLL path divider choice depends on PLL_FREQ_SEL and CPUPERIOD_SEL
uint32_t pll_freq_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_PLL_FREQ_SEL);
uint32_t cpu_freq_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL);
if (pll_freq_sel == 0 && cpu_freq_sel == 0) {
return 4;
} else if (pll_freq_sel == 0 && cpu_freq_sel == 1) {
return 2;
} else {
// Invalid configuration if APLL is the clock source
return 0;
}
}
/**
* @brief Set REF_TICK divider to make REF_TICK frequency at 1MHz
*

View File

@ -0,0 +1,91 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL:
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
switch (source) {
case SOC_CPU_CLK_SRC_PLL: {
// PLL 320MHz, CPU 240MHz is an undetermined state
uint32_t pll_freq_mhz = clk_ll_bbpll_get_freq_mhz();
uint32_t cpu_freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
if (pll_freq_mhz == CLK_LL_PLL_320M_FREQ_MHZ && cpu_freq_mhz == CLK_LL_PLL_240M_FREQ_MHZ) {
HAL_LOGE(CLK_HAL_TAG, "Invalid cpu config");
return 0;
}
return cpu_freq_mhz * MHZ;
}
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
// AHB_CLK path is highly dependent on CPU_CLK path
switch (clk_ll_cpu_get_src()) {
case SOC_CPU_CLK_SRC_PLL:
// AHB_CLK is a fixed value when CPU_CLK is clocked from PLL
return CLK_LL_AHB_MAX_FREQ_MHZ * MHZ;
default: // SOC_CPU_CLK_SRC_XTAL, SOC_CPU_CLK_SRC_RC_FAST...
return clk_hal_cpu_get_freq_hz();
}
}
uint32_t clk_hal_apb_get_freq_hz(void)
{
return clk_hal_ahb_get_freq_hz();
}
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
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_RC_FAST_D256:
return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
return 0;
}
}
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
return (uint32_t)RTC_XTAL_FREQ_40M;
}
return freq;
}

View File

@ -31,6 +31,8 @@ extern "C" {
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_AHB_MAX_FREQ_MHZ CLK_LL_PLL_80M_FREQ_MHZ
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
.dac = 3, \
.dres = 3, \

View File

@ -0,0 +1,72 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/clk_tree_defs.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get SOC_ROOT_CLK frequency
*
* @param cpu_clk_src One of the clock sources in soc_cpu_clk_src_t
*
* @return SOC ROOT clock frequency, in MHz. Returns 0 if input argument is invalid.
*/
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src);
/**
* @brief Get CPU_CLK frequency
*
* @return CPU clock frequency, in Hz. Returns 0 if internal clock configuration is invalid.
*/
uint32_t clk_hal_cpu_get_freq_hz(void);
/**
* @brief Get AHB_CLK frequency
*
* @return AHB clock frequency, in Hz. Returns 0 if internal clock configuration is invalid.
*/
uint32_t clk_hal_ahb_get_freq_hz(void);
/**
* @brief Get APB_CLK frequency
*
* @return APB clock frequency, in Hz. Returns 0 if internal clock configuration is invalid.
*/
uint32_t clk_hal_apb_get_freq_hz(void);
/**
* @brief Get LP_SLOW_CLK (i.e. RTC_SLOW_CLK) approximate frequency
*
* @return LP Slow clock frequency, in Hz. Returns 0 if LP_SLOW clock source is invalid.
*/
uint32_t clk_hal_lp_slow_get_freq_hz(void);
/**
* @brief Get XTAL_CLK frequency
*
* @return XTAL clock frequency, in MHz
*/
uint32_t clk_hal_xtal_get_freq_mhz(void);
#if SOC_CLK_APLL_SUPPORTED
/**
* @brief Get APLL_CLK frequency
*
* @return APLL clock frequency, in Hz
*/
uint32_t clk_hal_apll_get_freq_hz(void);
#endif //SOC_CLK_APLL_SUPPORTED
#ifdef __cplusplus
}
#endif

View File

@ -771,6 +771,10 @@ config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
bool
default y
config SOC_CLK_XTAL32K_SUPPORTED
bool
default y
config SOC_SDMMC_USE_IOMUX
bool
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -115,6 +115,7 @@ typedef enum {
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external crystal (2~40MHz) */
SOC_MOD_CLK_REF_TICK, /*!< REF_TICK is derived from APB, it has a fixed frequency of 1MHz even when APB frequency changes */
SOC_MOD_CLK_APLL, /*!< APLL is sourced from PLL, and its frequency is configurable through APLL configuration registers */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER///////////////////////////////////////////////////////////////

View File

@ -384,6 +384,8 @@
#define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256 (1)
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
/*-------------------------- SDMMC CAPS -----------------------------------------*/
/* On ESP32, clock/cmd/data pins use IO MUX.

View File

@ -615,6 +615,10 @@ config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
bool
default y
config SOC_CLK_OSC_SLOW_SUPPORTED
bool
default y
config SOC_WIFI_HW_TSF
bool
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -110,6 +110,7 @@ typedef enum {
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST_D256, /*!< RC_FAST_D256_CLK comes from the internal 20MHz rc oscillator, divided by 256, and passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 26/40MHz crystal */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER///////////////////////////////////////////////////////////////

View File

@ -294,6 +294,8 @@
#define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256 (1)
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< ESP32C2 only supports to connect an external oscillator, not a crystal */
/*------------------------------------ WI-FI CAPS ------------------------------------*/
#define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */
#define SOC_WIFI_FTM_SUPPORT (0) /*!< FTM is not supported */

View File

@ -871,6 +871,10 @@ config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
bool
default y
config SOC_CLK_XTAL32K_SUPPORTED
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
bool
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -106,11 +106,11 @@ typedef enum {
SOC_MOD_CLK_APB, /*!< APB_CLK is highly dependent on the CPU_CLK source */
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL, and has a fixed frequency of 80MHz */
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from PLL, and has a fixed frequency of 160MHz */
SOC_MOD_CLK_PLL_D2, /*!< PLL_D2_CLK is derived from PLL, it has a fixed divider of 2 */
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST_D256, /*!< RC_FAST_D256_CLK comes from the internal 20MHz rc oscillator, divided by 256, and passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER///////////////////////////////////////////////////////////////

View File

@ -388,6 +388,8 @@
#define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256 (1)
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)

View File

@ -999,6 +999,18 @@ config SOC_MODEM_CLOCK_IS_INDEPENDENT
bool
default y
config SOC_CLK_XTAL32K_SUPPORTED
bool
default y
config SOC_CLK_OSC_SLOW_SUPPORTED
bool
default y
config SOC_CLK_RC32K_SUPPORTED
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
bool
default y

View File

@ -121,6 +121,7 @@ typedef enum {
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER//////////////////////////////////////////////////////////////

View File

@ -446,6 +446,10 @@
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (1)
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)

View File

@ -811,6 +811,18 @@ config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
bool
default y
config SOC_CLK_XTAL32K_SUPPORTED
bool
default y
config SOC_CLK_OSC_SLOW_SUPPORTED
bool
default y
config SOC_CLK_RC32K_SUPPORTED
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
bool
default y

View File

@ -124,6 +124,7 @@ typedef enum {
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 8MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER///////////////////////////////////////////////////////////////

View File

@ -425,6 +425,13 @@
#define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!<Supports CRC only the stub code in RTC memory */
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
// #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
// TODO: IDF-6229 (Copy from esp32c6, need check)
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)

View File

@ -811,6 +811,14 @@ config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
bool
default y
config SOC_CLK_XTAL32K_SUPPORTED
bool
default y
config SOC_CLK_RC32K_SUPPORTED
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
bool
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -117,6 +117,7 @@ typedef enum {
SOC_MOD_CLK_RC_FAST, /*< RC_FAST_CLK comes from the internal 8MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*< XTAL_CLK comes from the external 32MHz crystal */
SOC_MOD_CLK_PLL, /*< PLL_CLK is the output of 32MHz crystal oscillator frequency multiplier, 96MHz */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER///////////////////////////////////////////////////////////////

View File

@ -380,6 +380,10 @@
#define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!<Supports CRC only the stub code in RTC memory */
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)

View File

@ -983,6 +983,10 @@ config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
bool
default y
config SOC_CLK_XTAL32K_SUPPORTED
bool
default y
config SOC_COEX_HW_PTI
bool
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -113,6 +113,7 @@ typedef enum {
SOC_MOD_CLK_REF_TICK, /*!< REF_TICK is derived from XTAL or RC_FAST via a divider, it has a fixed frequency of 1MHz by default */
SOC_MOD_CLK_APLL, /*!< APLL is sourced from PLL, and its frequency is configurable through APLL configuration registers */
SOC_MOD_CLK_TEMP_SENSOR, /*!< TEMP_SENSOR_CLK comes directly from the internal 8MHz rc oscillator */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER///////////////////////////////////////////////////////////////

View File

@ -427,6 +427,8 @@
#define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256 (1)
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
/*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/
#define SOC_COEX_HW_PTI (1)
/* ---------------------------- Compatibility ------------------------------- */

View File

@ -1011,6 +1011,10 @@ config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
bool
default y
config SOC_CLK_XTAL32K_SUPPORTED
bool
default y
config SOC_EFUSE_DIS_DOWNLOAD_DCACHE
bool
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -112,6 +112,7 @@ typedef enum {
SOC_MOD_CLK_RC_FAST_D256, /*!< RC_FAST_D256_CLK comes from the internal 20MHz rc oscillator, divided by 256, and passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
SOC_MOD_CLK_TEMP_SENSOR, /*!< TEMP_SENSOR_CLK comes directly from the internal 20MHz rc oscillator */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
//////////////////////////////////////////////////SYSTIMER///////////////////////////////////////////////////////////////

View File

@ -417,6 +417,8 @@
#define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256 (1)
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
/*-------------------------- eFuse CAPS----------------------------*/
#define SOC_EFUSE_DIS_DOWNLOAD_DCACHE 1
#define SOC_EFUSE_HARD_DIS_JTAG 1

View File

@ -133,6 +133,7 @@ INPUT = \
$(PROJECT_PATH)/components/esp_http_server/include/esp_http_server.h \
$(PROJECT_PATH)/components/esp_https_ota/include/esp_https_ota.h \
$(PROJECT_PATH)/components/esp_https_server/include/esp_https_server.h \
$(PROJECT_PATH)/components/esp_hw_support/include/clk_tree.h \
$(PROJECT_PATH)/components/esp_hw_support/include/esp_async_memcpy.h \
$(PROJECT_PATH)/components/esp_hw_support/include/esp_chip_info.h \
$(PROJECT_PATH)/components/esp_hw_support/include/esp_cpu.h \

View File

@ -9,10 +9,17 @@ Clock Tree
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"}
The clock subsystem of {IDF_TARGET_NAME} is used to source and distribute system/module clocks from a range of root clocks. The clock tree driver maintains the basic functionality of the system clock and the intricate relationship among module clocks.
This document starts with the introduction to root and module clocks. Then it covers the clock tree APIs that users can call to monitor the status of the module clocks at runtime.
Introduction
------------
This section lists definitions of the {IDF_TARGET_NAME}'s supported root clocks and module clocks. These definitions are commonly used in the driver configuration, to help user select a proper source clock for the peripheral.
Root Clocks
-----------
^^^^^^^^^^^
Root clocks generate reliable clock signals. These clock signals then pass through various gates, muxes, dividers, or multipliers to become the clock sources for every functional module: the CPU core(s), WIFI, BT, the RTC, and the peripherals.
@ -69,11 +76,17 @@ Root clocks generate reliable clock signals. These clock signals then pass throu
Typically, the frequency of the signal generated from a RC oscillator circuit is less accurate and more sensitive to environment comparing to the signal generated from a crystal. {IDF_TARGET_NAME} provides several clock source options for the RTC_SLOW_CLK, and users can make the choice based on the requirements for system time accuracy and power consumption (refer to :ref:`rtc-clock-source-choice` for more details).
Module Clocks
-------------
^^^^^^^^^^^^^
{IDF_TARGET_NAME}'s available module clocks are listed in :cpp:type:`soc_module_clk_t`. Each module clock has a unique ID. You can get more information on each clock by checking the documented enum value.
API Usage
---------
The clock tree driver provides an all-in-one API to get the frequency of the module clocks, :cpp:func:`clk_tree_src_get_freq_hz`. Users can call this function at any moment, with specifying the clock name (:cpp:enum:`soc_module_clk_t`) and the desired degree of precision of the returned frequency value (:cpp:enum:`clk_tree_src_freq_precision_t`).
API Reference
-------------
.. include-build-file:: inc/clk_tree_defs.inc
.. include-build-file:: inc/clk_tree.inc

View File

@ -32,6 +32,11 @@ if(CONFIG_IDF_TARGET_ESP32C2 OR CONFIG_IDF_TARGET_ESP32C6 OR CONFIG_IDF_TARGET_E
idf_build_set_property(C_COMPILE_OPTIONS "-DCONFIG_MMU_PAGE_SIZE=64" APPEND)
endif()
if(CONFIG_IDF_TARGET_ESP32C2)
# clk_tree hal-driver needs CONFIG_XTAL_FREQ
idf_build_set_property(C_COMPILE_OPTIONS "-DCONFIG_XTAL_FREQ=26" APPEND)
endif()
# Currently, only support a single core on Xtensa targets.
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
idf_build_set_property(C_COMPILE_OPTIONS "-DportNUM_PROCESSORS=1" APPEND)