mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-07 14:44:32 +02:00
clk_tree: Refactor rtc_clk.c by adding HAL layer for clock subsystem
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
#include "hal/efuse_hal.h"
|
#include "hal/efuse_hal.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#include "soc/dport_reg.h"
|
#include "hal/clk_tree_ll.h"
|
||||||
#endif
|
#endif
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "esp_rom_uart.h"
|
#include "esp_rom_uart.h"
|
||||||
@@ -33,22 +33,28 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
|||||||
* previously.
|
* previously.
|
||||||
*/
|
*/
|
||||||
if (efuse_hal_get_chip_revision() == 0 &&
|
if (efuse_hal_get_chip_revision() == 0 &&
|
||||||
DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL) == DPORT_CPUPERIOD_SEL_240) {
|
clk_ll_cpu_get_freq_mhz_from_pll() == CLK_LL_PLL_240M_FREQ_MHZ) {
|
||||||
cpu_freq_mhz = 240;
|
cpu_freq_mhz = 240;
|
||||||
}
|
}
|
||||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||||
cpu_freq_mhz = 64;
|
cpu_freq_mhz = 64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rtc_clk_apb_freq_get() < APB_CLK_FREQ || esp_rom_get_reset_reason(0) != RESET_REASON_CPU0_SW) {
|
if (esp_rom_get_reset_reason(0) != RESET_REASON_CPU0_SW || rtc_clk_apb_freq_get() < APB_CLK_FREQ) {
|
||||||
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
|
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
||||||
#endif
|
#endif
|
||||||
/* ESP32-S2 doesn't have XTAL_FREQ choice, always 40MHz */
|
/* Except ESP32, there is no XTAL_FREQ choice */
|
||||||
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
|
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
|
||||||
clk_cfg.slow_clk_src = rtc_clk_slow_src_get();
|
clk_cfg.slow_clk_src = rtc_clk_slow_src_get();
|
||||||
|
if (clk_cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_INVALID) {
|
||||||
|
clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||||
|
}
|
||||||
clk_cfg.fast_clk_src = rtc_clk_fast_src_get();
|
clk_cfg.fast_clk_src = rtc_clk_fast_src_get();
|
||||||
|
if (clk_cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_INVALID) {
|
||||||
|
clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_XTAL_DIV;
|
||||||
|
}
|
||||||
rtc_clk_init(clk_cfg);
|
rtc_clk_init(clk_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include "esp_rom_caps.h"
|
#include "esp_rom_caps.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "esp_private/esp_clk.h"
|
#include "esp_private/esp_clk.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#include "esp32/rom/rtc.h"
|
#include "esp32/rom/rtc.h"
|
||||||
@@ -126,12 +127,12 @@ void esp_clk_slowclk_cal_set(uint32_t new_cal)
|
|||||||
*/
|
*/
|
||||||
esp_rtc_get_time_us();
|
esp_rtc_get_time_us();
|
||||||
#endif // CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER
|
#endif // CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER
|
||||||
REG_WRITE(RTC_SLOW_CLK_CAL_REG, new_cal);
|
clk_ll_rtc_slow_store_cal(new_cal);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t esp_clk_slowclk_cal_get(void)
|
uint32_t esp_clk_slowclk_cal_get(void)
|
||||||
{
|
{
|
||||||
return REG_READ(RTC_SLOW_CLK_CAL_REG);
|
return clk_ll_rtc_slow_load_cal();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t esp_clk_rtc_time(void)
|
uint64_t esp_clk_rtc_time(void)
|
||||||
|
@@ -47,7 +47,7 @@ void regi2c_exit_critical(void);
|
|||||||
#endif // BOOTLOADER_BUILD
|
#endif // BOOTLOADER_BUILD
|
||||||
|
|
||||||
/* Convenience macros for the above functions, these use register definitions
|
/* Convenience macros for the above functions, these use register definitions
|
||||||
* from regi2c_apll.h/regi2c_bbpll.h header files.
|
* from regi2c_xxx.h header files.
|
||||||
*/
|
*/
|
||||||
#define REGI2C_WRITE_MASK(block, reg_add, indata) \
|
#define REGI2C_WRITE_MASK(block, reg_add, indata) \
|
||||||
regi2c_ctrl_write_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata)
|
regi2c_ctrl_write_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata)
|
||||||
|
@@ -12,92 +12,24 @@
|
|||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/sens_periph.h"
|
#include "soc/sens_periph.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/dport_reg.h"
|
|
||||||
#include "hal/efuse_ll.h"
|
#include "hal/efuse_ll.h"
|
||||||
#include "hal/efuse_hal.h"
|
#include "hal/efuse_hal.h"
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "soc/gpio_struct.h"
|
#include "soc/gpio_struct.h"
|
||||||
#include "hal/cpu_hal.h"
|
#include "hal/cpu_hal.h"
|
||||||
#include "hal/gpio_ll.h"
|
#include "hal/gpio_ll.h"
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
|
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "esp_rom_gpio.h"
|
#include "esp_rom_gpio.h"
|
||||||
#include "esp32/rom/ets_sys.h" // for ets_update_cpu_frequency
|
#include "esp32/rom/ets_sys.h" // for ets_update_cpu_frequency
|
||||||
#include "esp32/rom/rtc.h"
|
#include "esp32/rom/rtc.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "soc/io_mux_reg.h"
|
||||||
|
|
||||||
#include "regi2c_ctrl.h"
|
|
||||||
#include "regi2c_apll.h"
|
|
||||||
#include "regi2c_bbpll.h"
|
|
||||||
|
|
||||||
/* BBPLL configuration values */
|
|
||||||
#define BBPLL_ENDIV5_VAL_320M 0x43
|
|
||||||
#define BBPLL_BBADC_DSMP_VAL_320M 0x84
|
|
||||||
#define BBPLL_ENDIV5_VAL_480M 0xc3
|
|
||||||
#define BBPLL_BBADC_DSMP_VAL_480M 0x74
|
|
||||||
#define BBPLL_IR_CAL_DELAY_VAL 0x18
|
|
||||||
#define BBPLL_IR_CAL_EXT_CAP_VAL 0x20
|
|
||||||
#define BBPLL_OC_ENB_FCAL_VAL 0x9a
|
|
||||||
#define BBPLL_OC_ENB_VCON_VAL 0x00
|
|
||||||
#define BBPLL_BBADC_CAL_7_0_VAL 0x00
|
|
||||||
|
|
||||||
#define APLL_SDM_STOP_VAL_1 0x09
|
|
||||||
#define APLL_SDM_STOP_VAL_2_REV0 0x69
|
|
||||||
#define APLL_SDM_STOP_VAL_2_REV1 0x49
|
|
||||||
|
|
||||||
#define APLL_CAL_DELAY_1 0x0f
|
|
||||||
#define APLL_CAL_DELAY_2 0x3f
|
|
||||||
#define APLL_CAL_DELAY_3 0x1f
|
|
||||||
|
|
||||||
#define XTAL_32K_DAC_VAL 1
|
|
||||||
#define XTAL_32K_DRES_VAL 3
|
|
||||||
#define XTAL_32K_DBIAS_VAL 0
|
|
||||||
|
|
||||||
#define XTAL_32K_BOOTSTRAP_DAC_VAL 3
|
|
||||||
#define XTAL_32K_BOOTSTRAP_DRES_VAL 3
|
|
||||||
#define XTAL_32K_BOOTSTRAP_DBIAS_VAL 0
|
|
||||||
#define XTAL_32K_BOOTSTRAP_TIME_US 7
|
#define XTAL_32K_BOOTSTRAP_TIME_US 7
|
||||||
|
|
||||||
#define XTAL_32K_EXT_DAC_VAL 2
|
|
||||||
#define XTAL_32K_EXT_DRES_VAL 3
|
|
||||||
#define XTAL_32K_EXT_DBIAS_VAL 1
|
|
||||||
|
|
||||||
/* Delays for various clock sources to be enabled/switched.
|
|
||||||
* All values are in microseconds.
|
|
||||||
* TODO: some of these are excessive, and should be reduced.
|
|
||||||
*/
|
|
||||||
#define DELAY_PLL_DBIAS_RAISE 3
|
|
||||||
#define DELAY_PLL_ENABLE_WITH_150K 80
|
|
||||||
#define DELAY_PLL_ENABLE_WITH_32K 160
|
|
||||||
#define DELAY_FAST_CLK_SWITCH 3
|
|
||||||
#define DELAY_SLOW_CLK_SWITCH 300
|
|
||||||
#define DELAY_8M_ENABLE 50
|
|
||||||
|
|
||||||
/* Core voltage needs to be increased in two cases:
|
|
||||||
* 1. running at 240 MHz
|
|
||||||
* 2. running with 80MHz Flash frequency
|
|
||||||
*
|
|
||||||
* There is a record in efuse which indicates the proper voltage for these two cases.
|
|
||||||
*/
|
|
||||||
#define RTC_CNTL_DBIAS_HP_VOLT (RTC_CNTL_DBIAS_1V25 - efuse_ll_get_vol_level_hp_inv())
|
|
||||||
#ifdef CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
|
||||||
#define DIG_DBIAS_80M_160M RTC_CNTL_DBIAS_HP_VOLT
|
|
||||||
#else
|
|
||||||
#define DIG_DBIAS_80M_160M RTC_CNTL_DBIAS_1V10
|
|
||||||
#endif
|
|
||||||
#define DIG_DBIAS_240M RTC_CNTL_DBIAS_HP_VOLT
|
|
||||||
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
|
||||||
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
|
||||||
|
|
||||||
#define RTC_PLL_FREQ_320M 320
|
|
||||||
#define RTC_PLL_FREQ_480M 480
|
|
||||||
#define DELAY_RTC_CLK_SWITCH 5
|
|
||||||
|
|
||||||
static void rtc_clk_cpu_freq_to_8m(void);
|
static void rtc_clk_cpu_freq_to_8m(void);
|
||||||
static void rtc_clk_bbpll_disable(void);
|
|
||||||
static void rtc_clk_bbpll_enable(void);
|
|
||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz);
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz);
|
||||||
|
|
||||||
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
||||||
@@ -105,20 +37,12 @@ static uint32_t s_cur_pll_freq;
|
|||||||
|
|
||||||
static const char* TAG = "rtc_clk";
|
static const char* TAG = "rtc_clk";
|
||||||
|
|
||||||
static void rtc_clk_32k_enable_common(int dac, int dres, int dbias)
|
static void rtc_clk_32k_enable_common(clk_ll_xtal32k_enable_mode_t mode)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG,
|
CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG,
|
||||||
RTC_IO_X32P_RDE | RTC_IO_X32P_RUE | RTC_IO_X32N_RUE |
|
RTC_IO_X32P_RDE | RTC_IO_X32P_RUE | RTC_IO_X32N_RUE |
|
||||||
RTC_IO_X32N_RDE | RTC_IO_X32N_FUN_IE | RTC_IO_X32P_FUN_IE);
|
RTC_IO_X32N_RDE | RTC_IO_X32N_FUN_IE | RTC_IO_X32P_FUN_IE);
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL | RTC_IO_X32P_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL | RTC_IO_X32P_MUX_SEL);
|
||||||
/* Set the parameters of xtal
|
|
||||||
dac --> current
|
|
||||||
dres --> resistance
|
|
||||||
dbias --> bais voltage
|
|
||||||
*/
|
|
||||||
REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DAC_XTAL_32K, dac);
|
|
||||||
REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DRES_XTAL_32K, dres);
|
|
||||||
REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DBIAS_XTAL_32K, dbias);
|
|
||||||
|
|
||||||
#ifdef CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT
|
#ifdef CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||||
uint8_t chip_ver = efuse_hal_get_chip_revision();
|
uint8_t chip_ver = efuse_hal_get_chip_revision();
|
||||||
@@ -157,17 +81,17 @@ static void rtc_clk_32k_enable_common(int dac, int dres, int dbias)
|
|||||||
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_START_M);
|
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_START_M);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Power up external xtal */
|
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K_M);
|
clk_ll_xtal32k_enable(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_32k_enable(bool enable)
|
void rtc_clk_32k_enable(bool enable)
|
||||||
{
|
{
|
||||||
if (enable) {
|
if (enable) {
|
||||||
rtc_clk_32k_enable_common(XTAL_32K_DAC_VAL, XTAL_32K_DRES_VAL, XTAL_32K_DBIAS_VAL);
|
rtc_clk_32k_enable_common(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
|
||||||
} else {
|
} else {
|
||||||
|
clk_ll_xtal32k_disable();
|
||||||
/* Disable X32N and X32P pad drive external xtal */
|
/* Disable X32N and X32P pad drive external xtal */
|
||||||
CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K_M);
|
|
||||||
CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL | RTC_IO_X32P_MUX_SEL);
|
CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL | RTC_IO_X32P_MUX_SEL);
|
||||||
|
|
||||||
#ifdef CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT
|
#ifdef CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||||
@@ -191,7 +115,7 @@ void rtc_clk_32k_enable(bool enable)
|
|||||||
|
|
||||||
void rtc_clk_32k_enable_external(void)
|
void rtc_clk_32k_enable_external(void)
|
||||||
{
|
{
|
||||||
rtc_clk_32k_enable_common(XTAL_32K_EXT_DAC_VAL, XTAL_32K_EXT_DRES_VAL, XTAL_32K_EXT_DBIAS_VAL);
|
rtc_clk_32k_enable_common(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helping external 32kHz crystal to start up.
|
/* Helping external 32kHz crystal to start up.
|
||||||
@@ -201,88 +125,86 @@ void rtc_clk_32k_enable_external(void)
|
|||||||
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
||||||
{
|
{
|
||||||
if (cycle){
|
if (cycle){
|
||||||
const uint32_t pin_32 = 32;
|
esp_rom_gpio_pad_select_gpio(XTAL32K_P_GPIO_NUM);
|
||||||
const uint32_t pin_33 = 33;
|
esp_rom_gpio_pad_select_gpio(XTAL32K_N_GPIO_NUM);
|
||||||
|
gpio_ll_output_enable(&GPIO, XTAL32K_P_GPIO_NUM);
|
||||||
esp_rom_gpio_pad_select_gpio(pin_32);
|
gpio_ll_output_enable(&GPIO, XTAL32K_N_GPIO_NUM);
|
||||||
esp_rom_gpio_pad_select_gpio(pin_33);
|
gpio_ll_set_level(&GPIO, XTAL32K_P_GPIO_NUM, 1);
|
||||||
gpio_ll_output_enable(&GPIO, pin_32);
|
gpio_ll_set_level(&GPIO, XTAL32K_N_GPIO_NUM, 0);
|
||||||
gpio_ll_output_enable(&GPIO, pin_33);
|
|
||||||
gpio_ll_set_level(&GPIO, pin_32, 1);
|
|
||||||
gpio_ll_set_level(&GPIO, pin_33, 0);
|
|
||||||
|
|
||||||
const uint32_t delay_us = (1000000 / SOC_CLK_XTAL32K_FREQ_APPROX / 2);
|
const uint32_t delay_us = (1000000 / SOC_CLK_XTAL32K_FREQ_APPROX / 2);
|
||||||
while(cycle){
|
while (cycle) {
|
||||||
gpio_ll_set_level(&GPIO, pin_32, 1);
|
gpio_ll_set_level(&GPIO, XTAL32K_P_GPIO_NUM, 1);
|
||||||
gpio_ll_set_level(&GPIO, pin_33, 0);
|
gpio_ll_set_level(&GPIO, XTAL32K_N_GPIO_NUM, 0);
|
||||||
esp_rom_delay_us(delay_us);
|
esp_rom_delay_us(delay_us);
|
||||||
gpio_ll_set_level(&GPIO, pin_33, 1);
|
gpio_ll_set_level(&GPIO, XTAL32K_N_GPIO_NUM, 1);
|
||||||
gpio_ll_set_level(&GPIO, pin_32, 0);
|
gpio_ll_set_level(&GPIO, XTAL32K_P_GPIO_NUM, 0);
|
||||||
esp_rom_delay_us(delay_us);
|
esp_rom_delay_us(delay_us);
|
||||||
cycle--;
|
cycle--;
|
||||||
}
|
}
|
||||||
// disable pins
|
// disable pins
|
||||||
gpio_ll_output_disable(&GPIO, pin_32);
|
gpio_ll_output_disable(&GPIO, XTAL32K_P_GPIO_NUM);
|
||||||
gpio_ll_output_disable(&GPIO, pin_33);
|
gpio_ll_output_disable(&GPIO, XTAL32K_N_GPIO_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K);
|
clk_ll_xtal32k_disable();
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_RUE | RTC_IO_X32N_RDE);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_RUE | RTC_IO_X32N_RDE);
|
||||||
esp_rom_delay_us(XTAL_32K_BOOTSTRAP_TIME_US);
|
esp_rom_delay_us(XTAL_32K_BOOTSTRAP_TIME_US);
|
||||||
|
|
||||||
rtc_clk_32k_enable_common(XTAL_32K_BOOTSTRAP_DAC_VAL,
|
rtc_clk_32k_enable_common(CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP);
|
||||||
XTAL_32K_BOOTSTRAP_DRES_VAL, XTAL_32K_BOOTSTRAP_DBIAS_VAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_32k_enabled(void)
|
bool rtc_clk_32k_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K) != 0;
|
return clk_ll_xtal32k_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
||||||
{
|
{
|
||||||
if (clk_8m_en) {
|
if (clk_8m_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_enable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
|
||||||
if (d256_en) {
|
if (d256_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_enable();
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_disable();
|
||||||
}
|
}
|
||||||
esp_rom_delay_us(DELAY_8M_ENABLE);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_disable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8m_enabled(void)
|
bool rtc_clk_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
return clk_ll_rc_fast_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8md256_enabled(void)
|
bool rtc_clk_8md256_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
return clk_ll_rc_fast_d256_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_apll_enable(bool enable)
|
void rtc_clk_apll_enable(bool enable)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1);
|
if (enable) {
|
||||||
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0);
|
clk_ll_apll_enable();
|
||||||
|
|
||||||
if (!enable &&
|
|
||||||
REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL) != RTC_CNTL_SOC_CLK_SEL_PLL) {
|
|
||||||
REG_SET_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD);
|
|
||||||
} else {
|
} else {
|
||||||
REG_CLR_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD);
|
clk_ll_apll_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enable && (clk_ll_cpu_get_src() != SOC_CPU_CLK_SRC_PLL)) {
|
||||||
|
// if apll and bbpll are both not in use, then can also power down the internal I2C bus
|
||||||
|
// this power down affects most of the analog peripherals
|
||||||
|
clk_ll_i2c_pd();
|
||||||
|
} else {
|
||||||
|
clk_ll_i2c_pu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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_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();
|
uint32_t xtal_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
if (rtc_xtal_freq == 0) {
|
if (xtal_freq_mhz == 0) {
|
||||||
// xtal_freq has not set yet
|
// xtal_freq has not set yet
|
||||||
ESP_HW_LOGE(TAG, "Get xtal clock frequency failed, it has not been set yet");
|
ESP_HW_LOGE(TAG, "Get xtal clock frequency failed, it has not been set yet");
|
||||||
abort();
|
abort();
|
||||||
@@ -316,9 +238,9 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// sdm2 = (int)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4
|
// sdm2 = (int)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4
|
||||||
sdm2 = (int)(((o_div + 2) * 2 * freq) / (rtc_xtal_freq * 1000000)) - 4;
|
sdm2 = (int)(((o_div + 2) * 2 * freq) / (xtal_freq_mhz * MHZ)) - 4;
|
||||||
// numrator = (((o_div + 2) * 2) * apll_freq / xtal_freq) - 4 - sdm2
|
// numrator = (((o_div + 2) * 2) * apll_freq / xtal_freq) - 4 - sdm2
|
||||||
float numrator = (((o_div + 2) * 2 * freq) / ((float)rtc_xtal_freq * 1000000)) - 4 - sdm2;
|
float numrator = (((o_div + 2) * 2 * freq) / ((float)xtal_freq_mhz * 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 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) {
|
if (numrator > 1.0 - (1.0 / 65536.0) / 2.0) {
|
||||||
sdm2++;
|
sdm2++;
|
||||||
@@ -330,7 +252,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
|
|||||||
// Get the closest sdm0
|
// Get the closest sdm0
|
||||||
sdm0 = (int)(numrator * 65536.0 + 0.5) % 256;
|
sdm0 = (int)(numrator * 65536.0 + 0.5) % 256;
|
||||||
}
|
}
|
||||||
uint32_t real_freq = (uint32_t)(rtc_xtal_freq * 1000000 * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) / (((float)o_div + 2) * 2));
|
uint32_t real_freq = (uint32_t)(xtal_freq_mhz * MHZ * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) / (((float)o_div + 2) * 2));
|
||||||
*_o_div = o_div;
|
*_o_div = o_div;
|
||||||
*_sdm0 = sdm0;
|
*_sdm0 = sdm0;
|
||||||
*_sdm1 = sdm1;
|
*_sdm1 = sdm1;
|
||||||
@@ -340,168 +262,90 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
|
|||||||
|
|
||||||
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
|
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
|
||||||
{
|
{
|
||||||
uint8_t sdm_stop_val_2 = APLL_SDM_STOP_VAL_2_REV1;
|
bool is_rev0 = (efuse_ll_get_chip_ver_rev1() == 0);
|
||||||
uint32_t is_rev0 = (efuse_ll_get_chip_ver_rev1() == 0);
|
clk_ll_apll_set_config(is_rev0, o_div, sdm0, sdm1, sdm2);
|
||||||
if (is_rev0) {
|
|
||||||
sdm0 = 0;
|
|
||||||
sdm1 = 0;
|
|
||||||
sdm_stop_val_2 = APLL_SDM_STOP_VAL_2_REV0;
|
|
||||||
}
|
|
||||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2);
|
|
||||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0);
|
|
||||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1);
|
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_1);
|
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, sdm_stop_val_2);
|
|
||||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
|
|
||||||
|
|
||||||
/* calibration */
|
/* calibration */
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_1);
|
clk_ll_apll_set_calibration();
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_2);
|
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_3);
|
|
||||||
|
|
||||||
/* wait for calibration end */
|
/* wait for calibration end */
|
||||||
while (!(REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_CAL_END))) {
|
while (!clk_ll_apll_calibration_is_done()) {
|
||||||
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
|
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
|
||||||
esp_rom_delay_us(1);
|
esp_rom_delay_us(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t slow_freq)
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
|
clk_ll_rtc_slow_set_src(clk_src);
|
||||||
|
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN,
|
// The logic should be moved to BT driver
|
||||||
(slow_freq == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? 1 : 0);
|
if (clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||||
|
clk_ll_xtal32k_digi_enable();
|
||||||
|
} else {
|
||||||
|
clk_ll_xtal32k_digi_disable();
|
||||||
|
}
|
||||||
|
|
||||||
esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
return clk_ll_rtc_slow_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||||
{
|
{
|
||||||
switch(rtc_clk_slow_src_get()) {
|
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_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_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
||||||
|
default: return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t fast_freq)
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
|
clk_ll_rtc_fast_set_src(clk_src);
|
||||||
esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
return clk_ll_rtc_fast_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
static void rtc_clk_bbpll_disable(void)
|
||||||
{
|
{
|
||||||
uint8_t div_ref;
|
clk_ll_bbpll_disable();
|
||||||
uint8_t div7_0;
|
s_cur_pll_freq = 0;
|
||||||
uint8_t div10_8;
|
|
||||||
uint8_t lref;
|
|
||||||
uint8_t dcur;
|
|
||||||
uint8_t bw;
|
|
||||||
|
|
||||||
if (pll_freq == RTC_PLL_FREQ_320M) {
|
// if apll is under force power down, then can also power down the internal I2C bus
|
||||||
/* Raise the voltage, if needed */
|
// this power down affects most of the analog peripherals
|
||||||
|
if (clk_ll_apll_is_fpd()) {
|
||||||
|
clk_ll_i2c_pd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtc_clk_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
clk_ll_i2c_pu();
|
||||||
|
clk_ll_bbpll_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
||||||
|
{
|
||||||
|
/* Raise the voltage */
|
||||||
|
if (pll_freq == CLK_LL_PLL_320M_FREQ_MHZ) {
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_80M_160M);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_80M_160M);
|
||||||
/* Configure 320M PLL */
|
} else { // CLK_LL_PLL_480M_FREQ_MHZ
|
||||||
switch (xtal_freq) {
|
|
||||||
case RTC_XTAL_FREQ_40M:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 32;
|
|
||||||
div10_8 = 0;
|
|
||||||
lref = 0;
|
|
||||||
dcur = 6;
|
|
||||||
bw = 3;
|
|
||||||
break;
|
|
||||||
case RTC_XTAL_FREQ_26M:
|
|
||||||
div_ref = 12;
|
|
||||||
div7_0 = 224;
|
|
||||||
div10_8 = 4;
|
|
||||||
lref = 1;
|
|
||||||
dcur = 0;
|
|
||||||
bw = 1;
|
|
||||||
break;
|
|
||||||
case RTC_XTAL_FREQ_24M:
|
|
||||||
div_ref = 11;
|
|
||||||
div7_0 = 224;
|
|
||||||
div10_8 = 4;
|
|
||||||
lref = 1;
|
|
||||||
dcur = 0;
|
|
||||||
bw = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
div_ref = 12;
|
|
||||||
div7_0 = 224;
|
|
||||||
div10_8 = 4;
|
|
||||||
lref = 0;
|
|
||||||
dcur = 0;
|
|
||||||
bw = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_ENDIV5, BBPLL_ENDIV5_VAL_320M);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, BBPLL_BBADC_DSMP_VAL_320M);
|
|
||||||
} else {
|
|
||||||
/* Raise the voltage */
|
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_240M);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_240M);
|
||||||
esp_rom_delay_us(DELAY_PLL_DBIAS_RAISE);
|
esp_rom_delay_us(SOC_DELAY_PLL_DBIAS_RAISE);
|
||||||
/* Configure 480M PLL */
|
|
||||||
switch (xtal_freq) {
|
|
||||||
case RTC_XTAL_FREQ_40M:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 28;
|
|
||||||
div10_8 = 0;
|
|
||||||
lref = 0;
|
|
||||||
dcur = 6;
|
|
||||||
bw = 3;
|
|
||||||
break;
|
|
||||||
case RTC_XTAL_FREQ_26M:
|
|
||||||
div_ref = 12;
|
|
||||||
div7_0 = 144;
|
|
||||||
div10_8 = 4;
|
|
||||||
lref = 1;
|
|
||||||
dcur = 0;
|
|
||||||
bw = 1;
|
|
||||||
break;
|
|
||||||
case RTC_XTAL_FREQ_24M:
|
|
||||||
div_ref = 11;
|
|
||||||
div7_0 = 144;
|
|
||||||
div10_8 = 4;
|
|
||||||
lref = 1;
|
|
||||||
dcur = 0;
|
|
||||||
bw = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
div_ref = 12;
|
|
||||||
div7_0 = 224;
|
|
||||||
div10_8 = 4;
|
|
||||||
lref = 0;
|
|
||||||
dcur = 0;
|
|
||||||
bw = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_ENDIV5, BBPLL_ENDIV5_VAL_480M);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, BBPLL_BBADC_DSMP_VAL_480M);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t i2c_bbpll_lref = (lref << 7) | (div10_8 << 4) | (div_ref);
|
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||||
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
uint32_t delay_pll_en = (clk_ll_rtc_slow_get_src() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ?
|
||||||
uint8_t i2c_bbpll_dcur = (bw << 6) | dcur;
|
SOC_DELAY_PLL_ENABLE_WITH_150K : SOC_DELAY_PLL_ENABLE_WITH_32K;
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_LREF, i2c_bbpll_lref);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
|
||||||
uint32_t delay_pll_en = (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ?
|
|
||||||
DELAY_PLL_ENABLE_WITH_150K : DELAY_PLL_ENABLE_WITH_32K;
|
|
||||||
esp_rom_delay_us(delay_pll_en);
|
esp_rom_delay_us(delay_pll_en);
|
||||||
s_cur_pll_freq = pll_freq;
|
s_cur_pll_freq = pll_freq;
|
||||||
}
|
}
|
||||||
@@ -513,58 +357,29 @@ void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
|||||||
{
|
{
|
||||||
ets_update_cpu_frequency(freq);
|
ets_update_cpu_frequency(freq);
|
||||||
/* set divider from XTAL to APB clock */
|
/* set divider from XTAL to APB clock */
|
||||||
REG_SET_FIELD(SYSCON_SYSCLK_CONF_REG, SYSCON_PRE_DIV_CNT, div - 1);
|
clk_ll_cpu_set_divider(div);
|
||||||
/* adjust ref_tick */
|
/* adjust ref_tick */
|
||||||
REG_WRITE(SYSCON_XTAL_TICK_CONF_REG, freq * MHZ / REF_CLK_FREQ - 1);
|
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_XTAL, freq);
|
||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL, RTC_CNTL_SOC_CLK_SEL_XTL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||||
rtc_clk_apb_freq_update(freq * MHZ);
|
rtc_clk_apb_freq_update(freq * MHZ);
|
||||||
/* lower the voltage */
|
/* lower the voltage */
|
||||||
if (freq <= 2) {
|
int dbias = (freq <= 2) ? DIG_DBIAS_2M : DIG_DBIAS_XTAL;
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_2M);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
|
||||||
} else {
|
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_cpu_freq_to_8m(void)
|
static void rtc_clk_cpu_freq_to_8m(void)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(8);
|
ets_update_cpu_frequency(8);
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
|
||||||
REG_SET_FIELD(SYSCON_SYSCLK_CONF_REG, SYSCON_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL, RTC_CNTL_SOC_CLK_SEL_8M);
|
/* adjust ref_tick */
|
||||||
|
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_RC_FAST, 8);
|
||||||
|
/* switch clock source */
|
||||||
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||||
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_disable(void)
|
|
||||||
{
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
|
|
||||||
RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD |
|
|
||||||
RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
s_cur_pll_freq = 0;
|
|
||||||
|
|
||||||
/* is APLL under force power down? */
|
|
||||||
uint32_t apll_fpd = REG_GET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
|
||||||
if (apll_fpd) {
|
|
||||||
/* then also power down the internal I2C bus */
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rtc_clk_bbpll_enable(void)
|
|
||||||
{
|
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
|
|
||||||
RTC_CNTL_BIAS_I2C_FORCE_PD | RTC_CNTL_BB_I2C_FORCE_PD |
|
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
|
|
||||||
/* reset BBPLL configuration */
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_IR_CAL_DELAY, BBPLL_IR_CAL_DELAY_VAL);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, BBPLL_IR_CAL_EXT_CAP_VAL);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_ENB_FCAL, BBPLL_OC_ENB_FCAL_VAL);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_ENB_VCON, BBPLL_OC_ENB_VCON_VAL);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_BBADC_CAL_7_0, BBPLL_BBADC_CAL_7_0_VAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
|
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
|
||||||
* PLL must already be enabled.
|
* PLL must already be enabled.
|
||||||
@@ -572,22 +387,13 @@ static void rtc_clk_bbpll_enable(void)
|
|||||||
*/
|
*/
|
||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||||
{
|
{
|
||||||
int dbias = DIG_DBIAS_80M_160M;
|
int dbias = (cpu_freq_mhz == 240) ? DIG_DBIAS_240M : DIG_DBIAS_80M_160M;
|
||||||
int per_conf = DPORT_CPUPERIOD_SEL_80;
|
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
||||||
if (cpu_freq_mhz == 80) {
|
|
||||||
/* nothing to do */
|
|
||||||
} else if (cpu_freq_mhz == 160) {
|
|
||||||
per_conf = DPORT_CPUPERIOD_SEL_160;
|
|
||||||
} else if (cpu_freq_mhz == 240) {
|
|
||||||
dbias = DIG_DBIAS_240M;
|
|
||||||
per_conf = DPORT_CPUPERIOD_SEL_240;
|
|
||||||
} else {
|
|
||||||
ESP_HW_LOGE(TAG, "invalid frequency");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
DPORT_REG_WRITE(DPORT_CPU_PER_CONF_REG, per_conf);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL, RTC_CNTL_SOC_CLK_SEL_PLL);
|
/* adjust ref_tick */
|
||||||
|
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_PLL, cpu_freq_mhz);
|
||||||
|
/* switch clock source */
|
||||||
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||||
rtc_clk_apb_freq_update(80 * MHZ);
|
rtc_clk_apb_freq_update(80 * MHZ);
|
||||||
ets_update_cpu_frequency(cpu_freq_mhz);
|
ets_update_cpu_frequency(cpu_freq_mhz);
|
||||||
rtc_clk_wait_for_slow_cycle();
|
rtc_clk_wait_for_slow_cycle();
|
||||||
@@ -595,7 +401,7 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_xtal(void)
|
void rtc_clk_cpu_freq_set_xtal(void)
|
||||||
{
|
{
|
||||||
int freq_mhz = (int) rtc_clk_xtal_freq_get();
|
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||||
|
|
||||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||||
rtc_clk_wait_for_slow_cycle();
|
rtc_clk_wait_for_slow_cycle();
|
||||||
@@ -623,17 +429,17 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* ou
|
|||||||
} else if (freq_mhz == 80) {
|
} else if (freq_mhz == 80) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_320M;
|
source_freq_mhz = CLK_LL_PLL_320M_FREQ_MHZ;
|
||||||
divider = 4;
|
divider = 4;
|
||||||
} else if (freq_mhz == 160) {
|
} else if (freq_mhz == 160) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_320M;
|
source_freq_mhz = CLK_LL_PLL_320M_FREQ_MHZ;
|
||||||
divider = 2;
|
divider = 2;
|
||||||
} else if (freq_mhz == 240) {
|
} else if (freq_mhz == 240) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 2;
|
divider = 2;
|
||||||
} else {
|
} else {
|
||||||
// unsupported frequency
|
// unsupported frequency
|
||||||
@@ -651,14 +457,15 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* ou
|
|||||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t* config)
|
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t* config)
|
||||||
{
|
{
|
||||||
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL);
|
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||||
if (soc_clk_sel != RTC_CNTL_SOC_CLK_SEL_XTL) {
|
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_XTAL) {
|
||||||
rtc_clk_cpu_freq_to_xtal(xtal_freq, 1);
|
rtc_clk_cpu_freq_to_xtal(xtal_freq, 1);
|
||||||
rtc_clk_wait_for_slow_cycle();
|
rtc_clk_wait_for_slow_cycle();
|
||||||
}
|
}
|
||||||
if (soc_clk_sel == RTC_CNTL_SOC_CLK_SEL_PLL) {
|
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) {
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||||
if (config->div > 1) {
|
if (config->div > 1) {
|
||||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||||
@@ -675,50 +482,43 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t* config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t* out_config)
|
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t* out_config)
|
||||||
{
|
{
|
||||||
soc_cpu_clk_src_t source;
|
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||||
uint32_t source_freq_mhz;
|
uint32_t source_freq_mhz;
|
||||||
uint32_t div;
|
uint32_t div;
|
||||||
uint32_t freq_mhz;
|
uint32_t freq_mhz;
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL);
|
switch (source) {
|
||||||
switch (soc_clk_sel) {
|
case SOC_CPU_CLK_SRC_XTAL: {
|
||||||
case RTC_CNTL_SOC_CLK_SEL_XTL: {
|
div = clk_ll_cpu_get_divider();
|
||||||
source = SOC_CPU_CLK_SRC_XTAL;
|
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
|
||||||
div = REG_GET_FIELD(SYSCON_SYSCLK_CONF_REG, SYSCON_PRE_DIV_CNT) + 1;
|
freq_mhz = source_freq_mhz / div;
|
||||||
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
|
}
|
||||||
freq_mhz = source_freq_mhz / div;
|
break;
|
||||||
}
|
case SOC_CPU_CLK_SRC_PLL: {
|
||||||
break;
|
freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
|
||||||
case RTC_CNTL_SOC_CLK_SEL_PLL: {
|
if (freq_mhz == CLK_LL_PLL_80M_FREQ_MHZ) {
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source_freq_mhz = CLK_LL_PLL_320M_FREQ_MHZ;
|
||||||
uint32_t cpuperiod_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL);
|
div = 4;
|
||||||
if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80) {
|
} else if (freq_mhz == CLK_LL_PLL_160M_FREQ_MHZ) {
|
||||||
source_freq_mhz = RTC_PLL_FREQ_320M;
|
source_freq_mhz = CLK_LL_PLL_320M_FREQ_MHZ;
|
||||||
div = 4;
|
div = 2;
|
||||||
freq_mhz = 80;
|
} else if (freq_mhz == CLK_LL_PLL_240M_FREQ_MHZ) {
|
||||||
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160) {
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_320M;
|
div = 2;
|
||||||
div = 2;
|
} else {
|
||||||
freq_mhz = 160;
|
|
||||||
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_240) {
|
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
|
||||||
div = 2;
|
|
||||||
freq_mhz = 240;
|
|
||||||
} else {
|
|
||||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RTC_CNTL_SOC_CLK_SEL_8M:
|
|
||||||
source = SOC_CPU_CLK_SRC_RC_FAST;
|
|
||||||
source_freq_mhz = 8;
|
|
||||||
div = 1;
|
|
||||||
freq_mhz = source_freq_mhz;
|
|
||||||
break;
|
|
||||||
case RTC_CNTL_SOC_CLK_SEL_APLL:
|
|
||||||
default:
|
|
||||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||||
abort();
|
abort();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
source_freq_mhz = 8;
|
||||||
|
div = 1;
|
||||||
|
freq_mhz = source_freq_mhz;
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_APLL:
|
||||||
|
default:
|
||||||
|
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
*out_config = (rtc_cpu_freq_config_t) {
|
*out_config = (rtc_cpu_freq_config_t) {
|
||||||
.source = source,
|
.source = source,
|
||||||
@@ -743,26 +543,21 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t* config)
|
|||||||
|
|
||||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||||
{
|
{
|
||||||
/* We may have already written XTAL value into RTC_XTAL_FREQ_REG */
|
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||||
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
if (xtal_freq_mhz == 0) {
|
||||||
if (!clk_val_is_valid(xtal_freq_reg)) {
|
|
||||||
return RTC_XTAL_FREQ_AUTO;
|
return RTC_XTAL_FREQ_AUTO;
|
||||||
}
|
}
|
||||||
return reg_val_to_clk_val(xtal_freq_reg & ~RTC_DISABLE_ROM_LOG);
|
return (rtc_xtal_freq_t)xtal_freq_mhz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
||||||
{
|
{
|
||||||
uint32_t reg = READ_PERI_REG(RTC_XTAL_FREQ_REG) & RTC_DISABLE_ROM_LOG;
|
clk_ll_xtal_store_freq_mhz((uint32_t)xtal_freq);
|
||||||
if (reg == RTC_DISABLE_ROM_LOG) {
|
|
||||||
xtal_freq |= 1;
|
|
||||||
}
|
|
||||||
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, clk_val_to_reg_val(xtal_freq));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_APB_FREQ_REG, clk_val_to_reg_val(apb_freq >> 12));
|
clk_ll_apb_store_freq_hz(apb_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_apb_freq_get(void)
|
uint32_t rtc_clk_apb_freq_get(void)
|
||||||
@@ -770,28 +565,24 @@ uint32_t rtc_clk_apb_freq_get(void)
|
|||||||
#if CONFIG_IDF_ENV_FPGA
|
#if CONFIG_IDF_ENV_FPGA
|
||||||
return CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ * MHZ;
|
return CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ * MHZ;
|
||||||
#endif // CONFIG_IDF_ENV_FPGA
|
#endif // CONFIG_IDF_ENV_FPGA
|
||||||
uint32_t freq_hz = reg_val_to_clk_val(READ_PERI_REG(RTC_APB_FREQ_REG)) << 12;
|
return clk_ll_apb_load_freq_hz();
|
||||||
// round to the nearest MHz
|
|
||||||
freq_hz += MHZ / 2;
|
|
||||||
uint32_t remainder = freq_hz % MHZ;
|
|
||||||
return freq_hz - remainder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_enable(void)
|
void rtc_dig_clk8m_enable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_enable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_disable(void)
|
void rtc_dig_clk8m_disable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_disable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_dig_8m_enabled(void)
|
bool rtc_dig_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
return clk_ll_rc_fast_digi_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Name used in libphy.a:phy_chip_v7.o
|
/* Name used in libphy.a:phy_chip_v7.o
|
||||||
|
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define MHZ (1000000)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
|
||||||
|
|
||||||
/* Values of RTC_XTAL_FREQ_REG and RTC_APB_FREQ_REG are stored as two copies in
|
|
||||||
* lower and upper 16-bit halves. These are the routines to work with such a
|
|
||||||
* representation.
|
|
||||||
*/
|
|
||||||
static inline bool clk_val_is_valid(uint32_t val) {
|
|
||||||
return (val & 0xffff) == ((val >> 16) & 0xffff) &&
|
|
||||||
val != 0 &&
|
|
||||||
val != UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t reg_val_to_clk_val(uint32_t val) {
|
|
||||||
return val & UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t clk_val_to_reg_val(uint32_t val) {
|
|
||||||
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@@ -14,12 +14,11 @@
|
|||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/sens_periph.h"
|
#include "soc/sens_periph.h"
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "hal/cpu_hal.h"
|
#include "hal/cpu_hal.h"
|
||||||
#include "regi2c_ctrl.h"
|
#include "hal/clk_tree_ll.h"
|
||||||
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
|
|
||||||
/* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
|
/* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
|
||||||
* 10 cycles will take approximately 300 microseconds.
|
* 10 cycles will take approximately 300 microseconds.
|
||||||
@@ -27,6 +26,7 @@
|
|||||||
#define XTAL_FREQ_EST_CYCLES 10
|
#define XTAL_FREQ_EST_CYCLES 10
|
||||||
|
|
||||||
static rtc_xtal_freq_t rtc_clk_xtal_freq_estimate(void);
|
static rtc_xtal_freq_t rtc_clk_xtal_freq_estimate(void);
|
||||||
|
extern void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
||||||
|
|
||||||
static const char* TAG = "rtc_clk_init";
|
static const char* TAG = "rtc_clk_init";
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
* PLL is configured for 480M, but it takes less time to switch to 40M and
|
* PLL is configured for 480M, but it takes less time to switch to 40M and
|
||||||
* run the following code than querying the PLL does.
|
* run the following code than querying the PLL does.
|
||||||
*/
|
*/
|
||||||
if (REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL) == RTC_CNTL_SOC_CLK_SEL_PLL) {
|
if (clk_ll_cpu_get_src() == SOC_CPU_CLK_SRC_PLL) {
|
||||||
/* We don't know actual XTAL frequency yet, assume 40MHz.
|
/* We don't know actual XTAL frequency yet, assume 40MHz.
|
||||||
* REF_TICK divider will be corrected below, once XTAL frequency is
|
* REF_TICK divider will be corrected below, once XTAL frequency is
|
||||||
* determined.
|
* determined.
|
||||||
@@ -63,18 +63,22 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
|
||||||
|
|
||||||
/* Configure 8M clock division */
|
/* Configure 8M clock division */
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, cfg.clk_8m_div);
|
clk_ll_rc_fast_set_divider(cfg.clk_8m_div + 1);
|
||||||
|
|
||||||
|
/* Reset (disable) i2c internal bus for all regi2c registers */
|
||||||
|
regi2c_ctrl_ll_i2c_reset(); // TODO: This should be move out from rtc_clk_init
|
||||||
/* Enable the internal bus used to configure PLLs */
|
/* Enable the internal bus used to configure PLLs */
|
||||||
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
regi2c_ctrl_ll_i2c_bbpll_enable(); // TODO: This should be moved to bbpll_set_config
|
||||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_APLL_M | I2C_BBPLL_M);
|
regi2c_ctrl_ll_i2c_apll_enable(); // TODO: This should be moved to apll_set_config
|
||||||
|
|
||||||
/* Estimate XTAL frequency */
|
/* Estimate XTAL frequency */
|
||||||
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
rtc_xtal_freq_t configured_xtal_freq = cfg.xtal_freq;
|
||||||
if (xtal_freq == RTC_XTAL_FREQ_AUTO) {
|
rtc_xtal_freq_t stored_xtal_freq = rtc_clk_xtal_freq_get(); // read the xtal freq value from RTC storage register
|
||||||
if (clk_val_is_valid(READ_PERI_REG(RTC_XTAL_FREQ_REG))) {
|
rtc_xtal_freq_t xtal_freq = configured_xtal_freq;
|
||||||
|
if (configured_xtal_freq == RTC_XTAL_FREQ_AUTO) {
|
||||||
|
if (stored_xtal_freq != RTC_XTAL_FREQ_AUTO) {
|
||||||
/* XTAL frequency has already been set, use existing value */
|
/* XTAL frequency has already been set, use existing value */
|
||||||
xtal_freq = rtc_clk_xtal_freq_get();
|
xtal_freq = stored_xtal_freq;
|
||||||
} else {
|
} else {
|
||||||
/* Not set yet, estimate XTAL frequency based on RTC_FAST_CLK */
|
/* Not set yet, estimate XTAL frequency based on RTC_FAST_CLK */
|
||||||
xtal_freq = rtc_clk_xtal_freq_estimate();
|
xtal_freq = rtc_clk_xtal_freq_estimate();
|
||||||
@@ -83,16 +87,16 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
xtal_freq = RTC_XTAL_FREQ_26M;
|
xtal_freq = RTC_XTAL_FREQ_26M;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!clk_val_is_valid(READ_PERI_REG(RTC_XTAL_FREQ_REG))) {
|
} else if (stored_xtal_freq == RTC_XTAL_FREQ_AUTO) {
|
||||||
/* Exact frequency was set in sdkconfig, but still warn if autodetected
|
/* Exact frequency was set in sdkconfig, but still warn if autodetected
|
||||||
* frequency is different. If autodetection failed, worst case we get a
|
* frequency is different. If autodetection failed, worst case we get a
|
||||||
* bit of garbage output.
|
* bit of garbage output.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rtc_xtal_freq_t est_xtal_freq = rtc_clk_xtal_freq_estimate();
|
rtc_xtal_freq_t est_xtal_freq = rtc_clk_xtal_freq_estimate();
|
||||||
if (est_xtal_freq != xtal_freq) {
|
if (est_xtal_freq != configured_xtal_freq) {
|
||||||
ESP_HW_LOGW(TAG, "Possibly invalid CONFIG_ESP32_XTAL_FREQ setting (%dMHz). Detected %d MHz.",
|
ESP_HW_LOGW(TAG, "Possibly invalid CONFIG_ESP32_XTAL_FREQ setting (%dMHz). Detected %d MHz.",
|
||||||
xtal_freq, est_xtal_freq);
|
configured_xtal_freq, est_xtal_freq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
esp_rom_uart_tx_wait_idle(0);
|
esp_rom_uart_tx_wait_idle(0);
|
||||||
@@ -112,8 +116,10 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
rtc_clk_cpu_freq_set_config(&new_config);
|
rtc_clk_cpu_freq_set_config(&new_config);
|
||||||
|
|
||||||
/* Configure REF_TICK */
|
/* Configure REF_TICK */
|
||||||
REG_WRITE(SYSCON_XTAL_TICK_CONF_REG, xtal_freq - 1);
|
// Initialize it in the bootloader stage, but it is not a must to do here
|
||||||
REG_WRITE(SYSCON_PLL_TICK_CONF_REG, APB_CLK_FREQ / MHZ - 1); /* Under PLL, APB frequency is always 80MHz */
|
// REF_TICK divider value always gets updated when switching cpu clock source
|
||||||
|
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_XTAL, xtal_freq);
|
||||||
|
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_PLL, new_config.freq_mhz);
|
||||||
|
|
||||||
/* Re-calculate the ccount to make time calculation correct. */
|
/* Re-calculate the ccount to make time calculation correct. */
|
||||||
cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before );
|
cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before );
|
||||||
|
@@ -6,12 +6,11 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/timer_periph.h"
|
#include "soc/timer_periph.h"
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
|
|
||||||
#define MHZ (1000000)
|
|
||||||
|
|
||||||
static const char* TAG = "rtc_time";
|
static const char* TAG = "rtc_time";
|
||||||
|
|
||||||
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||||
@@ -36,13 +35,13 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
|||||||
{
|
{
|
||||||
assert(slowclk_cycles < 32767);
|
assert(slowclk_cycles < 32767);
|
||||||
/* Enable requested clock (150k clock is always on) */
|
/* Enable requested clock (150k clock is always on) */
|
||||||
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
|
||||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
|
clk_ll_xtal32k_digi_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cal_clk == RTC_CAL_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_enable();
|
||||||
}
|
}
|
||||||
/* Prepare calibration */
|
/* Prepare calibration */
|
||||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
|
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
|
||||||
@@ -88,10 +87,13 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
|||||||
esp_rom_delay_us(1);
|
esp_rom_delay_us(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
|
/* 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_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_disable();
|
||||||
}
|
}
|
||||||
if (timeout_us == 0) {
|
if (timeout_us == 0) {
|
||||||
/* timed out waiting for calibration */
|
/* timed out waiting for calibration */
|
||||||
@@ -139,7 +141,7 @@ uint64_t rtc_time_get(void)
|
|||||||
while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
|
while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
|
||||||
esp_rom_delay_us(1); // might take 1 RTC slowclk period, don't flood RTC bus
|
esp_rom_delay_us(1); // might take 1 RTC slowclk period, don't flood RTC bus
|
||||||
if (attempts) {
|
if (attempts) {
|
||||||
if (--attempts == 0 && REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN)) {
|
if (--attempts == 0 && clk_ll_xtal32k_digi_is_enabled()) {
|
||||||
ESP_HW_LOGE(TAG, "rtc_time_get() 32kHz xtal has been stopped");
|
ESP_HW_LOGE(TAG, "rtc_time_get() 32kHz xtal has been stopped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +167,7 @@ void rtc_clk_wait_for_slow_cycle(void)
|
|||||||
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
|
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
|
||||||
esp_rom_delay_us(1);
|
esp_rom_delay_us(1);
|
||||||
if (attempts) {
|
if (attempts) {
|
||||||
if (--attempts == 0 && REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN)) {
|
if (--attempts == 0 && clk_ll_xtal32k_digi_is_enabled()) {
|
||||||
ESP_HW_LOGE(TAG, "32kHz xtal has been stopped");
|
ESP_HW_LOGE(TAG, "32kHz xtal has been stopped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,80 +15,75 @@
|
|||||||
#include "esp32c2/rom/uart.h"
|
#include "esp32c2/rom/uart.h"
|
||||||
#include "esp32c2/rom/gpio.h"
|
#include "esp32c2/rom/gpio.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "hal/gpio_ll.h"
|
||||||
#include "soc/efuse_reg.h"
|
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "soc/system_reg.h"
|
|
||||||
#include "soc/io_mux_reg.h"
|
#include "soc/io_mux_reg.h"
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "regi2c_ctrl.h"
|
|
||||||
#include "regi2c_bbpll.h"
|
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk";
|
static const char *TAG = "rtc_clk";
|
||||||
|
|
||||||
#define RTC_PLL_FREQ_480M 480
|
// Current PLL frequency, in 480MHZ. Zero if PLL is not enabled.
|
||||||
#define DELAY_RTC_CLK_SWITCH 5
|
|
||||||
|
|
||||||
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
|
||||||
static int s_cur_pll_freq;
|
static int s_cur_pll_freq;
|
||||||
|
|
||||||
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
||||||
static void rtc_clk_cpu_freq_to_8m(void);
|
static void rtc_clk_cpu_freq_to_8m(void);
|
||||||
|
|
||||||
void rtc_clk_32k_enable_external(void)
|
void rtc_clk_32k_enable_external(void)
|
||||||
{
|
{
|
||||||
REG_SET_BIT(PERIPHS_IO_MUX_XTAL_32K_P_U, FUN_IE);
|
gpio_ll_input_enable(&GPIO, EXT_OSC_SLOW_GPIO_NUM);
|
||||||
REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, RTC_CNTL_GPIO_PIN0_HOLD);
|
gpio_ll_hold_en(&GPIO, EXT_OSC_SLOW_GPIO_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
||||||
{
|
{
|
||||||
if (clk_8m_en) {
|
if (clk_8m_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_enable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
|
||||||
esp_rom_delay_us(DELAY_8M_ENABLE);
|
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_disable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
|
||||||
}
|
}
|
||||||
/* d256 should be independent configured with 8M
|
/* d256 should be independent configured with 8M
|
||||||
* Maybe we can split this function into 8m and dmd256
|
* Maybe we can split this function into 8m and dmd256
|
||||||
*/
|
*/
|
||||||
if (d256_en) {
|
if (d256_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_enable();
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8m_enabled(void)
|
bool rtc_clk_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
return clk_ll_rc_fast_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8md256_enabled(void)
|
bool rtc_clk_8md256_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
return clk_ll_rc_fast_d256_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t slow_freq)
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
|
clk_ll_rtc_slow_set_src(clk_src);
|
||||||
|
|
||||||
/* Why we need to connect this clock to digital?
|
/* Why we need to connect this clock to digital?
|
||||||
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
|
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
|
||||||
*/
|
*/
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN,
|
if (clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
|
||||||
(slow_freq == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? 1 : 0);
|
clk_ll_xtal32k_digi_enable();
|
||||||
|
} else {
|
||||||
|
clk_ll_xtal32k_digi_disable();
|
||||||
|
}
|
||||||
|
|
||||||
esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
return clk_ll_rtc_slow_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||||
@@ -97,60 +92,39 @@ uint32_t rtc_clk_slow_freq_get_hz(void)
|
|||||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
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_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;
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
||||||
|
default: return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t fast_freq)
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
|
clk_ll_rtc_fast_set_src(clk_src);
|
||||||
esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
return clk_ll_rtc_fast_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_disable(void)
|
static void rtc_clk_bbpll_disable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_disable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
s_cur_pll_freq = 0;
|
s_cur_pll_freq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_enable(void)
|
static void rtc_clk_bbpll_enable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_enable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
||||||
{
|
{
|
||||||
(void) xtal_freq;
|
/* Digital part */
|
||||||
// ESP32-C2 only support 40M XTAL, all the parameters are given as 40M XTAL directly.
|
clk_ll_bbpll_set_freq_mhz(pll_freq);
|
||||||
uint8_t div_ref = 0;
|
/* Analog part */
|
||||||
uint8_t div7_0 = 8;
|
regi2c_ctrl_ll_bbpll_calibration_start();
|
||||||
uint8_t dr1 = 0;
|
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||||
uint8_t dr3 = 0;
|
|
||||||
uint8_t dchgp = 5;
|
|
||||||
uint8_t dcur = 3;
|
|
||||||
uint8_t dbias = 2;
|
|
||||||
|
|
||||||
CLEAR_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
|
||||||
SET_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
|
||||||
/* Set this register to let the digital part know 480M PLL is used */
|
|
||||||
SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
|
|
||||||
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
|
||||||
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
|
||||||
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
|
|
||||||
|
|
||||||
s_cur_pll_freq = pll_freq;
|
s_cur_pll_freq = pll_freq;
|
||||||
}
|
}
|
||||||
@@ -162,18 +136,9 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
|||||||
*/
|
*/
|
||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||||
{
|
{
|
||||||
int per_conf = DPORT_CPUPERIOD_SEL_80;
|
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
||||||
if (cpu_freq_mhz == 80) {
|
clk_ll_cpu_set_divider(1);
|
||||||
/* nothing to do */
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||||
} else if (cpu_freq_mhz == 120) {
|
|
||||||
per_conf = DPORT_CPUPERIOD_SEL_120;
|
|
||||||
} else {
|
|
||||||
ESP_HW_LOGE(TAG, "invalid frequency");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, per_conf);
|
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_PLL);
|
|
||||||
rtc_clk_apb_freq_update(40 * MHZ);
|
rtc_clk_apb_freq_update(40 * MHZ);
|
||||||
ets_update_cpu_frequency(cpu_freq_mhz);
|
ets_update_cpu_frequency(cpu_freq_mhz);
|
||||||
}
|
}
|
||||||
@@ -185,7 +150,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
uint32_t divider;
|
uint32_t divider;
|
||||||
uint32_t real_freq_mhz;
|
uint32_t real_freq_mhz;
|
||||||
|
|
||||||
uint32_t xtal_freq = (uint32_t) rtc_clk_xtal_freq_get();
|
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
||||||
divider = xtal_freq / freq_mhz;
|
divider = xtal_freq / freq_mhz;
|
||||||
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
||||||
@@ -199,12 +164,12 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
} else if (freq_mhz == 80) {
|
} else if (freq_mhz == 80) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 6;
|
divider = 6;
|
||||||
} else if (freq_mhz == 120) {
|
} else if (freq_mhz == 120) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 4;
|
divider = 4;
|
||||||
} else {
|
} else {
|
||||||
// unsupported frequency
|
// unsupported frequency
|
||||||
@@ -221,21 +186,21 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||||
{
|
{
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||||
if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
|
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) {
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
||||||
if (soc_clk_sel != DPORT_SOC_CLK_SEL_PLL) {
|
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
|
||||||
rtc_clk_bbpll_enable();
|
rtc_clk_bbpll_enable();
|
||||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
|
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
|
||||||
}
|
}
|
||||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||||
rtc_clk_cpu_freq_to_8m();
|
rtc_clk_cpu_freq_to_8m();
|
||||||
if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
|
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) {
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,38 +208,32 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
||||||
{
|
{
|
||||||
soc_cpu_clk_src_t source;
|
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||||
uint32_t source_freq_mhz;
|
uint32_t source_freq_mhz;
|
||||||
uint32_t div;
|
uint32_t div;
|
||||||
uint32_t freq_mhz;
|
uint32_t freq_mhz;
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
switch (source) {
|
||||||
switch (soc_clk_sel) {
|
case SOC_CPU_CLK_SRC_XTAL: {
|
||||||
case DPORT_SOC_CLK_SEL_XTAL: {
|
div = clk_ll_cpu_get_divider();
|
||||||
source = SOC_CPU_CLK_SRC_XTAL;
|
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
div = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
|
||||||
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
|
|
||||||
freq_mhz = source_freq_mhz / div;
|
freq_mhz = source_freq_mhz / div;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DPORT_SOC_CLK_SEL_PLL: {
|
case SOC_CPU_CLK_SRC_PLL: {
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
|
||||||
uint32_t cpuperiod_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; // PLL clock on ESP32-C2 was fixed to 480MHz
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M; // PLL clock on ESP32-C2 was fixed to 480MHz
|
if (freq_mhz == CLK_LL_PLL_80M_FREQ_MHZ) {
|
||||||
if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80) {
|
|
||||||
div = 6;
|
div = 6;
|
||||||
freq_mhz = 80;
|
} else if (freq_mhz == CLK_LL_PLL_120M_FREQ_MHZ) {
|
||||||
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_120) {
|
|
||||||
div = 4;
|
div = 4;
|
||||||
freq_mhz = 120;
|
|
||||||
} else {
|
} else {
|
||||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DPORT_SOC_CLK_SEL_8M:
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
source = SOC_CPU_CLK_SRC_RC_FAST;
|
source_freq_mhz = 20;
|
||||||
source_freq_mhz = 8;
|
|
||||||
div = 1;
|
div = 1;
|
||||||
freq_mhz = source_freq_mhz;
|
freq_mhz = source_freq_mhz;
|
||||||
break;
|
break;
|
||||||
@@ -305,7 +264,7 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_xtal(void)
|
void rtc_clk_cpu_freq_set_xtal(void)
|
||||||
{
|
{
|
||||||
int freq_mhz = (int) rtc_clk_xtal_freq_get();
|
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||||
|
|
||||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
@@ -314,84 +273,75 @@ void rtc_clk_cpu_freq_set_xtal(void)
|
|||||||
/**
|
/**
|
||||||
* Switch to XTAL frequency. Does not disable the PLL.
|
* Switch to XTAL frequency. Does not disable the PLL.
|
||||||
*/
|
*/
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(freq);
|
ets_update_cpu_frequency(freq);
|
||||||
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, div - 1);
|
clk_ll_cpu_set_divider(div);
|
||||||
/* no need to adjust the REF_TICK */
|
|
||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||||
rtc_clk_apb_freq_update(freq * MHZ);
|
rtc_clk_apb_freq_update(freq * MHZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_cpu_freq_to_8m(void)
|
static void rtc_clk_cpu_freq_to_8m(void)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(8);
|
ets_update_cpu_frequency(20);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_8M);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||||
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||||
{
|
{
|
||||||
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||||
if (!clk_val_is_valid(xtal_freq_reg)) {
|
if (xtal_freq_mhz == 0) {
|
||||||
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value: 0x%08x", xtal_freq_reg);
|
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
|
||||||
return RTC_XTAL_FREQ_40M;
|
return RTC_XTAL_FREQ_40M;
|
||||||
}
|
}
|
||||||
return reg_val_to_clk_val(xtal_freq_reg);
|
return (rtc_xtal_freq_t)xtal_freq_mhz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, clk_val_to_reg_val(xtal_freq));
|
clk_ll_xtal_store_freq_mhz(xtal_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_APB_FREQ_REG, clk_val_to_reg_val(apb_freq >> 12));
|
clk_ll_apb_store_freq_hz(apb_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_apb_freq_get(void)
|
uint32_t rtc_clk_apb_freq_get(void)
|
||||||
{
|
{
|
||||||
uint32_t freq_hz = reg_val_to_clk_val(READ_PERI_REG(RTC_APB_FREQ_REG)) << 12;
|
return clk_ll_apb_load_freq_hz();
|
||||||
// round to the nearest MHz
|
|
||||||
freq_hz += MHZ / 2;
|
|
||||||
uint32_t remainder = freq_hz % MHZ;
|
|
||||||
return freq_hz - remainder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_divider_set(uint32_t div)
|
void rtc_clk_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
clk_ll_rc_slow_set_divider(div + 1);
|
||||||
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, div);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_divider_set(uint32_t div)
|
void rtc_clk_8m_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
clk_ll_rc_fast_set_divider(div + 1);
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, div);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_enable(void)
|
void rtc_dig_clk8m_enable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_enable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_disable(void)
|
void rtc_dig_clk8m_disable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_disable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_dig_8m_enabled(void)
|
bool rtc_dig_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
return clk_ll_rc_fast_digi_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Name used in libphy.a:phy_chip_v7.o
|
/* Name used in libphy.a:phy_chip_v7.o
|
||||||
|
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define MHZ (1000000)
|
|
||||||
|
|
||||||
#define DPORT_CPUPERIOD_SEL_80 0
|
|
||||||
#define DPORT_CPUPERIOD_SEL_120 1
|
|
||||||
|
|
||||||
#define DPORT_SOC_CLK_SEL_XTAL 0
|
|
||||||
#define DPORT_SOC_CLK_SEL_PLL 1
|
|
||||||
#define DPORT_SOC_CLK_SEL_8M 2
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
|
||||||
|
|
||||||
/* Values of RTC_XTAL_FREQ_REG and RTC_APB_FREQ_REG are stored as two copies in
|
|
||||||
* lower and upper 16-bit halves. These are the routines to work with such a
|
|
||||||
* representation.
|
|
||||||
*/
|
|
||||||
static inline bool clk_val_is_valid(uint32_t val)
|
|
||||||
{
|
|
||||||
return (val & 0xffff) == ((val >> 16) & 0xffff) &&
|
|
||||||
val != 0 &&
|
|
||||||
val != UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t reg_val_to_clk_val(uint32_t val)
|
|
||||||
{
|
|
||||||
return val & UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t clk_val_to_reg_val(uint32_t val)
|
|
||||||
{
|
|
||||||
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@@ -15,10 +15,9 @@
|
|||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
#include "hal/cpu_hal.h"
|
#include "hal/cpu_hal.h"
|
||||||
#include "regi2c_ctrl.h"
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "esp_rom_uart.h"
|
#include "esp_rom_uart.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk_init";
|
static const char *TAG = "rtc_clk_init";
|
||||||
@@ -44,9 +43,10 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
/* Configure 8M clock division */
|
/* Configure 8M clock division */
|
||||||
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
||||||
|
|
||||||
/* Enable the internal bus used to configure PLLs */
|
/* Reset (disable) i2c internal bus for all regi2c registers */
|
||||||
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
regi2c_ctrl_ll_i2c_reset(); // TODO: This should be move out from rtc_clk_init
|
||||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
|
/* Enable the internal bus used to configure BBPLL */
|
||||||
|
regi2c_ctrl_ll_i2c_bbpll_enable(); // TODO: This should be moved to bbpll_set_config
|
||||||
|
|
||||||
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
||||||
esp_rom_uart_tx_wait_idle(0);
|
esp_rom_uart_tx_wait_idle(0);
|
||||||
@@ -66,7 +66,7 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
/* Re-calculate the ccount to make time calculation correct. */
|
/* Re-calculate the ccount to make time calculation correct. */
|
||||||
cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before );
|
cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before );
|
||||||
|
|
||||||
/* fast clocks setup */
|
/* Slow & fast clocks setup */
|
||||||
if (cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_RC_FAST) {
|
if (cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_RC_FAST) {
|
||||||
bool need_8md256 = cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256;
|
bool need_8md256 = cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256;
|
||||||
rtc_clk_8m_enable(true, need_8md256);
|
rtc_clk_8m_enable(true, need_8md256);
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "esp32c2/rom/ets_sys.h"
|
#include "esp32c2/rom/ets_sys.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "soc/timer_group_reg.h"
|
#include "soc/timer_group_reg.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
@@ -45,13 +46,13 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Enable requested clock (150k clock is always on) */
|
/* Enable requested clock (150k clock is always on) */
|
||||||
int dig_ext_clk_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
bool dig_ext_clk_enabled = clk_ll_xtal32k_digi_is_enabled();
|
||||||
if (cal_clk == RTC_CAL_EXT_CLK && !dig_ext_clk_state) {
|
if (cal_clk == RTC_CAL_EXT_CLK && !dig_ext_clk_enabled) {
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
|
clk_ll_xtal32k_digi_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cal_clk == RTC_CAL_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_enable();
|
||||||
}
|
}
|
||||||
/* Prepare calibration */
|
/* Prepare calibration */
|
||||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
|
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
|
||||||
@@ -99,10 +100,13 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
}
|
}
|
||||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
|
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_ext_clk_state);
|
/* if dig_ext_clk was originally off and enabled due to calibration, then set back to off state */
|
||||||
|
if (cal_clk == RTC_CAL_EXT_CLK && !dig_ext_clk_enabled) {
|
||||||
|
clk_ll_xtal32k_digi_disable();
|
||||||
|
}
|
||||||
|
|
||||||
if (cal_clk == RTC_CAL_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
return cal_val;
|
return cal_val;
|
||||||
|
@@ -12,57 +12,34 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp32c3/rom/ets_sys.h"
|
#include "esp32c3/rom/ets_sys.h"
|
||||||
#include "esp32c3/rom/rtc.h"
|
#include "esp32c3/rom/rtc.h"
|
||||||
#include "esp32c3/rom/uart.h"
|
|
||||||
#include "esp32c3/rom/gpio.h"
|
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
|
||||||
#include "soc/efuse_reg.h"
|
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "soc/system_reg.h"
|
|
||||||
#include "regi2c_ctrl.h"
|
|
||||||
#include "regi2c_bbpll.h"
|
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "hal/usb_serial_jtag_ll.h"
|
#include "hal/usb_serial_jtag_ll.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk";
|
static const char *TAG = "rtc_clk";
|
||||||
|
|
||||||
#define RTC_PLL_FREQ_320M 320
|
|
||||||
#define RTC_PLL_FREQ_480M 480
|
|
||||||
#define DELAY_RTC_CLK_SWITCH 5
|
|
||||||
|
|
||||||
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
||||||
static int s_cur_pll_freq;
|
static int s_cur_pll_freq;
|
||||||
|
|
||||||
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
||||||
static void rtc_clk_cpu_freq_to_8m(void);
|
static void rtc_clk_cpu_freq_to_8m(void);
|
||||||
static bool rtc_clk_set_bbpll_always_on(void);
|
static bool rtc_clk_set_bbpll_always_on(void);
|
||||||
|
|
||||||
void rtc_clk_32k_enable_internal(x32k_config_t cfg)
|
|
||||||
{
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtc_clk_32k_enable(bool enable)
|
void rtc_clk_32k_enable(bool enable)
|
||||||
{
|
{
|
||||||
if (enable) {
|
if (enable) {
|
||||||
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
|
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
|
||||||
rtc_clk_32k_enable_internal(cfg);
|
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
clk_ll_xtal32k_disable();
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_32k_enable_external(void)
|
void rtc_clk_32k_enable_external(void)
|
||||||
{
|
{
|
||||||
/* TODO ESP32-C3 IDF-2408: external 32k source may need different settings */
|
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
|
||||||
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
|
|
||||||
rtc_clk_32k_enable_internal(cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
||||||
@@ -70,67 +47,62 @@ void rtc_clk_32k_bootstrap(uint32_t cycle)
|
|||||||
/* No special bootstrapping needed for ESP32-C3, 'cycle' argument is to keep the signature
|
/* No special bootstrapping needed for ESP32-C3, 'cycle' argument is to keep the signature
|
||||||
* same as for the ESP32. Just enable the XTAL here.
|
* same as for the ESP32. Just enable the XTAL here.
|
||||||
*/
|
*/
|
||||||
(void) cycle;
|
(void)cycle;
|
||||||
rtc_clk_32k_enable(true);
|
rtc_clk_32k_enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_32k_enabled(void)
|
bool rtc_clk_32k_enabled(void)
|
||||||
{
|
{
|
||||||
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
return clk_ll_xtal32k_is_enabled();
|
||||||
/* If xtal xpd is controlled by software */
|
|
||||||
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
|
||||||
/* If xtal xpd software control is on */
|
|
||||||
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
|
||||||
bool disabled = xtal_xpd_sw && !xtal_xpd_st;
|
|
||||||
return !disabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
||||||
{
|
{
|
||||||
if (clk_8m_en) {
|
if (clk_8m_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_enable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
|
||||||
esp_rom_delay_us(DELAY_8M_ENABLE);
|
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_disable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
|
||||||
}
|
}
|
||||||
/* d256 should be independent configured with 8M
|
/* d256 should be independent configured with 8M
|
||||||
* Maybe we can split this function into 8m and dmd256
|
* Maybe we can split this function into 8m and dmd256
|
||||||
*/
|
*/
|
||||||
if (d256_en) {
|
if (d256_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_enable();
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8m_enabled(void)
|
bool rtc_clk_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
return clk_ll_rc_fast_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8md256_enabled(void)
|
bool rtc_clk_8md256_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
return clk_ll_rc_fast_d256_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t slow_freq)
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
|
clk_ll_rtc_slow_set_src(clk_src);
|
||||||
|
|
||||||
/* Why we need to connect this clock to digital?
|
/* Why we need to connect this clock to digital?
|
||||||
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
|
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
|
||||||
*/
|
*/
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN,
|
if (clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||||
(slow_freq == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? 1 : 0);
|
clk_ll_xtal32k_digi_enable();
|
||||||
|
} else {
|
||||||
|
clk_ll_xtal32k_digi_disable();
|
||||||
|
}
|
||||||
|
|
||||||
esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
return clk_ll_rtc_slow_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||||
@@ -139,126 +111,39 @@ uint32_t rtc_clk_slow_freq_get_hz(void)
|
|||||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
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_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
||||||
|
default: return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t fast_freq)
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
|
clk_ll_rtc_fast_set_src(clk_src);
|
||||||
esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
return clk_ll_rtc_fast_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_disable(void)
|
static void rtc_clk_bbpll_disable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_disable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
s_cur_pll_freq = 0;
|
s_cur_pll_freq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_enable(void)
|
static void rtc_clk_bbpll_enable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_enable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
||||||
{
|
{
|
||||||
uint8_t div_ref;
|
/* Digital part */
|
||||||
uint8_t div7_0;
|
clk_ll_bbpll_set_freq_mhz(pll_freq);
|
||||||
uint8_t dr1;
|
/* Analog part */
|
||||||
uint8_t dr3;
|
regi2c_ctrl_ll_bbpll_calibration_start();
|
||||||
uint8_t dchgp;
|
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||||
uint8_t dcur;
|
|
||||||
uint8_t dbias;
|
|
||||||
|
|
||||||
CLEAR_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
|
||||||
SET_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
|
||||||
if (pll_freq == RTC_PLL_FREQ_480M) {
|
|
||||||
/* Set this register to let the digital part know 480M PLL is used */
|
|
||||||
SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
|
||||||
/* Configure 480M PLL */
|
|
||||||
switch (xtal_freq) {
|
|
||||||
case RTC_XTAL_FREQ_40M:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 8;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
case RTC_XTAL_FREQ_32M:
|
|
||||||
div_ref = 1;
|
|
||||||
div7_0 = 26;
|
|
||||||
dr1 = 1;
|
|
||||||
dr3 = 1;
|
|
||||||
dchgp = 4;
|
|
||||||
dcur = 0;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 8;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
|
|
||||||
} else {
|
|
||||||
/* Clear this register to let the digital part know 320M PLL is used */
|
|
||||||
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
|
||||||
/* Configure 320M PLL */
|
|
||||||
switch (xtal_freq) {
|
|
||||||
case RTC_XTAL_FREQ_40M:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 4;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
case RTC_XTAL_FREQ_32M:
|
|
||||||
div_ref = 1;
|
|
||||||
div7_0 = 6;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 4;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
|
|
||||||
}
|
|
||||||
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
|
||||||
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
|
||||||
uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 2);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1);
|
|
||||||
|
|
||||||
s_cur_pll_freq = pll_freq;
|
s_cur_pll_freq = pll_freq;
|
||||||
}
|
}
|
||||||
@@ -270,18 +155,9 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
|||||||
*/
|
*/
|
||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||||
{
|
{
|
||||||
int per_conf = DPORT_CPUPERIOD_SEL_80;
|
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
||||||
if (cpu_freq_mhz == 80) {
|
clk_ll_cpu_set_divider(1);
|
||||||
/* nothing to do */
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||||
} else if (cpu_freq_mhz == 160) {
|
|
||||||
per_conf = DPORT_CPUPERIOD_SEL_160;
|
|
||||||
} else {
|
|
||||||
ESP_HW_LOGE(TAG, "invalid frequency");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, per_conf);
|
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_PLL);
|
|
||||||
rtc_clk_apb_freq_update(80 * MHZ);
|
rtc_clk_apb_freq_update(80 * MHZ);
|
||||||
ets_update_cpu_frequency(cpu_freq_mhz);
|
ets_update_cpu_frequency(cpu_freq_mhz);
|
||||||
}
|
}
|
||||||
@@ -293,7 +169,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
uint32_t divider;
|
uint32_t divider;
|
||||||
uint32_t real_freq_mhz;
|
uint32_t real_freq_mhz;
|
||||||
|
|
||||||
uint32_t xtal_freq = (uint32_t) rtc_clk_xtal_freq_get();
|
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
||||||
divider = xtal_freq / freq_mhz;
|
divider = xtal_freq / freq_mhz;
|
||||||
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
||||||
@@ -307,12 +183,12 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
} else if (freq_mhz == 80) {
|
} else if (freq_mhz == 80) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 6;
|
divider = 6;
|
||||||
} else if (freq_mhz == 160) {
|
} else if (freq_mhz == 160) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 3;
|
divider = 3;
|
||||||
} else {
|
} else {
|
||||||
// unsupported frequency
|
// unsupported frequency
|
||||||
@@ -329,22 +205,22 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||||
{
|
{
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||||
if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) {
|
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !rtc_clk_set_bbpll_always_on()) {
|
||||||
// We don't turn off the bbpll if some consumers only depends on bbpll
|
// We don't turn off the bbpll if some consumers only depends on bbpll
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
||||||
if (soc_clk_sel != DPORT_SOC_CLK_SEL_PLL) {
|
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
|
||||||
rtc_clk_bbpll_enable();
|
rtc_clk_bbpll_enable();
|
||||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
|
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
|
||||||
}
|
}
|
||||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||||
rtc_clk_cpu_freq_to_8m();
|
rtc_clk_cpu_freq_to_8m();
|
||||||
if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) {
|
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !rtc_clk_set_bbpll_always_on()) {
|
||||||
// We don't turn off the bbpll if some consumers only depends on bbpll
|
// We don't turn off the bbpll if some consumers only depends on bbpll
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
@@ -353,40 +229,32 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
||||||
{
|
{
|
||||||
soc_cpu_clk_src_t source;
|
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||||
uint32_t source_freq_mhz;
|
uint32_t source_freq_mhz;
|
||||||
uint32_t div;
|
uint32_t div;
|
||||||
uint32_t freq_mhz;
|
uint32_t freq_mhz;
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
switch (source) {
|
||||||
switch (soc_clk_sel) {
|
case SOC_CPU_CLK_SRC_XTAL: {
|
||||||
case DPORT_SOC_CLK_SEL_XTAL: {
|
div = clk_ll_cpu_get_divider();
|
||||||
source = SOC_CPU_CLK_SRC_XTAL;
|
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
div = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
|
||||||
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
|
|
||||||
freq_mhz = source_freq_mhz / div;
|
freq_mhz = source_freq_mhz / div;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DPORT_SOC_CLK_SEL_PLL: {
|
case SOC_CPU_CLK_SRC_PLL: {
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
|
||||||
uint32_t cpuperiod_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
|
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||||
uint32_t pllfreq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
if (freq_mhz == CLK_LL_PLL_80M_FREQ_MHZ) {
|
||||||
source_freq_mhz = (pllfreq_sel) ? RTC_PLL_FREQ_480M : RTC_PLL_FREQ_320M;
|
div = (source_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) ? 6 : 4;
|
||||||
if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80) {
|
} else if (freq_mhz == CLK_LL_PLL_160M_FREQ_MHZ) {
|
||||||
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 6 : 4;
|
div = (source_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) ? 3 : 2;
|
||||||
freq_mhz = 80;
|
|
||||||
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160) {
|
|
||||||
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 3 : 2;
|
|
||||||
div = 3;
|
|
||||||
freq_mhz = 160;
|
|
||||||
} else {
|
} else {
|
||||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DPORT_SOC_CLK_SEL_8M:
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
source = SOC_CPU_CLK_SRC_RC_FAST;
|
source_freq_mhz = 20;
|
||||||
source_freq_mhz = 8;
|
|
||||||
div = 1;
|
div = 1;
|
||||||
freq_mhz = source_freq_mhz;
|
freq_mhz = source_freq_mhz;
|
||||||
break;
|
break;
|
||||||
@@ -417,7 +285,7 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_xtal(void)
|
void rtc_clk_cpu_freq_set_xtal(void)
|
||||||
{
|
{
|
||||||
int freq_mhz = (int) rtc_clk_xtal_freq_get();
|
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||||
|
|
||||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||||
// We don't turn off the bbpll if some consumers only depends on bbpll
|
// We don't turn off the bbpll if some consumers only depends on bbpll
|
||||||
@@ -429,84 +297,75 @@ void rtc_clk_cpu_freq_set_xtal(void)
|
|||||||
/**
|
/**
|
||||||
* Switch to XTAL frequency. Does not disable the PLL.
|
* Switch to XTAL frequency. Does not disable the PLL.
|
||||||
*/
|
*/
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(freq);
|
ets_update_cpu_frequency(freq);
|
||||||
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, div - 1);
|
clk_ll_cpu_set_divider(div);
|
||||||
/* no need to adjust the REF_TICK */
|
|
||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||||
rtc_clk_apb_freq_update(freq * MHZ);
|
rtc_clk_apb_freq_update(freq * MHZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_cpu_freq_to_8m(void)
|
static void rtc_clk_cpu_freq_to_8m(void)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(8);
|
ets_update_cpu_frequency(20);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_8M);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||||
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||||
{
|
{
|
||||||
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||||
if (!clk_val_is_valid(xtal_freq_reg)) {
|
if (xtal_freq_mhz == 0) {
|
||||||
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value: 0x%08x", xtal_freq_reg);
|
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
|
||||||
return RTC_XTAL_FREQ_40M;
|
return RTC_XTAL_FREQ_40M;
|
||||||
}
|
}
|
||||||
return reg_val_to_clk_val(xtal_freq_reg);
|
return (rtc_xtal_freq_t)xtal_freq_mhz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, clk_val_to_reg_val(xtal_freq));
|
clk_ll_xtal_store_freq_mhz(xtal_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_APB_FREQ_REG, clk_val_to_reg_val(apb_freq >> 12));
|
clk_ll_apb_store_freq_hz(apb_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_apb_freq_get(void)
|
uint32_t rtc_clk_apb_freq_get(void)
|
||||||
{
|
{
|
||||||
uint32_t freq_hz = reg_val_to_clk_val(READ_PERI_REG(RTC_APB_FREQ_REG)) << 12;
|
return clk_ll_apb_load_freq_hz();
|
||||||
// round to the nearest MHz
|
|
||||||
freq_hz += MHZ / 2;
|
|
||||||
uint32_t remainder = freq_hz % MHZ;
|
|
||||||
return freq_hz - remainder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_divider_set(uint32_t div)
|
void rtc_clk_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
clk_ll_rc_slow_set_divider(div + 1);
|
||||||
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, div);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_divider_set(uint32_t div)
|
void rtc_clk_8m_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
clk_ll_rc_fast_set_divider(div + 1);
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, div);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_enable(void)
|
void rtc_dig_clk8m_enable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_enable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_disable(void)
|
void rtc_dig_clk8m_disable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_disable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_dig_8m_enabled(void)
|
bool rtc_dig_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
return clk_ll_rc_fast_digi_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rtc_clk_set_bbpll_always_on(void)
|
static bool rtc_clk_set_bbpll_always_on(void)
|
||||||
|
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define MHZ (1000000)
|
|
||||||
|
|
||||||
#define DPORT_CPUPERIOD_SEL_80 0
|
|
||||||
#define DPORT_CPUPERIOD_SEL_160 1
|
|
||||||
|
|
||||||
#define DPORT_SOC_CLK_SEL_XTAL 0
|
|
||||||
#define DPORT_SOC_CLK_SEL_PLL 1
|
|
||||||
#define DPORT_SOC_CLK_SEL_8M 2
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
|
||||||
|
|
||||||
/* Values of RTC_XTAL_FREQ_REG and RTC_APB_FREQ_REG are stored as two copies in
|
|
||||||
* lower and upper 16-bit halves. These are the routines to work with such a
|
|
||||||
* representation.
|
|
||||||
*/
|
|
||||||
static inline bool clk_val_is_valid(uint32_t val)
|
|
||||||
{
|
|
||||||
return (val & 0xffff) == ((val >> 16) & 0xffff) &&
|
|
||||||
val != 0 &&
|
|
||||||
val != UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t reg_val_to_clk_val(uint32_t val)
|
|
||||||
{
|
|
||||||
return val & UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t clk_val_to_reg_val(uint32_t val)
|
|
||||||
{
|
|
||||||
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@@ -14,12 +14,10 @@
|
|||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "hal/cpu_hal.h"
|
#include "hal/cpu_hal.h"
|
||||||
#include "regi2c_ctrl.h"
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "esp_rom_uart.h"
|
#include "esp_rom_uart.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk_init";
|
static const char *TAG = "rtc_clk_init";
|
||||||
@@ -45,9 +43,10 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
/* Configure 8M clock division */
|
/* Configure 8M clock division */
|
||||||
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
||||||
|
|
||||||
/* Enable the internal bus used to configure PLLs */
|
/* Reset (disable) i2c internal bus for all regi2c registers */
|
||||||
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
regi2c_ctrl_ll_i2c_reset(); // TODO: This should be move out from rtc_clk_init
|
||||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
|
/* Enable the internal bus used to configure BBPLL */
|
||||||
|
regi2c_ctrl_ll_i2c_bbpll_enable(); // TODO: This should be moved to bbpll_set_config
|
||||||
|
|
||||||
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
||||||
esp_rom_uart_tx_wait_idle(0);
|
esp_rom_uart_tx_wait_idle(0);
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "esp32c3/rom/ets_sys.h"
|
#include "esp32c3/rom/ets_sys.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "soc/timer_group_reg.h"
|
#include "soc/timer_group_reg.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
@@ -49,13 +50,13 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
|
|
||||||
|
|
||||||
/* Enable requested clock (150k clock is always on) */
|
/* Enable requested clock (150k clock is always on) */
|
||||||
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
|
||||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
|
clk_ll_xtal32k_digi_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cal_clk == RTC_CAL_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_enable();
|
||||||
}
|
}
|
||||||
/* There may be another calibration process already running during we call this function,
|
/* There may be another calibration process already running during we call this function,
|
||||||
* so we should wait the last process is done.
|
* so we should wait the last process is done.
|
||||||
@@ -108,10 +109,13 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
}
|
}
|
||||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
|
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
|
/* 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_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
return cal_val;
|
return cal_val;
|
||||||
|
@@ -15,70 +15,48 @@
|
|||||||
#include "esp32h2/rom/uart.h"
|
#include "esp32h2/rom/uart.h"
|
||||||
#include "esp32h2/rom/gpio.h"
|
#include "esp32h2/rom/gpio.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "i2c_bbpll.h"
|
#include "soc/io_mux_reg.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "soc/efuse_reg.h"
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
#include "soc/syscon_reg.h"
|
#include "hal/gpio_ll.h"
|
||||||
#include "soc/system_reg.h"
|
|
||||||
#include "regi2c_ctrl.h"
|
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk";
|
static const char *TAG = "rtc_clk";
|
||||||
|
|
||||||
#define RTC_PLL_FREQ_96M 96
|
|
||||||
#define RTC_OSC_FREQ_RC8M 8
|
#define RTC_OSC_FREQ_RC8M 8
|
||||||
#define DELAY_RTC_CLK_SWITCH 5
|
|
||||||
#define RTC_CNTL_ANA_CONF0_CAL_REG 0x6000e040
|
|
||||||
#define RTC_CNTL_ANA_CONF0_CAL_START BIT(2)
|
|
||||||
#define RTC_CNTL_ANA_CONF0_CAL_STOP BIT(3)
|
|
||||||
#define RTC_CNTL_ANA_CONF0_CAL_DONE BIT(24)
|
|
||||||
|
|
||||||
// Current PLL frequency, in 96MHZ. Zero if PLL is not enabled.
|
// Current PLL frequency, in 96MHZ. Zero if PLL is not enabled.
|
||||||
static int s_cur_pll_freq;
|
static int s_cur_pll_freq;
|
||||||
|
|
||||||
|
static uint32_t rtc_clk_ahb_freq_get(void);
|
||||||
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
||||||
void rtc_clk_cpu_freq_to_8m(void);
|
void rtc_clk_cpu_freq_to_8m(void);
|
||||||
static uint32_t rtc_clk_ahb_freq_set(uint32_t div);
|
|
||||||
|
|
||||||
void rtc_clk_32k_enable_internal(x32k_config_t cfg)
|
static void rtc_gpio_hangup(uint32_t gpio_no)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
gpio_ll_pulldown_dis(&GPIO, gpio_no);
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
gpio_ll_pullup_dis(&GPIO, gpio_no);
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
gpio_ll_output_disable(&GPIO, gpio_no);
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
gpio_ll_input_disable(&GPIO, gpio_no);
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_no], PIN_FUNC_GPIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_32k_enable(bool enable)
|
void rtc_clk_32k_enable(bool enable)
|
||||||
{
|
{
|
||||||
if (enable) {
|
if (enable) {
|
||||||
/* need to hangup gpio0 & 1 before enable xtal_32k */
|
/* need to hangup 32K_P and 32K_N pins before enable xtal_32k */
|
||||||
rtc_gpio_hangup(0);
|
rtc_gpio_hangup(XTAL32K_P_GPIO_NUM);
|
||||||
rtc_gpio_hangup(1);
|
rtc_gpio_hangup(XTAL32K_N_GPIO_NUM);
|
||||||
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
|
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
|
||||||
rtc_clk_32k_enable_internal(cfg);
|
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
clk_ll_xtal32k_disable();
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_rc32k_dfreq(uint32_t dfreq)
|
|
||||||
{
|
|
||||||
REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_DFREQ, dfreq);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtc_clk_rc32k_enable(bool enable)
|
|
||||||
{
|
|
||||||
rc32k_config_t cfg = RC32K_CONFIG_DEFAULT();
|
|
||||||
rtc_clk_rc32k_dfreq(cfg.dfreq);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_XPD, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtc_clk_32k_enable_external(void)
|
void rtc_clk_32k_enable_external(void)
|
||||||
{
|
{
|
||||||
rtc_clk_32k_enable(true);
|
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
||||||
@@ -86,32 +64,35 @@ void rtc_clk_32k_bootstrap(uint32_t cycle)
|
|||||||
/* No special bootstrapping needed for ESP32-H2, 'cycle' argument is to keep the signature
|
/* No special bootstrapping needed for ESP32-H2, 'cycle' argument is to keep the signature
|
||||||
* same as for the ESP32. Just enable the XTAL here.
|
* same as for the ESP32. Just enable the XTAL here.
|
||||||
*/
|
*/
|
||||||
(void) cycle;
|
(void)cycle;
|
||||||
rtc_clk_32k_enable(true);
|
rtc_clk_32k_enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_32k_enabled(void)
|
bool rtc_clk_32k_enabled(void)
|
||||||
{
|
{
|
||||||
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
return clk_ll_xtal32k_is_enabled();
|
||||||
/* If xtal xpd is controlled by software */
|
|
||||||
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
|
||||||
/* If xtal xpd software control is on */
|
|
||||||
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
|
||||||
bool disabled = xtal_xpd_sw && !xtal_xpd_st;
|
|
||||||
return !disabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t slow_freq)
|
void rtc_clk_rc32k_enable(bool enable)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
|
if (enable) {
|
||||||
rtc_clk_32k_enable((slow_freq == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? 1 : 0);
|
clk_ll_rc32k_enable();
|
||||||
rtc_clk_rc32k_enable((slow_freq == SOC_RTC_SLOW_CLK_SRC_RC32K) ? 1 : 0);
|
} else {
|
||||||
esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
|
clk_ll_rc32k_disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
|
||||||
|
{
|
||||||
|
clk_ll_rtc_slow_set_src(clk_src);
|
||||||
|
rtc_clk_32k_enable((clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? 1 : 0);
|
||||||
|
rtc_clk_rc32k_enable((clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) ? 1 : 0);
|
||||||
|
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
return clk_ll_rtc_slow_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||||
@@ -120,62 +101,86 @@ uint32_t rtc_clk_slow_freq_get_hz(void)
|
|||||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
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_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX;
|
case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX;
|
||||||
|
default: return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t fast_freq)
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
|
clk_ll_rtc_fast_set_src(clk_src);
|
||||||
esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
return clk_ll_rtc_fast_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_disable(void)
|
static void rtc_clk_bbpll_disable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_disable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
s_cur_pll_freq = 0;
|
s_cur_pll_freq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_enable(void)
|
static void rtc_clk_bbpll_enable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_enable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
}
|
|
||||||
static void rtc_clk_bbpll_cali_stop(void)
|
|
||||||
{
|
|
||||||
while (!REG_GET_BIT(RTC_CNTL_ANA_CONF0_CAL_REG, RTC_CNTL_ANA_CONF0_CAL_DONE));
|
|
||||||
REG_CLR_BIT(RTC_CNTL_ANA_CONF0_CAL_REG, RTC_CNTL_ANA_CONF0_CAL_STOP);
|
|
||||||
REG_SET_BIT(RTC_CNTL_ANA_CONF0_CAL_REG, RTC_CNTL_ANA_CONF0_CAL_START);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
||||||
{
|
{
|
||||||
uint8_t div_ref;
|
if (!((pll_freq == CLK_LL_PLL_96M_FREQ_MHZ) && (xtal_freq == RTC_XTAL_FREQ_32M))) {
|
||||||
uint8_t div5_0;
|
ESP_HW_LOGE(TAG, "invalid pll or xtal frequency");
|
||||||
if ((pll_freq == RTC_PLL_FREQ_96M) && (xtal_freq == RTC_XTAL_FREQ_32M)) {
|
|
||||||
/* Configure 96M PLL */
|
|
||||||
div_ref = 0;
|
|
||||||
div5_0 = 1;
|
|
||||||
} else {
|
|
||||||
div_ref = 0;
|
|
||||||
div5_0 = 1;
|
|
||||||
ESP_HW_LOGE(TAG, "invalid pll frequency");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, div_ref);
|
// No digital part needs to be set, pll_freq can only be 96MHz
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DIV, div5_0); //I2C_BBPLL_OC_DIV_5_0
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 3); // need update to 3 since s2
|
// Configure analog part
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1);
|
regi2c_ctrl_ll_bbpll_calibration_start();
|
||||||
|
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||||
|
// Wait until calibration finishes
|
||||||
|
while (!regi2c_ctrl_ll_bbpll_calibration_is_done());
|
||||||
|
// Prevent BBPLL clock jitter
|
||||||
|
regi2c_ctrl_ll_bbpll_calibration_stop();
|
||||||
s_cur_pll_freq = pll_freq;
|
s_cur_pll_freq = pll_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rtc_clk_select_root_clk(soc_cpu_clk_src_t cpu_clk_src)
|
||||||
|
{
|
||||||
|
uint32_t root_clk_freq_mhz;
|
||||||
|
switch (cpu_clk_src) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
root_clk_freq_mhz = RTC_XTAL_FREQ_32M;
|
||||||
|
rtc_clk_bbpll_disable();
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
// SPLL_ENABLE
|
||||||
|
root_clk_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
|
||||||
|
rtc_clk_bbpll_enable();
|
||||||
|
rtc_clk_bbpll_configure(RTC_XTAL_FREQ_32M, root_clk_freq_mhz);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
root_clk_freq_mhz = RTC_OSC_FREQ_RC8M;
|
||||||
|
rtc_dig_clk8m_enable(); // TODO: Do we need to enable digital gating here?
|
||||||
|
rtc_clk_8m_divider_set(1);
|
||||||
|
rtc_clk_bbpll_disable();
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL_D2:
|
||||||
|
root_clk_freq_mhz = RTC_XTAL_FREQ_32M / 2;
|
||||||
|
rtc_clk_bbpll_disable();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_HW_LOGE(TAG, "unsupported source clk configuration");
|
||||||
|
// fallback to XTAL as root clock source
|
||||||
|
root_clk_freq_mhz = RTC_XTAL_FREQ_32M;
|
||||||
|
rtc_clk_bbpll_disable();
|
||||||
|
cpu_clk_src = SOC_CPU_CLK_SRC_XTAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
clk_ll_cpu_set_src(cpu_clk_src);
|
||||||
|
return root_clk_freq_mhz;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
|
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
|
||||||
* PLL must already be enabled.
|
* PLL must already be enabled.
|
||||||
@@ -184,39 +189,40 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
|||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||||
{
|
{
|
||||||
int div = 1;
|
int div = 1;
|
||||||
if (RTC_PLL_FREQ_96M % cpu_freq_mhz == 0) {
|
if (CLK_LL_PLL_96M_FREQ_MHZ % cpu_freq_mhz == 0) {
|
||||||
div = RTC_PLL_FREQ_96M / cpu_freq_mhz;
|
div = CLK_LL_PLL_96M_FREQ_MHZ / cpu_freq_mhz;
|
||||||
} else {
|
} else {
|
||||||
ESP_HW_LOGE(TAG, "invalid frequency");
|
ESP_HW_LOGE(TAG, "invalid frequency");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
rtc_clk_cpu_freq_set(DPORT_SOC_CLK_SEL_PLL, div - 1);
|
rtc_clk_cpu_freq_set(SOC_CPU_CLK_SRC_PLL, div);
|
||||||
if (cpu_freq_mhz > RTC_XTAL_FREQ_32M) {
|
if (cpu_freq_mhz > RTC_XTAL_FREQ_32M) {
|
||||||
rtc_clk_ahb_freq_set(2);
|
clk_ll_ahb_set_divider(2);
|
||||||
} else {
|
} else {
|
||||||
rtc_clk_ahb_freq_set(1);
|
clk_ll_ahb_set_divider(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
|
||||||
ets_update_cpu_frequency(cpu_freq_mhz);
|
ets_update_cpu_frequency(cpu_freq_mhz);
|
||||||
|
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
|
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
|
||||||
{
|
{
|
||||||
|
// TODO: This function supposes to only fill a cpu config, but it is writing to registers, needs to check
|
||||||
uint32_t source_freq_mhz;
|
uint32_t source_freq_mhz;
|
||||||
soc_cpu_clk_src_t source;
|
soc_cpu_clk_src_t source;
|
||||||
uint32_t divider;
|
uint32_t divider;
|
||||||
uint32_t xtal_freq = (uint32_t) rtc_clk_xtal_freq_get();
|
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
if (freq_mhz > xtal_freq) {
|
if (freq_mhz > xtal_freq) {
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_96M;
|
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
|
||||||
divider = RTC_PLL_FREQ_96M / freq_mhz;
|
divider = CLK_LL_PLL_96M_FREQ_MHZ / freq_mhz;
|
||||||
rtc_clk_ahb_freq_set(2);
|
clk_ll_ahb_set_divider(2);
|
||||||
} else if (freq_mhz != 0) {
|
} else if (freq_mhz != 0) {
|
||||||
source = root_clk_get();
|
source = clk_ll_cpu_get_src();
|
||||||
source_freq_mhz = root_clk_slt(source);
|
source_freq_mhz = rtc_clk_select_root_clk(source);
|
||||||
divider = source_freq_mhz / freq_mhz;
|
divider = source_freq_mhz / freq_mhz;
|
||||||
rtc_clk_ahb_freq_set(1);
|
clk_ll_ahb_set_divider(1);
|
||||||
} else {
|
} else {
|
||||||
// unsupported frequency
|
// unsupported frequency
|
||||||
return false;
|
return false;
|
||||||
@@ -232,7 +238,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||||
{
|
{
|
||||||
uint32_t src_freq_mhz = root_clk_slt(config->source);
|
uint32_t src_freq_mhz = rtc_clk_select_root_clk(config->source);
|
||||||
uint32_t div = src_freq_mhz / (config->freq_mhz);
|
uint32_t div = src_freq_mhz / (config->freq_mhz);
|
||||||
rtc_clk_cpu_freq_set(config->source, div);
|
rtc_clk_cpu_freq_set(config->source, div);
|
||||||
ets_update_cpu_frequency(config->freq_mhz);
|
ets_update_cpu_frequency(config->freq_mhz);
|
||||||
@@ -240,37 +246,32 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
||||||
{
|
{
|
||||||
soc_cpu_clk_src_t source;
|
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||||
uint32_t source_freq_mhz;
|
uint32_t source_freq_mhz;
|
||||||
uint32_t div;
|
uint32_t div;
|
||||||
uint32_t freq_mhz;
|
uint32_t freq_mhz;
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
switch (source) {
|
||||||
switch (soc_clk_sel) {
|
case SOC_CPU_CLK_SRC_XTAL: {
|
||||||
case DPORT_SOC_CLK_SEL_XTAL: {
|
div = clk_ll_cpu_get_divider();
|
||||||
source = SOC_CPU_CLK_SRC_XTAL;
|
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
div = REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
|
||||||
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
|
|
||||||
freq_mhz = source_freq_mhz / div;
|
freq_mhz = source_freq_mhz / div;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DPORT_SOC_CLK_SEL_PLL: {
|
case SOC_CPU_CLK_SRC_PLL: {
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
div = clk_ll_cpu_get_divider();
|
||||||
div = REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_96M;
|
|
||||||
freq_mhz = source_freq_mhz / div;
|
freq_mhz = source_freq_mhz / div;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DPORT_SOC_CLK_SEL_8M: {
|
case SOC_CPU_CLK_SRC_RC_FAST: {
|
||||||
source = SOC_CPU_CLK_SRC_RC_FAST;
|
|
||||||
source_freq_mhz = RTC_OSC_FREQ_RC8M;
|
source_freq_mhz = RTC_OSC_FREQ_RC8M;
|
||||||
div = REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
div = clk_ll_cpu_get_divider();
|
||||||
freq_mhz = source_freq_mhz / div;
|
freq_mhz = source_freq_mhz / div;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DPORT_SOC_CLK_SEL_XTAL_D2: {
|
case SOC_CPU_CLK_SRC_XTAL_D2: {
|
||||||
source = SOC_CPU_CLK_SRC_XTAL_D2;
|
div = clk_ll_cpu_get_divider();
|
||||||
div = REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
|
|
||||||
freq_mhz = source_freq_mhz / div / 2;
|
freq_mhz = source_freq_mhz / div / 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -302,7 +303,8 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_xtal(void)
|
void rtc_clk_cpu_freq_set_xtal(void)
|
||||||
{
|
{
|
||||||
int freq_mhz = (int) rtc_clk_xtal_freq_get();
|
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||||
|
|
||||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
@@ -310,11 +312,11 @@ void rtc_clk_cpu_freq_set_xtal(void)
|
|||||||
/**
|
/**
|
||||||
* Switch to XTAL frequency. Does not disable the PLL.
|
* Switch to XTAL frequency. Does not disable the PLL.
|
||||||
*/
|
*/
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(freq);
|
ets_update_cpu_frequency(freq);
|
||||||
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
||||||
rtc_clk_cpu_freq_set(DPORT_SOC_CLK_SEL_XTAL, div);
|
rtc_clk_cpu_freq_set(SOC_CPU_CLK_SRC_XTAL, div);
|
||||||
/* no need to adjust the REF_TICK */
|
/* no need to adjust the REF_TICK */
|
||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
||||||
@@ -323,148 +325,75 @@ void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
|||||||
void rtc_clk_cpu_freq_to_8m(void)
|
void rtc_clk_cpu_freq_to_8m(void)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(RTC_OSC_FREQ_RC8M);
|
ets_update_cpu_frequency(RTC_OSC_FREQ_RC8M);
|
||||||
root_clk_slt(DPORT_SOC_CLK_SEL_8M);
|
rtc_clk_select_root_clk(SOC_CPU_CLK_SRC_RC_FAST);
|
||||||
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||||
{
|
{
|
||||||
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||||
if (!clk_val_is_valid(xtal_freq_reg)) {
|
if (xtal_freq_mhz == 0) {
|
||||||
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value: 0x%08x", xtal_freq_reg);
|
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 32MHz");
|
||||||
return RTC_XTAL_FREQ_32M;
|
return RTC_XTAL_FREQ_32M;
|
||||||
}
|
}
|
||||||
return reg_val_to_clk_val(xtal_freq_reg);
|
return (rtc_xtal_freq_t)xtal_freq_mhz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, clk_val_to_reg_val(xtal_freq));
|
clk_ll_xtal_store_freq_mhz(xtal_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_APB_FREQ_REG, clk_val_to_reg_val(apb_freq >> 12));
|
clk_ll_apb_store_freq_hz(apb_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t rtc_clk_apb_freq_get(void)
|
uint32_t rtc_clk_apb_freq_get(void)
|
||||||
{
|
{
|
||||||
uint32_t apb_div = REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM) + 1;
|
return rtc_clk_ahb_freq_get() / clk_ll_apb_get_divider();
|
||||||
return rtc_clk_ahb_freq_get() / apb_div;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_ahb_freq_get()
|
static uint32_t rtc_clk_ahb_freq_get(void)
|
||||||
{
|
{
|
||||||
rtc_cpu_freq_config_t cpu_config;
|
rtc_cpu_freq_config_t cpu_config;
|
||||||
uint32_t ahb_div = REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM) + 1;
|
rtc_clk_cpu_freq_get_config(&cpu_config);
|
||||||
rtc_clk_cpu_freq_get_config(&cpu_config) ;
|
return cpu_config.freq_mhz * MHZ / clk_ll_ahb_get_divider();
|
||||||
return cpu_config.freq_mhz * MHZ / ahb_div;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t rtc_clk_ahb_freq_set(uint32_t div)
|
|
||||||
{
|
|
||||||
REG_SET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM, div - 1);
|
|
||||||
return rtc_clk_ahb_freq_get();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t rtc_clk_apb_freq_set(uint32_t div)
|
|
||||||
{
|
|
||||||
REG_SET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM, div - 1);
|
|
||||||
return rtc_clk_apb_freq_get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_cpu_freq_set(uint32_t source, uint32_t div)
|
void rtc_clk_cpu_freq_set(uint32_t source, uint32_t div)
|
||||||
{
|
{
|
||||||
if (root_clk_get() != source) {
|
if ((uint32_t)clk_ll_cpu_get_src() != source) {
|
||||||
root_clk_slt(source);
|
rtc_clk_select_root_clk(source);
|
||||||
}
|
}
|
||||||
REG_SET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_CPU_DIV_NUM, div - 1);
|
clk_ll_cpu_set_divider(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_divider_set(uint32_t div)
|
void rtc_clk_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
clk_ll_rc_slow_set_divider(div);
|
||||||
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, div - 1);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_divider_set(uint32_t div)
|
void rtc_clk_8m_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
clk_ll_rc_fast_set_divider(div);
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, div - 1);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_enable(void)
|
void rtc_dig_clk8m_enable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN);
|
clk_ll_rc_fast_digi_enable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_disable(void)
|
void rtc_dig_clk8m_disable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN);
|
clk_ll_rc_fast_digi_disable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_dig_8m_enabled(void)
|
bool rtc_dig_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
return clk_ll_rc_fast_digi_is_enabled();
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t read_spll_freq(void)
|
|
||||||
{
|
|
||||||
return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SPLL_FREQ);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t read_xtal_freq(void)
|
|
||||||
{
|
|
||||||
return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_CLK_XTAL_FREQ);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Select clock root source for esp32h2. return source clk freq_mhz
|
|
||||||
*/
|
|
||||||
uint32_t root_clk_slt(uint32_t source)
|
|
||||||
{
|
|
||||||
uint32_t root_clk_freq_mhz;
|
|
||||||
switch (source) {
|
|
||||||
case SOC_CPU_CLK_SRC_XTAL:
|
|
||||||
root_clk_freq_mhz = RTC_XTAL_FREQ_32M;
|
|
||||||
rtc_clk_bbpll_disable();
|
|
||||||
break;
|
|
||||||
case SOC_CPU_CLK_SRC_PLL:
|
|
||||||
// SPLL_ENABLE
|
|
||||||
root_clk_freq_mhz = RTC_PLL_FREQ_96M;
|
|
||||||
rtc_clk_bbpll_enable();
|
|
||||||
rtc_clk_bbpll_configure(RTC_XTAL_FREQ_32M, root_clk_freq_mhz);
|
|
||||||
rtc_clk_bbpll_cali_stop();
|
|
||||||
break;
|
|
||||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
|
||||||
root_clk_freq_mhz = RTC_OSC_FREQ_RC8M;
|
|
||||||
rtc_dig_clk8m_enable();
|
|
||||||
rtc_clk_8m_divider_set(1);
|
|
||||||
rtc_clk_bbpll_disable();
|
|
||||||
break;
|
|
||||||
case SOC_CPU_CLK_SRC_XTAL_D2:
|
|
||||||
root_clk_freq_mhz = RTC_XTAL_FREQ_32M / 2;
|
|
||||||
rtc_clk_bbpll_disable();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ESP_HW_LOGE(TAG, "unsupported source clk configuration");
|
|
||||||
root_clk_freq_mhz = RTC_XTAL_FREQ_32M;
|
|
||||||
rtc_clk_bbpll_disable();
|
|
||||||
source = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, source);
|
|
||||||
return root_clk_freq_mhz;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t root_clk_get()
|
|
||||||
{
|
|
||||||
uint32_t src_slt = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
|
||||||
return src_slt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Name used in libphy.a:phy_chip_v7.o
|
/* Name used in libphy.a:phy_chip_v7.o
|
||||||
|
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define MHZ (1000000)
|
|
||||||
|
|
||||||
#define DPORT_CPUPERIOD_SEL_80 0
|
|
||||||
#define DPORT_CPUPERIOD_SEL_160 1
|
|
||||||
|
|
||||||
#define DPORT_SOC_CLK_SEL_XTAL 0
|
|
||||||
#define DPORT_SOC_CLK_SEL_PLL 1
|
|
||||||
#define DPORT_SOC_CLK_SEL_8M 2
|
|
||||||
#define DPORT_SOC_CLK_SEL_XTAL_D2 3
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
|
||||||
|
|
||||||
/* Values of RTC_XTAL_FREQ_REG and RTC_APB_FREQ_REG are stored as two copies in
|
|
||||||
* lower and upper 16-bit halves. These are the routines to work with such a
|
|
||||||
* representation.
|
|
||||||
*/
|
|
||||||
static inline bool clk_val_is_valid(uint32_t val)
|
|
||||||
{
|
|
||||||
return (val & 0xffff) == ((val >> 16) & 0xffff) &&
|
|
||||||
val != 0 &&
|
|
||||||
val != UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t reg_val_to_clk_val(uint32_t val)
|
|
||||||
{
|
|
||||||
return val & UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t clk_val_to_reg_val(uint32_t val)
|
|
||||||
{
|
|
||||||
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@@ -17,18 +17,13 @@
|
|||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "hal/cpu_hal.h"
|
#include "hal/cpu_hal.h"
|
||||||
#include "regi2c_ctrl.h"
|
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "esp_rom_uart.h"
|
#include "esp_rom_uart.h"
|
||||||
#include "soc/efuse_reg.h"
|
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "soc/system_reg.h"
|
#include "soc/system_reg.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk_init";
|
static const char *TAG = "rtc_clk_init";
|
||||||
|
|
||||||
void rtc_clk_init(rtc_clk_config_t cfg)
|
void rtc_clk_init(rtc_clk_config_t cfg)
|
||||||
@@ -68,7 +63,7 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
rtc_clk_cpu_freq_get_config(&old_config);
|
rtc_clk_cpu_freq_get_config(&old_config);
|
||||||
uint32_t freq_before = old_config.freq_mhz;
|
uint32_t freq_before = old_config.freq_mhz;
|
||||||
|
|
||||||
root_clk_slt(cfg.root_clk_slt);
|
rtc_clk_select_root_clk(cfg.root_clk_slt);
|
||||||
bool res = rtc_clk_cpu_freq_mhz_to_config(cfg.cpu_freq_mhz, &new_config);
|
bool res = rtc_clk_cpu_freq_mhz_to_config(cfg.cpu_freq_mhz, &new_config);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
ESP_HW_LOGE(TAG, "invalid CPU frequency value");
|
ESP_HW_LOGE(TAG, "invalid CPU frequency value");
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/io_mux_reg.h"
|
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
#include "soc/gpio_reg.h"
|
#include "soc/gpio_reg.h"
|
||||||
#include "soc/spi_mem_reg.h"
|
#include "soc/spi_mem_reg.h"
|
||||||
@@ -207,41 +206,3 @@ void rtc_vddsdio_set_config(rtc_vddsdio_config_t config)
|
|||||||
val |= RTC_CNTL_SDIO_PD_EN;
|
val |= RTC_CNTL_SDIO_PD_EN;
|
||||||
REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val);
|
REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dig_gpio_setpd(uint32_t gpio_no, bool pd)
|
|
||||||
{
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_XTAL_32K_P_U + 4 * gpio_no, 0x1, pd, FUN_PD_S);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dig_gpio_setpu(uint32_t gpio_no, bool pu)
|
|
||||||
{
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_XTAL_32K_P_U + 4 * gpio_no, 0x1, pu, FUN_PU_S);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dig_gpio_in_en(uint32_t gpio_no, bool enable)
|
|
||||||
{
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_XTAL_32K_P_U + 4 * gpio_no, 0x1, enable, FUN_IE_S);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dig_gpio_out_en(uint32_t gpio_no, bool enable)
|
|
||||||
{
|
|
||||||
if (enable)
|
|
||||||
SET_PERI_REG_MASK(GPIO_ENABLE_W1TS_REG, 1 << gpio_no);
|
|
||||||
else
|
|
||||||
SET_PERI_REG_MASK(GPIO_ENABLE_W1TC_REG, 1 << gpio_no);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dig_gpio_mcusel(uint32_t gpio_no, uint32_t mcu_sel)
|
|
||||||
{
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_XTAL_32K_P_U + 4 * gpio_no, MCU_SEL, mcu_sel, MCU_SEL_S);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void rtc_gpio_hangup(uint32_t gpio_no)
|
|
||||||
{
|
|
||||||
dig_gpio_setpd(gpio_no, 0);
|
|
||||||
dig_gpio_setpu(gpio_no, 0);
|
|
||||||
dig_gpio_out_en(gpio_no, 0);
|
|
||||||
dig_gpio_in_en(gpio_no, 0);
|
|
||||||
dig_gpio_mcusel(gpio_no, 1);
|
|
||||||
}
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "esp32h2/rom/ets_sys.h"
|
#include "esp32h2/rom/ets_sys.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "soc/timer_group_reg.h"
|
#include "soc/timer_group_reg.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
@@ -44,15 +45,15 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
cal_clk = RTC_CAL_RC32K;
|
cal_clk = RTC_CAL_RC32K;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Enable requested clock (150k clock is always on) */
|
|
||||||
bool dig_32k_xtal_state = REG_GET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
|
||||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
|
|
||||||
|
|
||||||
|
/* Enable requested clock (150k clock is always on) */
|
||||||
|
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 dig_rc32k_state = REG_GET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN);
|
bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
|
||||||
if (cal_clk == RTC_CAL_RC32K && !dig_rc32k_state) {
|
if (cal_clk == RTC_CAL_RC32K && !dig_rc32k_enabled) {
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN, 1);
|
clk_ll_rc32k_digi_enable();
|
||||||
}
|
}
|
||||||
/* There may be another calibration process already running during we call this function,
|
/* There may be another calibration process already running during we call this function,
|
||||||
* so we should wait the last process is done.
|
* so we should wait the last process is done.
|
||||||
@@ -104,8 +105,15 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN, dig_rc32k_state);
|
/* 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 dig_rc32k was originally off and enabled due to calibration, then set back to off state */
|
||||||
|
if (cal_clk == RTC_CAL_RC32K && !dig_rc32k_enabled) {
|
||||||
|
clk_ll_rc32k_digi_disable();
|
||||||
|
}
|
||||||
|
|
||||||
return cal_val;
|
return cal_val;
|
||||||
}
|
}
|
||||||
|
@@ -16,50 +16,28 @@
|
|||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/sens_reg.h"
|
|
||||||
#include "soc/dport_reg.h"
|
|
||||||
#include "soc/efuse_reg.h"
|
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "regi2c_ctrl.h"
|
|
||||||
#include "regi2c_apll.h"
|
|
||||||
#include "regi2c_bbpll.h"
|
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk";
|
static const char *TAG = "rtc_clk";
|
||||||
|
|
||||||
#define RTC_PLL_FREQ_320M 320
|
|
||||||
#define RTC_PLL_FREQ_480M 480
|
|
||||||
#define DELAY_RTC_CLK_SWITCH 5
|
|
||||||
|
|
||||||
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
||||||
// On the ESP32-S2, 480MHz PLL is enabled at reset.
|
// On the ESP32-S2, 480MHz PLL is enabled at reset.
|
||||||
static uint32_t s_cur_pll_freq = RTC_PLL_FREQ_480M;
|
static uint32_t s_cur_pll_freq = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
|
|
||||||
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
||||||
static void rtc_clk_cpu_freq_to_8m(void);
|
static void rtc_clk_cpu_freq_to_8m(void);
|
||||||
|
|
||||||
void rtc_clk_32k_enable_internal(x32k_config_t cfg)
|
|
||||||
{
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtc_clk_32k_enable(bool enable)
|
void rtc_clk_32k_enable(bool enable)
|
||||||
{
|
{
|
||||||
if (enable) {
|
if (enable) {
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
|
||||||
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
|
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
|
||||||
rtc_clk_32k_enable_internal(cfg);
|
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
clk_ll_xtal32k_disable();
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,9 +45,7 @@ void rtc_clk_32k_enable_external(void)
|
|||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
|
||||||
/* TODO: external 32k source may need different settings */
|
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
|
||||||
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
|
|
||||||
rtc_clk_32k_enable_internal(cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
||||||
@@ -77,55 +53,50 @@ void rtc_clk_32k_bootstrap(uint32_t cycle)
|
|||||||
/* No special bootstrapping needed for ESP32-S2, 'cycle' argument is to keep the signature
|
/* No special bootstrapping needed for ESP32-S2, 'cycle' argument is to keep the signature
|
||||||
* same as for the ESP32. Just enable the XTAL here.
|
* same as for the ESP32. Just enable the XTAL here.
|
||||||
*/
|
*/
|
||||||
(void) cycle;
|
(void)cycle;
|
||||||
rtc_clk_32k_enable(true);
|
rtc_clk_32k_enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_32k_enabled(void)
|
bool rtc_clk_32k_enabled(void)
|
||||||
{
|
{
|
||||||
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
return clk_ll_xtal32k_is_enabled();
|
||||||
/* If xtal xpd is controlled by software */
|
|
||||||
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
|
||||||
/* If xtal xpd software control is on */
|
|
||||||
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
|
||||||
bool disabled = xtal_xpd_sw && !xtal_xpd_st;
|
|
||||||
return !disabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
||||||
{
|
{
|
||||||
if (clk_8m_en) {
|
if (clk_8m_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_enable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
|
||||||
esp_rom_delay_us(DELAY_8M_ENABLE);
|
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_disable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
|
||||||
}
|
}
|
||||||
/* d256 should be independent configured with 8M
|
/* d256 should be independent configured with 8M
|
||||||
* Maybe we can split this function into 8m and dmd256
|
* Maybe we can split this function into 8m and dmd256
|
||||||
*/
|
*/
|
||||||
if (d256_en) {
|
if (d256_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_enable();
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8m_enabled(void)
|
bool rtc_clk_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
return clk_ll_rc_fast_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8md256_enabled(void)
|
bool rtc_clk_8md256_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
return clk_ll_rc_fast_d256_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_apll_enable(bool enable)
|
void rtc_clk_apll_enable(bool enable)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1);
|
if (enable) {
|
||||||
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0);
|
clk_ll_apll_enable();
|
||||||
|
} else {
|
||||||
|
clk_ll_apll_disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm0, uint32_t *_sdm1, uint32_t *_sdm2)
|
||||||
@@ -165,9 +136,9 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// sdm2 = (int)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4
|
// sdm2 = (int)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4
|
||||||
sdm2 = (int)(((o_div + 2) * 2 * freq) / (rtc_xtal_freq * 1000000)) - 4;
|
sdm2 = (int)(((o_div + 2) * 2 * freq) / (rtc_xtal_freq * MHZ)) - 4;
|
||||||
// numrator = (((o_div + 2) * 2) * apll_freq / xtal_freq) - 4 - sdm2
|
// numrator = (((o_div + 2) * 2) * apll_freq / xtal_freq) - 4 - sdm2
|
||||||
float numrator = (((o_div + 2) * 2 * freq) / ((float)rtc_xtal_freq * 1000000)) - 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 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) {
|
if (numrator > 1.0 - (1.0 / 65536.0) / 2.0) {
|
||||||
sdm2++;
|
sdm2++;
|
||||||
@@ -179,7 +150,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
|
|||||||
// Get the closest sdm0
|
// Get the closest sdm0
|
||||||
sdm0 = (int)(numrator * 65536.0 + 0.5) % 256;
|
sdm0 = (int)(numrator * 65536.0 + 0.5) % 256;
|
||||||
}
|
}
|
||||||
uint32_t real_freq = (uint32_t)(rtc_xtal_freq * 1000000 * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) / (((float)o_div + 2) * 2));
|
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;
|
*_o_div = o_div;
|
||||||
*_sdm0 = sdm0;
|
*_sdm0 = sdm0;
|
||||||
*_sdm1 = sdm1;
|
*_sdm1 = sdm1;
|
||||||
@@ -189,41 +160,37 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
|
|||||||
|
|
||||||
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
|
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
|
||||||
{
|
{
|
||||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2);
|
clk_ll_apll_set_config(o_div, sdm0, sdm1, sdm2);
|
||||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0);
|
|
||||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1);
|
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_1);
|
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_2_REV1);
|
|
||||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
|
|
||||||
|
|
||||||
/* calibration */
|
/* calibration */
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_1);
|
clk_ll_apll_set_calibration();
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_2);
|
|
||||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_3);
|
|
||||||
|
|
||||||
/* wait for calibration end */
|
/* wait for calibration end */
|
||||||
while (!(REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_CAL_END))) {
|
while (!clk_ll_apll_calibration_is_done()) {
|
||||||
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
|
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
|
||||||
esp_rom_delay_us(1);
|
esp_rom_delay_us(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t slow_freq)
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
|
clk_ll_rtc_slow_set_src(clk_src);
|
||||||
|
|
||||||
/* Why we need to connect this clock to digital?
|
/* Why we need to connect this clock to digital?
|
||||||
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
|
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
|
||||||
*/
|
*/
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN,
|
if (clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||||
(slow_freq == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? 1 : 0);
|
clk_ll_xtal32k_digi_enable();
|
||||||
|
} else {
|
||||||
|
clk_ll_xtal32k_digi_disable();
|
||||||
|
}
|
||||||
|
|
||||||
esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
return clk_ll_rtc_slow_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||||
@@ -232,84 +199,45 @@ uint32_t rtc_clk_slow_freq_get_hz(void)
|
|||||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
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_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
||||||
|
default: return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t fast_freq)
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
|
clk_ll_rtc_fast_set_src(clk_src);
|
||||||
esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
return clk_ll_rtc_fast_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_disable(void)
|
static void rtc_clk_bbpll_disable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_disable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
s_cur_pll_freq = 0;
|
s_cur_pll_freq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_enable(void)
|
static void rtc_clk_bbpll_enable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_enable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
||||||
{
|
{
|
||||||
uint8_t div_ref;
|
|
||||||
uint8_t div7_0;
|
|
||||||
uint8_t dr1;
|
|
||||||
uint8_t dr3;
|
|
||||||
uint8_t dchgp;
|
|
||||||
uint8_t dcur;
|
|
||||||
|
|
||||||
assert(xtal_freq == RTC_XTAL_FREQ_40M);
|
assert(xtal_freq == RTC_XTAL_FREQ_40M);
|
||||||
|
|
||||||
if (pll_freq == RTC_PLL_FREQ_480M) {
|
/* Digital part */
|
||||||
/* Clear this register to let the digital part know 480M PLL is used */
|
clk_ll_bbpll_set_freq_mhz(pll_freq);
|
||||||
SET_PERI_REG_MASK(DPORT_CPU_PER_CONF_REG, DPORT_PLL_FREQ_SEL);
|
/* Analog part */
|
||||||
/* Configure 480M PLL */
|
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 8;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 4;
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
|
|
||||||
} else {
|
|
||||||
/* Clear this register to let the digital part know 320M PLL is used */
|
|
||||||
CLEAR_PERI_REG_MASK(DPORT_CPU_PER_CONF_REG, DPORT_PLL_FREQ_SEL);
|
|
||||||
/* Configure 320M PLL */
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 4;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 5;
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
|
|
||||||
}
|
|
||||||
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
|
||||||
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
|
||||||
uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
|
||||||
|
|
||||||
// Enable calibration by software
|
// Enable calibration by software
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_IR_CAL_ENX_CAP, 1);
|
clk_ll_bbpll_calibration_enable();
|
||||||
for (int ext_cap = 0; ext_cap < 16; ext_cap++) {
|
for (int ext_cap = 0; ext_cap < 16; ext_cap++) {
|
||||||
uint8_t cal_result;
|
if (clk_ll_bbpll_calibration_is_done(ext_cap)) {
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, ext_cap);
|
|
||||||
cal_result = REGI2C_READ_MASK(I2C_BBPLL, I2C_BBPLL_OR_CAL_CAP);
|
|
||||||
if (cal_result == 0) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ext_cap == 15) {
|
if (ext_cap == 15) {
|
||||||
@@ -328,23 +256,11 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
|||||||
*/
|
*/
|
||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||||
{
|
{
|
||||||
int dbias = DIG_DBIAS_80M_160M;
|
int dbias = (cpu_freq_mhz == 240) ? DIG_DBIAS_240M : DIG_DBIAS_80M_160M;
|
||||||
int per_conf = DPORT_CPUPERIOD_SEL_80;
|
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
||||||
if (cpu_freq_mhz == 80) {
|
clk_ll_cpu_set_divider(1);
|
||||||
/* nothing to do */
|
|
||||||
} else if (cpu_freq_mhz == 160) {
|
|
||||||
per_conf = DPORT_CPUPERIOD_SEL_160;
|
|
||||||
} else if (cpu_freq_mhz == 240) {
|
|
||||||
dbias = DIG_DBIAS_240M;
|
|
||||||
per_conf = DPORT_CPUPERIOD_SEL_240;
|
|
||||||
} else {
|
|
||||||
ESP_HW_LOGE(TAG, "invalid frequency");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, per_conf);
|
|
||||||
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_PRE_DIV_CNT, 0);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
|
||||||
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_PLL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||||
rtc_clk_apb_freq_update(80 * MHZ);
|
rtc_clk_apb_freq_update(80 * MHZ);
|
||||||
ets_update_cpu_frequency(cpu_freq_mhz);
|
ets_update_cpu_frequency(cpu_freq_mhz);
|
||||||
}
|
}
|
||||||
@@ -356,7 +272,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* ou
|
|||||||
uint32_t divider;
|
uint32_t divider;
|
||||||
uint32_t real_freq_mhz;
|
uint32_t real_freq_mhz;
|
||||||
|
|
||||||
uint32_t xtal_freq = RTC_XTAL_FREQ;
|
uint32_t xtal_freq = CLK_LL_XTAL_FREQ_MHZ;
|
||||||
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
||||||
divider = xtal_freq / freq_mhz;
|
divider = xtal_freq / freq_mhz;
|
||||||
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
||||||
@@ -370,17 +286,17 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* ou
|
|||||||
} else if (freq_mhz == 80) {
|
} else if (freq_mhz == 80) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 6;
|
divider = 6;
|
||||||
} else if (freq_mhz == 160) {
|
} else if (freq_mhz == 160) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 3;
|
divider = 3;
|
||||||
} else if (freq_mhz == 240) {
|
} else if (freq_mhz == 240) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 2;
|
divider = 2;
|
||||||
} else {
|
} else {
|
||||||
// unsupported frequency
|
// unsupported frequency
|
||||||
@@ -397,20 +313,21 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* ou
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t* config)
|
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t* config)
|
||||||
{
|
{
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL);
|
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||||
if (soc_clk_sel != DPORT_SOC_CLK_SEL_XTAL) {
|
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_XTAL) {
|
||||||
rtc_clk_cpu_freq_to_xtal(RTC_XTAL_FREQ, 1);
|
rtc_clk_cpu_freq_to_xtal(CLK_LL_XTAL_FREQ_MHZ, 1);
|
||||||
}
|
}
|
||||||
if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL && config->source_freq_mhz != s_cur_pll_freq) {
|
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL && config->source_freq_mhz != s_cur_pll_freq) {
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||||
if (config->div > 1) {
|
if (config->div > 1) {
|
||||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||||
}
|
}
|
||||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
||||||
rtc_clk_bbpll_enable();
|
rtc_clk_bbpll_enable();
|
||||||
rtc_clk_bbpll_configure(RTC_XTAL_FREQ, config->source_freq_mhz);
|
rtc_clk_bbpll_configure((rtc_xtal_freq_t)CLK_LL_XTAL_FREQ_MHZ, config->source_freq_mhz);
|
||||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||||
rtc_clk_cpu_freq_to_8m();
|
rtc_clk_cpu_freq_to_8m();
|
||||||
@@ -419,47 +336,38 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t* config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t* out_config)
|
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t* out_config)
|
||||||
{
|
{
|
||||||
soc_cpu_clk_src_t source;
|
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||||
uint32_t source_freq_mhz;
|
uint32_t source_freq_mhz;
|
||||||
uint32_t div;
|
uint32_t div;
|
||||||
uint32_t freq_mhz;
|
uint32_t freq_mhz;
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL);
|
switch (source) {
|
||||||
switch (soc_clk_sel) {
|
case SOC_CPU_CLK_SRC_XTAL: {
|
||||||
case DPORT_SOC_CLK_SEL_XTAL: {
|
div = clk_ll_cpu_get_divider();
|
||||||
source = SOC_CPU_CLK_SRC_XTAL;
|
source_freq_mhz = CLK_LL_XTAL_FREQ_MHZ;
|
||||||
div = REG_GET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_PRE_DIV_CNT) + 1;
|
|
||||||
source_freq_mhz = RTC_XTAL_FREQ;
|
|
||||||
freq_mhz = source_freq_mhz / div;
|
freq_mhz = source_freq_mhz / div;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DPORT_SOC_CLK_SEL_PLL: {
|
case SOC_CPU_CLK_SRC_PLL: {
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
|
||||||
uint32_t cpuperiod_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL);
|
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||||
uint32_t pllfreq_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_PLL_FREQ_SEL);
|
if (freq_mhz == CLK_LL_PLL_80M_FREQ_MHZ) {
|
||||||
source_freq_mhz = (pllfreq_sel) ? RTC_PLL_FREQ_480M : RTC_PLL_FREQ_320M;
|
div = (source_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) ? 6 : 4;
|
||||||
if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80) {
|
} else if (freq_mhz == CLK_LL_PLL_160M_FREQ_MHZ) {
|
||||||
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 6 : 4;
|
div = (source_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) ? 3 : 2;
|
||||||
freq_mhz = 80;
|
} else if (freq_mhz == CLK_LL_PLL_240M_FREQ_MHZ && source_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) {
|
||||||
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160) {
|
|
||||||
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 3 : 2;
|
|
||||||
div = 3;
|
|
||||||
freq_mhz = 160;
|
|
||||||
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_240) {
|
|
||||||
div = 2;
|
div = 2;
|
||||||
freq_mhz = 240;
|
|
||||||
} else {
|
} else {
|
||||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DPORT_SOC_CLK_SEL_8M:
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
source = SOC_CPU_CLK_SRC_RC_FAST;
|
|
||||||
source_freq_mhz = 8;
|
source_freq_mhz = 8;
|
||||||
div = 1;
|
div = 1;
|
||||||
freq_mhz = source_freq_mhz;
|
freq_mhz = source_freq_mhz;
|
||||||
break;
|
break;
|
||||||
case DPORT_SOC_CLK_SEL_APLL:
|
case SOC_CPU_CLK_SRC_APLL:
|
||||||
default:
|
default:
|
||||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||||
abort();
|
abort();
|
||||||
@@ -488,88 +396,77 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t* config)
|
|||||||
void rtc_clk_cpu_freq_set_xtal(void)
|
void rtc_clk_cpu_freq_set_xtal(void)
|
||||||
{
|
{
|
||||||
/* BBPLL is kept enabled */
|
/* BBPLL is kept enabled */
|
||||||
rtc_clk_cpu_freq_to_xtal(RTC_XTAL_FREQ, 1);
|
rtc_clk_cpu_freq_to_xtal(CLK_LL_XTAL_FREQ_MHZ, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch to XTAL frequency. Does not disable the PLL.
|
* Switch to XTAL frequency. Does not disable the PLL.
|
||||||
*/
|
*/
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(freq);
|
ets_update_cpu_frequency(freq);
|
||||||
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
||||||
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_PRE_DIV_CNT, div - 1);
|
clk_ll_cpu_set_divider(div);
|
||||||
/* no need to adjust the REF_TICK */
|
/* no need to adjust the REF_TICK, default register value already set it to 1MHz with any cpu clock source */
|
||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||||
rtc_clk_apb_freq_update(freq * MHZ);
|
rtc_clk_apb_freq_update(freq * MHZ);
|
||||||
/* lower the voltage */
|
/* lower the voltage */
|
||||||
if (freq <= 2) {
|
int dbias = (freq <= 2) ? DIG_DBIAS_2M : DIG_DBIAS_XTAL;
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_2M);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
|
||||||
} else {
|
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_cpu_freq_to_8m(void)
|
static void rtc_clk_cpu_freq_to_8m(void)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(8);
|
ets_update_cpu_frequency(8);
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
|
||||||
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_8M);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||||
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||||
{
|
{
|
||||||
// Note, inside esp32s2-only code it's better to use RTC_XTAL_FREQ constant
|
// Note, inside esp32s2-only code it's better to use CLK_LL_XTAL_FREQ_MHZ constant
|
||||||
return RTC_XTAL_FREQ;
|
return (rtc_xtal_freq_t)CLK_LL_XTAL_FREQ_MHZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_APB_FREQ_REG, clk_val_to_reg_val(apb_freq >> 12));
|
clk_ll_apb_store_freq_hz(apb_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_apb_freq_get(void)
|
uint32_t rtc_clk_apb_freq_get(void)
|
||||||
{
|
{
|
||||||
uint32_t freq_hz = reg_val_to_clk_val(READ_PERI_REG(RTC_APB_FREQ_REG)) << 12;
|
return clk_ll_apb_load_freq_hz();
|
||||||
// round to the nearest MHz
|
|
||||||
freq_hz += MHZ / 2;
|
|
||||||
uint32_t remainder = freq_hz % MHZ;
|
|
||||||
return freq_hz - remainder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_divider_set(uint32_t div)
|
void rtc_clk_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
clk_ll_rc_slow_set_divider(div + 1);
|
||||||
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, div);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_divider_set(uint32_t div)
|
void rtc_clk_8m_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
clk_ll_rc_fast_set_divider(div + 1);
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, div);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_enable(void)
|
void rtc_dig_clk8m_enable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_enable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_disable(void)
|
void rtc_dig_clk8m_disable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_disable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_dig_8m_enabled(void)
|
bool rtc_dig_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
return clk_ll_rc_fast_digi_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Name used in libphy.a:phy_chip_v7.o
|
/* Name used in libphy.a:phy_chip_v7.o
|
||||||
|
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define MHZ (1000000)
|
|
||||||
|
|
||||||
#define DPORT_CPUPERIOD_SEL_80 0
|
|
||||||
#define DPORT_CPUPERIOD_SEL_160 1
|
|
||||||
#define DPORT_CPUPERIOD_SEL_240 2
|
|
||||||
|
|
||||||
#define DPORT_SOC_CLK_SEL_XTAL 0
|
|
||||||
#define DPORT_SOC_CLK_SEL_PLL 1
|
|
||||||
#define DPORT_SOC_CLK_SEL_8M 2
|
|
||||||
#define DPORT_SOC_CLK_SEL_APLL 3
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
|
||||||
|
|
||||||
/* Values of RTC_XTAL_FREQ_REG and RTC_APB_FREQ_REG are stored as two copies in
|
|
||||||
* lower and upper 16-bit halves. These are the routines to work with such a
|
|
||||||
* representation.
|
|
||||||
*/
|
|
||||||
static inline bool clk_val_is_valid(uint32_t val) {
|
|
||||||
return (val & 0xffff) == ((val >> 16) & 0xffff) &&
|
|
||||||
val != 0 &&
|
|
||||||
val != UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t reg_val_to_clk_val(uint32_t val) {
|
|
||||||
return val & UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t clk_val_to_reg_val(uint32_t val) {
|
|
||||||
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@@ -16,10 +16,9 @@
|
|||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
#include "soc/syscon_reg.h"
|
#include "soc/syscon_reg.h"
|
||||||
#include "hal/cpu_hal.h"
|
#include "hal/cpu_hal.h"
|
||||||
#include "regi2c_ctrl.h"
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
|
|
||||||
static const char* TAG = "rtc_clk_init";
|
static const char* TAG = "rtc_clk_init";
|
||||||
|
|
||||||
@@ -44,9 +43,11 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
/* Configure 8M clock division */
|
/* Configure 8M clock division */
|
||||||
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
||||||
|
|
||||||
|
/* Reset (disable) i2c internal bus for all regi2c registers */
|
||||||
|
regi2c_ctrl_ll_i2c_reset(); // TODO: This should be move out from rtc_clk_init
|
||||||
/* Enable the internal bus used to configure PLLs */
|
/* Enable the internal bus used to configure PLLs */
|
||||||
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
regi2c_ctrl_ll_i2c_bbpll_enable(); // TODO: This should be moved to bbpll_set_config
|
||||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_APLL_M | I2C_BBPLL_M);
|
regi2c_ctrl_ll_i2c_apll_enable(); // TODO: This should be moved to apll_set_config
|
||||||
|
|
||||||
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
||||||
esp_rom_uart_tx_wait_idle(0);
|
esp_rom_uart_tx_wait_idle(0);
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "soc/timer_group_reg.h"
|
#include "soc/timer_group_reg.h"
|
||||||
|
|
||||||
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||||
@@ -151,13 +152,13 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Enable requested clock (90k clock is always on) */
|
/* Enable requested clock (90k clock is always on) */
|
||||||
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
|
||||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
|
clk_ll_xtal32k_digi_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cal_clk == RTC_CAL_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t cal_val;
|
uint32_t cal_val;
|
||||||
@@ -169,10 +170,13 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, ui
|
|||||||
|
|
||||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
|
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
|
/* 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_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
return cal_val;
|
return cal_val;
|
||||||
|
@@ -13,55 +13,35 @@
|
|||||||
#include "esp32s3/rom/ets_sys.h"
|
#include "esp32s3/rom/ets_sys.h"
|
||||||
#include "esp32s3/rom/rtc.h"
|
#include "esp32s3/rom/rtc.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
|
||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
#include "soc/sens_reg.h"
|
|
||||||
#include "soc/dport_reg.h"
|
|
||||||
#include "soc/efuse_reg.h"
|
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "soc/system_reg.h"
|
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "regi2c_ctrl.h"
|
|
||||||
#include "regi2c_dig_reg.h"
|
|
||||||
#include "regi2c_bbpll.h"
|
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
#include "hal/usb_serial_jtag_ll.h"
|
#include "hal/usb_serial_jtag_ll.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
|
#include "esp_private/regi2c_ctrl.h"
|
||||||
|
#include "regi2c_dig_reg.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk";
|
static const char *TAG = "rtc_clk";
|
||||||
|
|
||||||
#define RTC_PLL_FREQ_320M 320
|
|
||||||
#define RTC_PLL_FREQ_480M 480
|
|
||||||
#define DELAY_RTC_CLK_SWITCH 5
|
|
||||||
|
|
||||||
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
||||||
static uint32_t s_cur_pll_freq;
|
static uint32_t s_cur_pll_freq;
|
||||||
|
|
||||||
static uint32_t s_apb_freq;
|
static uint32_t s_apb_freq;
|
||||||
|
|
||||||
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
||||||
static void rtc_clk_cpu_freq_to_8m(void);
|
static void rtc_clk_cpu_freq_to_8m(void);
|
||||||
static bool rtc_clk_set_bbpll_always_on(void);
|
static bool rtc_clk_set_bbpll_always_on(void);
|
||||||
|
|
||||||
void rtc_clk_32k_enable_internal(x32k_config_t cfg)
|
|
||||||
{
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
|
||||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtc_clk_32k_enable(bool enable)
|
void rtc_clk_32k_enable(bool enable)
|
||||||
{
|
{
|
||||||
if (enable) {
|
if (enable) {
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
|
||||||
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
|
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
|
||||||
rtc_clk_32k_enable_internal(cfg);
|
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
clk_ll_xtal32k_disable();
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,9 +49,7 @@ void rtc_clk_32k_enable_external(void)
|
|||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
|
||||||
/* TODO: external 32k source may need different settings */
|
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
|
||||||
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
|
|
||||||
rtc_clk_32k_enable_internal(cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
||||||
@@ -79,49 +57,41 @@ void rtc_clk_32k_bootstrap(uint32_t cycle)
|
|||||||
/* No special bootstrapping needed for ESP32-S3, 'cycle' argument is to keep the signature
|
/* No special bootstrapping needed for ESP32-S3, 'cycle' argument is to keep the signature
|
||||||
* same as for the ESP32. Just enable the XTAL here.
|
* same as for the ESP32. Just enable the XTAL here.
|
||||||
*/
|
*/
|
||||||
(void) cycle;
|
(void)cycle;
|
||||||
rtc_clk_32k_enable(true);
|
rtc_clk_32k_enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_32k_enabled(void)
|
bool rtc_clk_32k_enabled(void)
|
||||||
{
|
{
|
||||||
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
return clk_ll_xtal32k_is_enabled();
|
||||||
/* If xtal xpd is controlled by software */
|
|
||||||
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
|
||||||
/* If xtal xpd software control is on */
|
|
||||||
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
|
||||||
bool disabled = xtal_xpd_sw && !xtal_xpd_st;
|
|
||||||
return !disabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
||||||
{
|
{
|
||||||
if (clk_8m_en) {
|
if (clk_8m_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_enable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
|
||||||
esp_rom_delay_us(DELAY_8M_ENABLE);
|
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
clk_ll_rc_fast_disable();
|
||||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
|
||||||
}
|
}
|
||||||
/* d256 should be independent configured with 8M
|
/* d256 should be independent configured with 8M
|
||||||
* Maybe we can split this function into 8m and dmd256
|
* Maybe we can split this function into 8m and dmd256
|
||||||
*/
|
*/
|
||||||
if (d256_en) {
|
if (d256_en) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_enable();
|
||||||
} else {
|
} else {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
clk_ll_rc_fast_d256_disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8m_enabled(void)
|
bool rtc_clk_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
return clk_ll_rc_fast_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_8md256_enabled(void)
|
bool rtc_clk_8md256_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
return clk_ll_rc_fast_d256_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wait_dig_dbias_valid(uint64_t rtc_cycles)
|
static void wait_dig_dbias_valid(uint64_t rtc_cycles)
|
||||||
@@ -136,22 +106,25 @@ static void wait_dig_dbias_valid(uint64_t rtc_cycles)
|
|||||||
rtc_clk_cal(cal_clk, rtc_cycles);
|
rtc_clk_cal(cal_clk, rtc_cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t slow_freq)
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
|
clk_ll_rtc_slow_set_src(clk_src);
|
||||||
|
|
||||||
/* Why we need to connect this clock to digital?
|
/* Why we need to connect this clock to digital?
|
||||||
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
|
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
|
||||||
*/
|
*/
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN,
|
if (clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||||
(slow_freq == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? 1 : 0);
|
clk_ll_xtal32k_digi_enable();
|
||||||
|
} else {
|
||||||
|
clk_ll_xtal32k_digi_disable();
|
||||||
|
}
|
||||||
|
|
||||||
esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
return clk_ll_rtc_slow_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||||
@@ -160,132 +133,45 @@ uint32_t rtc_clk_slow_freq_get_hz(void)
|
|||||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
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_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256: return SOC_CLK_RC_FAST_D256_FREQ_APPROX;
|
||||||
|
default: return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t fast_freq)
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
|
||||||
{
|
{
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
|
clk_ll_rtc_fast_set_src(clk_src);
|
||||||
esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
||||||
{
|
{
|
||||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
return clk_ll_rtc_fast_get_src();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_disable(void)
|
static void rtc_clk_bbpll_disable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_disable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
s_cur_pll_freq = 0;
|
s_cur_pll_freq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_bbpll_enable(void)
|
static void rtc_clk_bbpll_enable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
clk_ll_bbpll_enable();
|
||||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
||||||
{
|
{
|
||||||
uint8_t div_ref;
|
/* Digital part */
|
||||||
uint8_t div7_0;
|
clk_ll_bbpll_set_freq_mhz(pll_freq);
|
||||||
uint8_t dr1;
|
/* Analog part */
|
||||||
uint8_t dr3;
|
|
||||||
uint8_t dchgp;
|
|
||||||
uint8_t dcur;
|
|
||||||
uint8_t dbias;
|
|
||||||
|
|
||||||
/* BBPLL CALIBRATION START */
|
/* BBPLL CALIBRATION START */
|
||||||
CLEAR_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
regi2c_ctrl_ll_bbpll_calibration_start();
|
||||||
SET_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||||
|
|
||||||
if (pll_freq == RTC_PLL_FREQ_480M) {
|
|
||||||
/* Set this register to let the digital part know 480M PLL is used */
|
|
||||||
SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
|
||||||
/* Configure 480M PLL */
|
|
||||||
switch (xtal_freq) {
|
|
||||||
case RTC_XTAL_FREQ_40M:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 8;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
case RTC_XTAL_FREQ_32M:
|
|
||||||
div_ref = 1;
|
|
||||||
div7_0 = 26;
|
|
||||||
dr1 = 1;
|
|
||||||
dr3 = 1;
|
|
||||||
dchgp = 4;
|
|
||||||
dcur = 0;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 8;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
|
|
||||||
} else {
|
|
||||||
/* Clear this register to let the digital part know 320M PLL is used */
|
|
||||||
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
|
||||||
/* Configure 320M PLL */
|
|
||||||
switch (xtal_freq) {
|
|
||||||
case RTC_XTAL_FREQ_40M:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 4;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
case RTC_XTAL_FREQ_32M:
|
|
||||||
div_ref = 1;
|
|
||||||
div7_0 = 6;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
div_ref = 0;
|
|
||||||
div7_0 = 4;
|
|
||||||
dr1 = 0;
|
|
||||||
dr3 = 0;
|
|
||||||
dchgp = 5;
|
|
||||||
dcur = 3;
|
|
||||||
dbias = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
|
|
||||||
}
|
|
||||||
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
|
||||||
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
|
||||||
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
|
||||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
|
||||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
|
|
||||||
|
|
||||||
/* WAIT CALIBRATION DONE */
|
/* WAIT CALIBRATION DONE */
|
||||||
while (!GET_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE));
|
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
|
||||||
/* BBPLL CALIBRATION STOP */
|
/* BBPLL CALIBRATION STOP */
|
||||||
CLEAR_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
regi2c_ctrl_ll_bbpll_calibration_stop();
|
||||||
SET_PERI_REG_MASK(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
|
||||||
s_cur_pll_freq = pll_freq;
|
s_cur_pll_freq = pll_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,24 +182,15 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
|||||||
*/
|
*/
|
||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||||
{
|
{
|
||||||
int dbias = DIG_DBIAS_80M_160M;
|
int dbias = (cpu_freq_mhz == 240) ? DIG_DBIAS_240M : DIG_DBIAS_80M_160M;
|
||||||
int per_conf = DPORT_CPUPERIOD_SEL_80;
|
|
||||||
if (cpu_freq_mhz == 80) {
|
|
||||||
/* nothing to do */
|
|
||||||
} else if (cpu_freq_mhz == 160) {
|
|
||||||
per_conf = DPORT_CPUPERIOD_SEL_160;
|
|
||||||
} else if (cpu_freq_mhz == 240) {
|
|
||||||
dbias = DIG_DBIAS_240M;
|
|
||||||
per_conf = DPORT_CPUPERIOD_SEL_240;
|
|
||||||
} else {
|
|
||||||
ESP_HW_LOGE(TAG, "invalid frequency");
|
|
||||||
}
|
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias);
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias);
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, dbias);
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, dbias);
|
||||||
wait_dig_dbias_valid(2);
|
wait_dig_dbias_valid(2);
|
||||||
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, per_conf);
|
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_PLL);
|
clk_ll_cpu_set_divider(1);
|
||||||
|
/* switch clock source */
|
||||||
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||||
rtc_clk_apb_freq_update(80 * MHZ);
|
rtc_clk_apb_freq_update(80 * MHZ);
|
||||||
ets_update_cpu_frequency(cpu_freq_mhz);
|
ets_update_cpu_frequency(cpu_freq_mhz);
|
||||||
}
|
}
|
||||||
@@ -325,7 +202,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
uint32_t divider;
|
uint32_t divider;
|
||||||
uint32_t real_freq_mhz;
|
uint32_t real_freq_mhz;
|
||||||
|
|
||||||
uint32_t xtal_freq = (uint32_t) rtc_clk_xtal_freq_get();
|
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
||||||
divider = xtal_freq / freq_mhz;
|
divider = xtal_freq / freq_mhz;
|
||||||
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
||||||
@@ -339,17 +216,17 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
} else if (freq_mhz == 80) {
|
} else if (freq_mhz == 80) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 6;
|
divider = 6;
|
||||||
} else if (freq_mhz == 160) {
|
} else if (freq_mhz == 160) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 3;
|
divider = 3;
|
||||||
} else if (freq_mhz == 240) {
|
} else if (freq_mhz == 240) {
|
||||||
real_freq_mhz = freq_mhz;
|
real_freq_mhz = freq_mhz;
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
source = SOC_CPU_CLK_SRC_PLL;
|
||||||
source_freq_mhz = RTC_PLL_FREQ_480M;
|
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
divider = 2;
|
divider = 2;
|
||||||
} else {
|
} else {
|
||||||
// unsupported frequency
|
// unsupported frequency
|
||||||
@@ -366,22 +243,22 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||||
{
|
{
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||||
if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) {
|
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !rtc_clk_set_bbpll_always_on()) {
|
||||||
// We don't turn off the bbpll if some consumers only depends on bbpll
|
// We don't turn off the bbpll if some consumers only depends on bbpll
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
||||||
if (soc_clk_sel != DPORT_SOC_CLK_SEL_PLL) {
|
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
|
||||||
rtc_clk_bbpll_enable();
|
rtc_clk_bbpll_enable();
|
||||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
|
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
|
||||||
}
|
}
|
||||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||||
rtc_clk_cpu_freq_to_8m();
|
rtc_clk_cpu_freq_to_8m();
|
||||||
if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) {
|
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !rtc_clk_set_bbpll_always_on()) {
|
||||||
// We don't turn off the bbpll if some consumers only depends on bbpll
|
// We don't turn off the bbpll if some consumers only depends on bbpll
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
}
|
}
|
||||||
@@ -390,43 +267,34 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
||||||
{
|
{
|
||||||
soc_cpu_clk_src_t source;
|
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||||
uint32_t source_freq_mhz;
|
uint32_t source_freq_mhz;
|
||||||
uint32_t div;
|
uint32_t div;
|
||||||
uint32_t freq_mhz;
|
uint32_t freq_mhz;
|
||||||
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
switch (source) {
|
||||||
switch (soc_clk_sel) {
|
case SOC_CPU_CLK_SRC_XTAL: {
|
||||||
case DPORT_SOC_CLK_SEL_XTAL: {
|
div = clk_ll_cpu_get_divider();
|
||||||
source = SOC_CPU_CLK_SRC_XTAL;
|
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||||
div = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
|
||||||
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
|
|
||||||
freq_mhz = source_freq_mhz / div;
|
freq_mhz = source_freq_mhz / div;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DPORT_SOC_CLK_SEL_PLL: {
|
case SOC_CPU_CLK_SRC_PLL: {
|
||||||
source = SOC_CPU_CLK_SRC_PLL;
|
freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
|
||||||
uint32_t cpuperiod_sel = DPORT_REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
|
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||||
uint32_t pllfreq_sel = DPORT_REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
if (freq_mhz == CLK_LL_PLL_80M_FREQ_MHZ) {
|
||||||
source_freq_mhz = (pllfreq_sel) ? RTC_PLL_FREQ_480M : RTC_PLL_FREQ_320M;
|
div = (source_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) ? 6 : 4;
|
||||||
if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80) {
|
} else if (freq_mhz == CLK_LL_PLL_160M_FREQ_MHZ) {
|
||||||
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 6 : 4;
|
div = (source_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) ? 3 : 2;
|
||||||
freq_mhz = 80;
|
} else if (freq_mhz == CLK_LL_PLL_240M_FREQ_MHZ && source_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) {
|
||||||
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160) {
|
|
||||||
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 3 : 2;
|
|
||||||
div = 3;
|
|
||||||
freq_mhz = 160;
|
|
||||||
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_240) {
|
|
||||||
div = 2;
|
div = 2;
|
||||||
freq_mhz = 240;
|
|
||||||
} else {
|
} else {
|
||||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DPORT_SOC_CLK_SEL_8M:
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
source = SOC_CPU_CLK_SRC_RC_FAST;
|
source_freq_mhz = 20;
|
||||||
source_freq_mhz = 8;
|
|
||||||
div = 1;
|
div = 1;
|
||||||
freq_mhz = source_freq_mhz;
|
freq_mhz = source_freq_mhz;
|
||||||
break;
|
break;
|
||||||
@@ -457,10 +325,9 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
|||||||
|
|
||||||
void rtc_clk_cpu_freq_set_xtal(void)
|
void rtc_clk_cpu_freq_set_xtal(void)
|
||||||
{
|
{
|
||||||
int freq_mhz = (int) rtc_clk_xtal_freq_get();
|
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||||
|
|
||||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||||
|
|
||||||
// We don't turn off the bbpll if some consumers only depends on bbpll
|
// We don't turn off the bbpll if some consumers only depends on bbpll
|
||||||
if (!rtc_clk_set_bbpll_always_on()) {
|
if (!rtc_clk_set_bbpll_always_on()) {
|
||||||
rtc_clk_bbpll_disable();
|
rtc_clk_bbpll_disable();
|
||||||
@@ -470,48 +337,44 @@ void rtc_clk_cpu_freq_set_xtal(void)
|
|||||||
/**
|
/**
|
||||||
* Switch to XTAL frequency. Does not disable the PLL.
|
* Switch to XTAL frequency. Does not disable the PLL.
|
||||||
*/
|
*/
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(freq);
|
ets_update_cpu_frequency(freq);
|
||||||
/* set digital voltage for different cpu freq from xtal */
|
/* set digital voltage for different cpu freq from xtal */
|
||||||
if (freq <= 2) {
|
int dbias = (freq <= 2) ? DIG_DBIAS_2M : DIG_DBIAS_XTAL;
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_2M);
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias);
|
||||||
} else {
|
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
|
|
||||||
}
|
|
||||||
wait_dig_dbias_valid(2);
|
wait_dig_dbias_valid(2);
|
||||||
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, div - 1);
|
clk_ll_cpu_set_divider(div);
|
||||||
/* no need to adjust the REF_TICK */
|
|
||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||||
rtc_clk_apb_freq_update(freq * MHZ);
|
rtc_clk_apb_freq_update(freq * MHZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_cpu_freq_to_8m(void)
|
static void rtc_clk_cpu_freq_to_8m(void)
|
||||||
{
|
{
|
||||||
ets_update_cpu_frequency(8);
|
ets_update_cpu_frequency(20);
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
|
||||||
wait_dig_dbias_valid(2);
|
wait_dig_dbias_valid(2);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_8M);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||||
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||||
{
|
{
|
||||||
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||||
if (!clk_val_is_valid(xtal_freq_reg)) {
|
if (xtal_freq_mhz == 0) {
|
||||||
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value: 0x%08x", xtal_freq_reg);
|
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
|
||||||
return RTC_XTAL_FREQ_40M;
|
return RTC_XTAL_FREQ_40M;
|
||||||
}
|
}
|
||||||
return reg_val_to_clk_val(xtal_freq_reg);
|
return (rtc_xtal_freq_t)xtal_freq_mhz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
||||||
{
|
{
|
||||||
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, clk_val_to_reg_val(xtal_freq));
|
clk_ll_xtal_store_freq_mhz(xtal_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
||||||
@@ -526,33 +389,29 @@ uint32_t rtc_clk_apb_freq_get(void)
|
|||||||
|
|
||||||
void rtc_clk_divider_set(uint32_t div)
|
void rtc_clk_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
clk_ll_rc_slow_set_divider(div + 1);
|
||||||
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, div);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_clk_8m_divider_set(uint32_t div)
|
void rtc_clk_8m_divider_set(uint32_t div)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
clk_ll_rc_fast_set_divider(div + 1);
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, div);
|
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_enable(void)
|
void rtc_dig_clk8m_enable(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_enable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_dig_clk8m_disable(void)
|
void rtc_dig_clk8m_disable(void)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
clk_ll_rc_fast_digi_disable();
|
||||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_dig_8m_enabled(void)
|
bool rtc_dig_8m_enabled(void)
|
||||||
{
|
{
|
||||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
return clk_ll_rc_fast_digi_is_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rtc_clk_set_bbpll_always_on(void)
|
static bool rtc_clk_set_bbpll_always_on(void)
|
||||||
|
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define MHZ (1000000)
|
|
||||||
|
|
||||||
#define DPORT_CPUPERIOD_SEL_80 0
|
|
||||||
#define DPORT_CPUPERIOD_SEL_160 1
|
|
||||||
#define DPORT_CPUPERIOD_SEL_240 2
|
|
||||||
|
|
||||||
#define DPORT_SOC_CLK_SEL_XTAL 0
|
|
||||||
#define DPORT_SOC_CLK_SEL_PLL 1
|
|
||||||
#define DPORT_SOC_CLK_SEL_8M 2
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
|
||||||
|
|
||||||
/* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
|
||||||
* halves. These are the routines to work with that representation.
|
|
||||||
*/
|
|
||||||
static inline bool clk_val_is_valid(uint32_t val)
|
|
||||||
{
|
|
||||||
return (val & 0xffff) == ((val >> 16) & 0xffff) &&
|
|
||||||
val != 0 &&
|
|
||||||
val != UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t reg_val_to_clk_val(uint32_t val)
|
|
||||||
{
|
|
||||||
return val & UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t clk_val_to_reg_val(uint32_t val)
|
|
||||||
{
|
|
||||||
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@@ -12,11 +12,9 @@
|
|||||||
#include "esp32s3/rom/rtc.h"
|
#include "esp32s3/rom/rtc.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/syscon_reg.h"
|
|
||||||
#include "hal/cpu_hal.h"
|
#include "hal/cpu_hal.h"
|
||||||
#include "regi2c_ctrl.h"
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
#include "esp_hw_log.h"
|
#include "esp_hw_log.h"
|
||||||
#include "rtc_clk_common.h"
|
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk_init";
|
static const char *TAG = "rtc_clk_init";
|
||||||
|
|
||||||
@@ -41,9 +39,10 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
/* Configure 8M clock division */
|
/* Configure 8M clock division */
|
||||||
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
||||||
|
|
||||||
/* Enable the internal bus used to configure PLLs */
|
/* Reset (disable) i2c internal bus for all regi2c registers */
|
||||||
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
regi2c_ctrl_ll_i2c_reset(); // TODO: This should be move out from rtc_clk_init
|
||||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_BBPLL_M);
|
/* Enable the internal bus used to configure BBPLL */
|
||||||
|
regi2c_ctrl_ll_i2c_bbpll_enable(); // TODO: This should be moved to bbpll_set_config
|
||||||
|
|
||||||
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
||||||
esp_rom_uart_tx_wait_idle(0);
|
esp_rom_uart_tx_wait_idle(0);
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "soc/timer_group_reg.h"
|
#include "soc/timer_group_reg.h"
|
||||||
|
|
||||||
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||||
@@ -47,13 +48,13 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Enable requested clock (150k clock is always on) */
|
/* Enable requested clock (150k clock is always on) */
|
||||||
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
|
||||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
|
clk_ll_xtal32k_digi_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cal_clk == RTC_CAL_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_enable();
|
||||||
}
|
}
|
||||||
/* There may be another calibration process already running during we call this function,
|
/* There may be another calibration process already running during we call this function,
|
||||||
* so we should wait the last process is done.
|
* so we should wait the last process is done.
|
||||||
@@ -106,10 +107,13 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
|||||||
}
|
}
|
||||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
|
|
||||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
|
/* 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_8MD256) {
|
if (cal_clk == RTC_CAL_8MD256) {
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
|
clk_ll_rc_fast_d256_digi_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
return cal_val;
|
return cal_val;
|
||||||
|
@@ -213,7 +213,7 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]")
|
|||||||
|
|
||||||
rtc_cpu_freq_config_t config_xtal, config_default;
|
rtc_cpu_freq_config_t config_xtal, config_default;
|
||||||
rtc_clk_cpu_freq_get_config(&config_default);
|
rtc_clk_cpu_freq_get_config(&config_default);
|
||||||
rtc_clk_cpu_freq_mhz_to_config((int) rtc_clk_xtal_freq_get(), &config_xtal);
|
rtc_clk_cpu_freq_mhz_to_config(esp_clk_xtal_freq() / MHZ, &config_xtal);
|
||||||
|
|
||||||
esp_sleep_enable_timer_wakeup(1000);
|
esp_sleep_enable_timer_wakeup(1000);
|
||||||
for (int i = 0; i < 1000; ++i) {
|
for (int i = 0; i < 1000; ++i) {
|
||||||
|
859
components/hal/esp32/include/hal/clk_tree_ll.h
Normal file
859
components/hal/esp32/include/hal/clk_tree_ll.h
Normal file
@@ -0,0 +1,859 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/clk_tree_defs.h"
|
||||||
|
#include "soc/rtc.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "soc/rtc_io_reg.h"
|
||||||
|
#include "soc/dport_reg.h"
|
||||||
|
#include "soc/syscon_reg.h"
|
||||||
|
#include "esp_private/regi2c_ctrl.h"
|
||||||
|
#include "regi2c_bbpll.h"
|
||||||
|
#include "regi2c_apll.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "esp32/rom/rtc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MHZ (1000000)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
|
||||||
|
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
|
||||||
|
#define CLK_LL_PLL_240M_FREQ_MHZ (240)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
|
||||||
|
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
|
||||||
|
|
||||||
|
/* BBPLL configuration parameters at reset */
|
||||||
|
#define CLK_LL_BBPLL_IR_CAL_DELAY_VAL 0x18
|
||||||
|
#define CLK_LL_BBPLL_IR_CAL_EXT_CAP_VAL 0x20
|
||||||
|
#define CLK_LL_BBPLL_OC_ENB_FCAL_VAL 0x9a
|
||||||
|
#define CLK_LL_BBPLL_OC_ENB_VCON_VAL 0x00
|
||||||
|
#define CLK_LL_BBPLL_BBADC_CAL_7_0_VAL 0x00
|
||||||
|
|
||||||
|
/* BBPLL configuration parameters */
|
||||||
|
#define CLK_LL_BBPLL_ENDIV5_VAL_320M 0x43
|
||||||
|
#define CLK_LL_BBPLL_BBADC_DSMP_VAL_320M 0x84
|
||||||
|
#define CLK_LL_BBPLL_ENDIV5_VAL_480M 0xc3
|
||||||
|
#define CLK_LL_BBPLL_BBADC_DSMP_VAL_480M 0x74
|
||||||
|
|
||||||
|
/* APLL configuration parameters */
|
||||||
|
#define CLK_LL_APLL_SDM_STOP_VAL_1 0x09
|
||||||
|
#define CLK_LL_APLL_SDM_STOP_VAL_2_REV0 0x69
|
||||||
|
#define CLK_LL_APLL_SDM_STOP_VAL_2_REV1 0x49
|
||||||
|
|
||||||
|
/* APLL calibration parameters */
|
||||||
|
#define CLK_LL_APLL_CAL_DELAY_1 0x0f
|
||||||
|
#define CLK_LL_APLL_CAL_DELAY_2 0x3f
|
||||||
|
#define CLK_LL_APLL_CAL_DELAY_3 0x1f
|
||||||
|
|
||||||
|
/* XTAL32K configuration parameters for 32kHz crystal */
|
||||||
|
#define CLK_LL_XTAL_32K_DAC_VAL 1
|
||||||
|
#define CLK_LL_XTAL_32K_DRES_VAL 3
|
||||||
|
#define CLK_LL_XTAL_32K_DBIAS_VAL 0
|
||||||
|
|
||||||
|
/* XTAL32K configuration parameters for external oscillator clock */
|
||||||
|
#define CLK_LL_XTAL_32K_EXT_DAC_VAL 2
|
||||||
|
#define CLK_LL_XTAL_32K_EXT_DRES_VAL 3
|
||||||
|
#define CLK_LL_XTAL_32K_EXT_DBIAS_VAL 1
|
||||||
|
|
||||||
|
/* XTAL32K configuration parameters for fast startup with bootstrap */
|
||||||
|
#define CLK_LL_XTAL_32K_BOOTSTRAP_DAC_VAL 3
|
||||||
|
#define CLK_LL_XTAL_32K_BOOTSTRAP_DRES_VAL 3
|
||||||
|
#define CLK_LL_XTAL_32K_BOOTSTRAP_DBIAS_VAL 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK enable modes
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
|
||||||
|
} clk_ll_xtal32k_enable_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up internal I2C bus
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_i2c_pu(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down internal I2C bus
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_i2c_pd(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
|
||||||
|
RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
// Reset BBPLL configuration
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_IR_CAL_DELAY, CLK_LL_BBPLL_IR_CAL_DELAY_VAL);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, CLK_LL_BBPLL_IR_CAL_EXT_CAP_VAL);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_ENB_FCAL, CLK_LL_BBPLL_OC_ENB_FCAL_VAL);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_ENB_VCON, CLK_LL_BBPLL_OC_ENB_VCON_VAL);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_BBADC_CAL_7_0, CLK_LL_BBPLL_BBADC_CAL_7_0_VAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
|
||||||
|
RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up APLL circuit
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_apll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down APLL circuit
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_apll_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whether APLL is under force power down state
|
||||||
|
*
|
||||||
|
* @return True if APLL is under force power down; otherwise false
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_apll_is_fpd(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set APLL configuration
|
||||||
|
*
|
||||||
|
* @param is_rev0 True if chip version is rev0
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_apll_set_config(bool is_rev0, uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
|
||||||
|
{
|
||||||
|
uint8_t sdm_stop_val_2 = CLK_LL_APLL_SDM_STOP_VAL_2_REV1;
|
||||||
|
if (is_rev0) {
|
||||||
|
sdm0 = 0;
|
||||||
|
sdm1 = 0;
|
||||||
|
sdm_stop_val_2 = CLK_LL_APLL_SDM_STOP_VAL_2_REV0;
|
||||||
|
}
|
||||||
|
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2);
|
||||||
|
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0);
|
||||||
|
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1);
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_1);
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, sdm_stop_val_2);
|
||||||
|
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set APLL calibration parameters
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_apll_set_calibration(void)
|
||||||
|
{
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, CLK_LL_APLL_CAL_DELAY_1);
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, CLK_LL_APLL_CAL_DELAY_2);
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, CLK_LL_APLL_CAL_DELAY_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whether APLL calibration is done
|
||||||
|
*
|
||||||
|
* @return True if calibration is done; otherwise false
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_apll_calibration_is_done(void)
|
||||||
|
{
|
||||||
|
return REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_CAL_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the 32kHz crystal oscillator
|
||||||
|
*
|
||||||
|
* @param mode Used to determine the xtal32k configuration parameters
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
|
||||||
|
{
|
||||||
|
// Configure xtal32k
|
||||||
|
// Default mode as CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL
|
||||||
|
uint32_t dac = CLK_LL_XTAL_32K_DAC_VAL; // current
|
||||||
|
uint32_t dres = CLK_LL_XTAL_32K_DRES_VAL; // resistance
|
||||||
|
uint32_t dbias = CLK_LL_XTAL_32K_DBIAS_VAL; // dbias voltage
|
||||||
|
if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
|
||||||
|
dac = CLK_LL_XTAL_32K_EXT_DAC_VAL;
|
||||||
|
dres = CLK_LL_XTAL_32K_EXT_DRES_VAL;
|
||||||
|
dbias = CLK_LL_XTAL_32K_EXT_DBIAS_VAL;
|
||||||
|
} else if (mode == CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP) {
|
||||||
|
dac = CLK_LL_XTAL_32K_BOOTSTRAP_DAC_VAL;
|
||||||
|
dres = CLK_LL_XTAL_32K_BOOTSTRAP_DRES_VAL;
|
||||||
|
dbias = CLK_LL_XTAL_32K_BOOTSTRAP_DBIAS_VAL;
|
||||||
|
}
|
||||||
|
REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DAC_XTAL_32K, dac);
|
||||||
|
REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DRES_XTAL_32K, dres);
|
||||||
|
REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DBIAS_XTAL_32K, dbias);
|
||||||
|
// Enable xtal32k xpd status
|
||||||
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the 32kHz crystal oscillator
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_disable(void)
|
||||||
|
{
|
||||||
|
// Disable xtal32k xpd status
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the 32kHz crystal clock
|
||||||
|
*
|
||||||
|
* @return True if the 32kHz XTAL is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the internal oscillator for RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the oscillator is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the output from the internal oscillator to be passed into a configurable divider,
|
||||||
|
* which by default divides the input clock frequency by 256. i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Divider values other than 256 may be configured, but this facility is not currently needed,
|
||||||
|
* so is not exposed in the code.
|
||||||
|
* The output of the divider, RC_FAST_D256_CLK, is referred as 8md256 or simply d256 in reg. descriptions.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the output from the internal oscillator to be passed into a configurable divider.
|
||||||
|
* i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Disabling this divider could reduce power consumption.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the divider which is applied to the output from the internal oscillator (RC_FAST_CLK)
|
||||||
|
*
|
||||||
|
* @return True if the divided output is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_d256_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital RC_FAST_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital XTAL32K_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital XTAL32K_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get PLL_CLK frequency
|
||||||
|
*
|
||||||
|
* @return PLL clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||||
|
{
|
||||||
|
// ESP32 BBPLL frequency is determined by the cpu freq sel
|
||||||
|
uint32_t cpu_freq_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL);
|
||||||
|
switch (cpu_freq_sel) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
return CLK_LL_PLL_320M_FREQ_MHZ;
|
||||||
|
case 2:
|
||||||
|
return CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
// Invalid CPUPERIOD_SEL value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (digital part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
|
||||||
|
{
|
||||||
|
(void)pll_freq_mhz;
|
||||||
|
// No such operation on ESP32
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Analog part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
uint8_t div_ref;
|
||||||
|
uint8_t div7_0;
|
||||||
|
uint8_t div10_8;
|
||||||
|
uint8_t lref;
|
||||||
|
uint8_t dcur;
|
||||||
|
uint8_t bw;
|
||||||
|
|
||||||
|
if (pll_freq_mhz == CLK_LL_PLL_320M_FREQ_MHZ) {
|
||||||
|
/* Configure 320M PLL */
|
||||||
|
switch (xtal_freq_mhz) {
|
||||||
|
case RTC_XTAL_FREQ_40M:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 32;
|
||||||
|
div10_8 = 0;
|
||||||
|
lref = 0;
|
||||||
|
dcur = 6;
|
||||||
|
bw = 3;
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_26M:
|
||||||
|
div_ref = 12;
|
||||||
|
div7_0 = 224;
|
||||||
|
div10_8 = 4;
|
||||||
|
lref = 1;
|
||||||
|
dcur = 0;
|
||||||
|
bw = 1;
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_24M:
|
||||||
|
div_ref = 11;
|
||||||
|
div7_0 = 224;
|
||||||
|
div10_8 = 4;
|
||||||
|
lref = 1;
|
||||||
|
dcur = 0;
|
||||||
|
bw = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
div_ref = 12;
|
||||||
|
div7_0 = 224;
|
||||||
|
div10_8 = 4;
|
||||||
|
lref = 0;
|
||||||
|
dcur = 0;
|
||||||
|
bw = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_ENDIV5, CLK_LL_BBPLL_ENDIV5_VAL_320M);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, CLK_LL_BBPLL_BBADC_DSMP_VAL_320M);
|
||||||
|
} else {
|
||||||
|
/* Configure 480M PLL */
|
||||||
|
switch (xtal_freq_mhz) {
|
||||||
|
case RTC_XTAL_FREQ_40M:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 28;
|
||||||
|
div10_8 = 0;
|
||||||
|
lref = 0;
|
||||||
|
dcur = 6;
|
||||||
|
bw = 3;
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_26M:
|
||||||
|
div_ref = 12;
|
||||||
|
div7_0 = 144;
|
||||||
|
div10_8 = 4;
|
||||||
|
lref = 1;
|
||||||
|
dcur = 0;
|
||||||
|
bw = 1;
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_24M:
|
||||||
|
div_ref = 11;
|
||||||
|
div7_0 = 144;
|
||||||
|
div10_8 = 4;
|
||||||
|
lref = 1;
|
||||||
|
dcur = 0;
|
||||||
|
bw = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
div_ref = 12;
|
||||||
|
div7_0 = 224;
|
||||||
|
div10_8 = 4;
|
||||||
|
lref = 0;
|
||||||
|
dcur = 0;
|
||||||
|
bw = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_ENDIV5, CLK_LL_BBPLL_ENDIV5_VAL_480M);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, CLK_LL_BBPLL_BBADC_DSMP_VAL_480M);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i2c_bbpll_lref = (lref << 7) | (div10_8 << 4) | (div_ref);
|
||||||
|
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
||||||
|
uint8_t i2c_bbpll_dcur = (bw << 6) | dcur;
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_LREF, i2c_bbpll_lref);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_cpu_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL, 2);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_APLL:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL, 3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_cpu_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_CPU_CLK_SRC_XTAL;
|
||||||
|
case 1:
|
||||||
|
return SOC_CPU_CLK_SRC_PLL;
|
||||||
|
case 2:
|
||||||
|
return SOC_CPU_CLK_SRC_RC_FAST;
|
||||||
|
case 3:
|
||||||
|
return SOC_CPU_CLK_SRC_APLL;
|
||||||
|
default:
|
||||||
|
return SOC_CPU_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU frequency from PLL clock
|
||||||
|
*
|
||||||
|
* @param cpu_mhz CPU frequency value, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_freq_mhz_from_pll(uint32_t cpu_mhz)
|
||||||
|
{
|
||||||
|
switch (cpu_mhz) {
|
||||||
|
case CLK_LL_PLL_80M_FREQ_MHZ:
|
||||||
|
DPORT_REG_WRITE(DPORT_CPU_PER_CONF_REG, 0);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_160M_FREQ_MHZ:
|
||||||
|
DPORT_REG_WRITE(DPORT_CPU_PER_CONF_REG, 1);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_240M_FREQ_MHZ:
|
||||||
|
DPORT_REG_WRITE(DPORT_CPU_PER_CONF_REG, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK freq from PLL
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK frequency from PLL_CLK source
|
||||||
|
*
|
||||||
|
* @return CPU clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_freq_mhz_from_pll(void)
|
||||||
|
{
|
||||||
|
uint32_t cpu_freq_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL);
|
||||||
|
switch (cpu_freq_sel) {
|
||||||
|
case 0:
|
||||||
|
return CLK_LL_PLL_80M_FREQ_MHZ;
|
||||||
|
case 1:
|
||||||
|
return CLK_LL_PLL_160M_FREQ_MHZ;
|
||||||
|
case 2:
|
||||||
|
return CLK_LL_PLL_240M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
// Invalid CPUPERIOD_SEL value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @param divider Divider. Usually this divider is set to 1 in bootloader stage. PRE_DIV_CNT = divider - 1.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
REG_SET_FIELD(SYSCON_SYSCLK_CONF_REG, SYSCON_PRE_DIV_CNT, divider - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (PRE_DIV_CNT + 1).
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(SYSCON_SYSCLK_CONF_REG, SYSCON_PRE_DIV_CNT) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set REF_TICK divider to make REF_TICK frequency at 1MHz
|
||||||
|
*
|
||||||
|
* @param cpu_clk_src Selected CPU clock source (one of soc_cpu_clk_src_t values)
|
||||||
|
* @param cpu_freq_mhz CPU frequency value, in MHz
|
||||||
|
*
|
||||||
|
* Divider = APB_CLK freq in Hz / 1MHz. Value in register = divider - 1.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_ref_tick_set_divider(soc_cpu_clk_src_t cpu_clk_src, uint32_t cpu_freq_mhz)
|
||||||
|
{
|
||||||
|
uint32_t apb_freq_mhz;
|
||||||
|
switch (cpu_clk_src) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
apb_freq_mhz = cpu_freq_mhz;
|
||||||
|
REG_WRITE(SYSCON_XTAL_TICK_CONF_REG, apb_freq_mhz - 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
apb_freq_mhz = 80;
|
||||||
|
REG_WRITE(SYSCON_PLL_TICK_CONF_REG, apb_freq_mhz - 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
apb_freq_mhz = cpu_freq_mhz;
|
||||||
|
REG_WRITE(SYSCON_CK8M_TICK_CONF_REG, apb_freq_mhz - 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_APLL:
|
||||||
|
apb_freq_mhz = cpu_freq_mhz >> 1;
|
||||||
|
REG_WRITE(SYSCON_APLL_TICK_CONF_REG, apb_freq_mhz - 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_slow_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_SLOW_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_slow_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
||||||
|
case 2:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256;
|
||||||
|
default:
|
||||||
|
// Invalid ANA_CLK_RTC_SEL value
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_fast_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_XTAL_D4:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_FAST_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_fast_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_XTAL_D4;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_FAST_CLK divider. The output from the divider is passed into rtc_fast_clk MUX.
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_FAST_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, divider - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get RC_FAST_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (CK8M_DIV_SEL + 1).
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rc_fast_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/
|
||||||
|
/**
|
||||||
|
* @brief Store XTAL_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz. The frequency must necessarily be even,
|
||||||
|
* otherwise there will be a conflict with the low bit, which is used to disable logs
|
||||||
|
* in the ROM code.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
// Read the status of whether disabling logging from ROM code
|
||||||
|
uint32_t reg = READ_PERI_REG(RTC_XTAL_FREQ_REG) & RTC_DISABLE_ROM_LOG;
|
||||||
|
// If so, need to write back this setting
|
||||||
|
if (reg == RTC_DISABLE_ROM_LOG) {
|
||||||
|
xtal_freq_mhz |= 1;
|
||||||
|
}
|
||||||
|
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load XTAL_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return XTAL frequency, in MHz. Returns 0 if format in reg is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
|
||||||
|
{
|
||||||
|
// Read from RTC storage register
|
||||||
|
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
||||||
|
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
|
||||||
|
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
|
||||||
|
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
|
||||||
|
}
|
||||||
|
// If the format in reg is invalid or haven't written XTAL value into RTC_XTAL_FREQ_REG
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store APB_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param apb_freq_hz APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_apb_store_freq_hz(uint32_t apb_freq_hz)
|
||||||
|
{
|
||||||
|
uint32_t val = apb_freq_hz >> 12;
|
||||||
|
WRITE_PERI_REG(RTC_APB_FREQ_REG, (val & UINT16_MAX) | ((val & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load APB_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return The stored APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_apb_load_freq_hz(void)
|
||||||
|
{
|
||||||
|
// Read from RTC storage register
|
||||||
|
uint32_t apb_freq_hz = (READ_PERI_REG(RTC_APB_FREQ_REG) & UINT16_MAX) << 12;
|
||||||
|
// Round to the nearest MHz
|
||||||
|
apb_freq_hz += MHZ / 2;
|
||||||
|
uint32_t remainder = apb_freq_hz % MHZ;
|
||||||
|
return apb_freq_hz - remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_SLOW_CLK_CAL_REG has to be in the same format as returned by rtc_clk_cal (microseconds,
|
||||||
|
* in Q13.19 fixed-point format).
|
||||||
|
*
|
||||||
|
* @param cal_value The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||||
|
{
|
||||||
|
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the calibration value of RTC_SLOW_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* This value gets updated (i.e. rtc slow clock gets calibrated) every time RTC_SLOW_CLK source switches
|
||||||
|
*
|
||||||
|
* @return The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rtc_slow_load_cal(void)
|
||||||
|
{
|
||||||
|
return REG_READ(RTC_SLOW_CLK_CAL_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
43
components/hal/esp32/include/hal/regi2c_ctrl_ll.h
Normal file
43
components/hal/esp32/include/hal/regi2c_ctrl_ll.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/regi2c_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset (Disable) the I2C internal bus for all regi2c registers
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_reset(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_BBPLL_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the APLL configuration register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_apll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_APLL_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
562
components/hal/esp32c2/include/hal/clk_tree_ll.h
Normal file
562
components/hal/esp32c2/include/hal/clk_tree_ll.h
Normal file
@@ -0,0 +1,562 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/clk_tree_defs.h"
|
||||||
|
#include "soc/rtc.h"
|
||||||
|
#include "soc/system_reg.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "esp_private/regi2c_ctrl.h"
|
||||||
|
#include "regi2c_bbpll.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "hal/log.h"
|
||||||
|
#include "esp32c2/rom/rtc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MHZ (1000000)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
|
||||||
|
#define CLK_LL_PLL_120M_FREQ_MHZ (120)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK enable modes
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK (i.e. EXT_OSC_CLK)
|
||||||
|
} clk_ll_xtal32k_enable_mode_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||||
|
{
|
||||||
|
REG_SET_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the internal oscillator for RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the oscillator is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the output from the internal oscillator to be passed into a configurable divider,
|
||||||
|
* which by default divides the input clock frequency by 256. i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Divider values other than 256 may be configured, but this facility is not currently needed,
|
||||||
|
* so is not exposed in the code.
|
||||||
|
* The output of the divider, RC_FAST_D256_CLK, is referred as 8md256 or simply d256 in reg. descriptions.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the output from the internal oscillator to be passed into a configurable divider.
|
||||||
|
* i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Disabling this divider could reduce power consumption.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the divider which is applied to the output from the internal oscillator (RC_FAST_CLK)
|
||||||
|
*
|
||||||
|
* @return True if the divided output is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_d256_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital RC_FAST_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital XTAL32K_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital XTAL32K_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get PLL_CLK frequency
|
||||||
|
*
|
||||||
|
* @return PLL clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||||
|
{
|
||||||
|
// ESP32C2 only support 480MHz PLL
|
||||||
|
uint32_t pll_freq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
||||||
|
switch (pll_freq_sel) {
|
||||||
|
case 1: // PLL_480M
|
||||||
|
return CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
// Invalid PLL_FREQ_SEL value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Digital part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
|
||||||
|
{
|
||||||
|
// ESP32C2 only support 480MHz PLL
|
||||||
|
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ);
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Analog part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
(void)pll_freq_mhz;
|
||||||
|
(void)xtal_freq_mhz;
|
||||||
|
// ESP32C2 only support 40M XTAL, all the parameters are given as 40M XTAL directly
|
||||||
|
uint8_t div_ref = 0;
|
||||||
|
uint8_t div7_0 = 8;
|
||||||
|
uint8_t dr1 = 0;
|
||||||
|
uint8_t dr3 = 0;
|
||||||
|
uint8_t dchgp = 5;
|
||||||
|
uint8_t dcur = 3;
|
||||||
|
uint8_t dbias = 2;
|
||||||
|
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
|
||||||
|
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
||||||
|
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
||||||
|
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_cpu_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_cpu_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_CPU_CLK_SRC_XTAL;
|
||||||
|
case 1:
|
||||||
|
return SOC_CPU_CLK_SRC_PLL;
|
||||||
|
case 2:
|
||||||
|
return SOC_CPU_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
// Invalid SOC_CLK_SEL value
|
||||||
|
return SOC_CPU_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU frequency from PLL clock
|
||||||
|
*
|
||||||
|
* @param cpu_mhz CPU frequency value, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_freq_mhz_from_pll(uint32_t cpu_mhz)
|
||||||
|
{
|
||||||
|
switch (cpu_mhz) {
|
||||||
|
case CLK_LL_PLL_80M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 0);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_120M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK freq from PLL
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK frequency from PLL_CLK source
|
||||||
|
*
|
||||||
|
* @return CPU clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_freq_mhz_from_pll(void)
|
||||||
|
{
|
||||||
|
uint32_t cpu_freq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
|
||||||
|
switch (cpu_freq_sel) {
|
||||||
|
case 0:
|
||||||
|
return CLK_LL_PLL_80M_FREQ_MHZ;
|
||||||
|
case 1:
|
||||||
|
return CLK_LL_PLL_120M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
// Invalid CPUPERIOD_SEL value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @param divider Divider. Usually this divider is set to 1 in bootloader stage. PRE_DIV_CNT = divider - 1.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, divider - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (PRE_DIV_CNT + 1).
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_slow_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_SLOW_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_slow_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW;
|
||||||
|
case 2:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256;
|
||||||
|
default:
|
||||||
|
// Invalid ANA_CLK_RTC_SEL value
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_fast_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_FAST_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_fast_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_FAST_CLK divider. The output from the divider is passed into rtc_fast_clk MUX.
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_FAST_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get RC_FAST_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (CK8M_DIV_SEL + 1).
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rc_fast_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_SLOW_CLK divider
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/
|
||||||
|
/**
|
||||||
|
* @brief Store XTAL_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load XTAL_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
|
||||||
|
{
|
||||||
|
// ESP32C2 has a fixed crystal frequency (40MHz), but we will still read from the RTC storage register
|
||||||
|
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
||||||
|
if ((xtal_freq_reg & UINT16_MAX) != RTC_XTAL_FREQ_40M) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (uint32_t)RTC_XTAL_FREQ_40M;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store APB_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param apb_freq_hz APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_apb_store_freq_hz(uint32_t apb_freq_hz)
|
||||||
|
{
|
||||||
|
uint32_t val = apb_freq_hz >> 12;
|
||||||
|
WRITE_PERI_REG(RTC_APB_FREQ_REG, (val & UINT16_MAX) | ((val & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load APB_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return The stored APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_apb_load_freq_hz(void)
|
||||||
|
{
|
||||||
|
// Read from RTC storage register
|
||||||
|
uint32_t apb_freq_hz = (READ_PERI_REG(RTC_APB_FREQ_REG) & UINT16_MAX) << 12;
|
||||||
|
// Round to the nearest MHz
|
||||||
|
apb_freq_hz += MHZ / 2;
|
||||||
|
uint32_t remainder = apb_freq_hz % MHZ;
|
||||||
|
return apb_freq_hz - remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_SLOW_CLK_CAL_REG has to be in the same format as returned by rtc_clk_cal (microseconds,
|
||||||
|
* in Q13.19 fixed-point format).
|
||||||
|
*
|
||||||
|
* @param cal_value The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||||
|
{
|
||||||
|
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the calibration value of RTC_SLOW_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* This value gets updated (i.e. rtc slow clock gets calibrated) every time RTC_SLOW_CLK source switches
|
||||||
|
*
|
||||||
|
* @return The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rtc_slow_load_cal(void)
|
||||||
|
{
|
||||||
|
return REG_READ(RTC_SLOW_CLK_CAL_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
44
components/hal/esp32c2/include/hal/regi2c_ctrl_ll.h
Normal file
44
components/hal/esp32c2/include/hal/regi2c_ctrl_ll.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/regi2c_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset (Disable) the I2C internal bus for all regi2c registers
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_reset(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start BBPLL self-calibration
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||||
|
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
702
components/hal/esp32c3/include/hal/clk_tree_ll.h
Normal file
702
components/hal/esp32c3/include/hal/clk_tree_ll.h
Normal file
@@ -0,0 +1,702 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/clk_tree_defs.h"
|
||||||
|
#include "soc/rtc.h"
|
||||||
|
#include "soc/system_reg.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "esp_private/regi2c_ctrl.h"
|
||||||
|
#include "regi2c_bbpll.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "hal/log.h"
|
||||||
|
#include "esp32c3/rom/rtc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MHZ (1000000)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
|
||||||
|
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
|
||||||
|
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
|
||||||
|
|
||||||
|
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
|
||||||
|
.dac = 3, \
|
||||||
|
.dres = 3, \
|
||||||
|
.dgm = 3, \
|
||||||
|
.dbuf = 1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK enable modes
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
|
||||||
|
} clk_ll_xtal32k_enable_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK configuration structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t dac : 6;
|
||||||
|
uint32_t dres : 3;
|
||||||
|
uint32_t dgm : 3;
|
||||||
|
uint32_t dbuf: 1;
|
||||||
|
} clk_ll_xtal32k_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||||
|
{
|
||||||
|
REG_SET_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the 32kHz crystal oscillator
|
||||||
|
*
|
||||||
|
* @param mode Used to determine the xtal32k configuration parameters
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
|
||||||
|
{
|
||||||
|
// Configure xtal32k
|
||||||
|
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
||||||
|
// Enable xtal32k xpd status
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||||
|
if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
|
||||||
|
/* TODO ESP32-C3 IDF-2408:: external 32k source may need different settings */
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the 32kHz crystal oscillator
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_disable(void)
|
||||||
|
{
|
||||||
|
// Set xtal32k xpd to be controlled by software
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
||||||
|
// Disable xtal32k xpd status
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the 32kHz crystal clock
|
||||||
|
*
|
||||||
|
* @return True if the 32kHz XTAL is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_is_enabled(void)
|
||||||
|
{
|
||||||
|
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
||||||
|
/* If xtal xpd is controlled by software */
|
||||||
|
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
||||||
|
/* If xtal xpd software control is on */
|
||||||
|
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
||||||
|
// disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled
|
||||||
|
bool enabled = !xtal_xpd_sw || xtal_xpd_st;
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the internal oscillator for RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the oscillator is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the output from the internal oscillator to be passed into a configurable divider,
|
||||||
|
* which by default divides the input clock frequency by 256. i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Divider values other than 256 may be configured, but this facility is not currently needed,
|
||||||
|
* so is not exposed in the code.
|
||||||
|
* The output of the divider, RC_FAST_D256_CLK, is referred as 8md256 or simply d256 in reg. descriptions.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the output from the internal oscillator to be passed into a configurable divider.
|
||||||
|
* i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Disabling this divider could reduce power consumption.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the divider which is applied to the output from the internal oscillator (RC_FAST_CLK)
|
||||||
|
*
|
||||||
|
* @return True if the divided output is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_d256_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital RC_FAST_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital XTAL32K_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital XTAL32K_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get PLL_CLK frequency
|
||||||
|
*
|
||||||
|
* @return PLL clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||||
|
{
|
||||||
|
uint32_t pll_freq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
||||||
|
switch (pll_freq_sel) {
|
||||||
|
case 0: // PLL_320M
|
||||||
|
return CLK_LL_PLL_320M_FREQ_MHZ;
|
||||||
|
case 1: // PLL_480M
|
||||||
|
return CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Digital part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
|
||||||
|
{
|
||||||
|
switch (pll_freq_mhz) {
|
||||||
|
case CLK_LL_PLL_320M_FREQ_MHZ: // PLL_320M
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL, 0);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_480M_FREQ_MHZ: // PLL_480M
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Analog part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
uint8_t div_ref;
|
||||||
|
uint8_t div7_0;
|
||||||
|
uint8_t dr1;
|
||||||
|
uint8_t dr3;
|
||||||
|
uint8_t dchgp;
|
||||||
|
uint8_t dcur;
|
||||||
|
uint8_t dbias;
|
||||||
|
|
||||||
|
if (pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) {
|
||||||
|
/* Configure 480M PLL */
|
||||||
|
switch (xtal_freq_mhz) {
|
||||||
|
case RTC_XTAL_FREQ_40M:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 8;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_32M:
|
||||||
|
div_ref = 1;
|
||||||
|
div7_0 = 26;
|
||||||
|
dr1 = 1;
|
||||||
|
dr3 = 1;
|
||||||
|
dchgp = 4;
|
||||||
|
dcur = 0;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 8;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
|
||||||
|
} else {
|
||||||
|
/* Configure 320M PLL */
|
||||||
|
switch (xtal_freq_mhz) {
|
||||||
|
case RTC_XTAL_FREQ_40M:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 4;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_32M:
|
||||||
|
div_ref = 1;
|
||||||
|
div7_0 = 6;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 4;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
|
||||||
|
}
|
||||||
|
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
||||||
|
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
||||||
|
uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 2);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_cpu_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_cpu_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_CPU_CLK_SRC_XTAL;
|
||||||
|
case 1:
|
||||||
|
return SOC_CPU_CLK_SRC_PLL;
|
||||||
|
case 2:
|
||||||
|
return SOC_CPU_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
// Invalid SOC_CLK_SEL value
|
||||||
|
return SOC_CPU_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU frequency from PLL clock
|
||||||
|
*
|
||||||
|
* @param cpu_mhz CPU frequency value, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_freq_mhz_from_pll(uint32_t cpu_mhz)
|
||||||
|
{
|
||||||
|
switch (cpu_mhz) {
|
||||||
|
case CLK_LL_PLL_80M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 0);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_160M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK freq from PLL
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK frequency from PLL_CLK source
|
||||||
|
*
|
||||||
|
* @return CPU clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_freq_mhz_from_pll(void)
|
||||||
|
{
|
||||||
|
uint32_t cpu_freq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
|
||||||
|
switch (cpu_freq_sel) {
|
||||||
|
case 0:
|
||||||
|
return CLK_LL_PLL_80M_FREQ_MHZ;
|
||||||
|
case 1:
|
||||||
|
return CLK_LL_PLL_160M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
// Invalid CPUPERIOD_SEL value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @param divider Divider. Usually this divider is set to 1 in bootloader stage. PRE_DIV_CNT = divider - 1.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, divider - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (PRE_DIV_CNT + 1).
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_slow_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_SLOW_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_slow_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
||||||
|
case 2:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256;
|
||||||
|
default:
|
||||||
|
// Invalid ANA_CLK_RTC_SEL value
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_fast_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_FAST_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_fast_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_FAST_CLK divider. The output from the divider is passed into rtc_fast_clk MUX.
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_FAST_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get RC_FAST_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (CK8M_DIV_SEL + 1).
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rc_fast_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_SLOW_CLK divider
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/
|
||||||
|
/**
|
||||||
|
* @brief Store XTAL_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load XTAL_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
|
||||||
|
{
|
||||||
|
// Read from RTC storage register
|
||||||
|
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
||||||
|
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
|
||||||
|
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
|
||||||
|
return xtal_freq_reg & UINT16_MAX;
|
||||||
|
}
|
||||||
|
// If the format in reg is invalid
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store APB_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param apb_freq_hz APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_apb_store_freq_hz(uint32_t apb_freq_hz)
|
||||||
|
{
|
||||||
|
uint32_t val = apb_freq_hz >> 12;
|
||||||
|
WRITE_PERI_REG(RTC_APB_FREQ_REG, (val & UINT16_MAX) | ((val & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load APB_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return The stored APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_apb_load_freq_hz(void)
|
||||||
|
{
|
||||||
|
// Read from RTC storage register
|
||||||
|
uint32_t apb_freq_hz = (READ_PERI_REG(RTC_APB_FREQ_REG) & UINT16_MAX) << 12;
|
||||||
|
// Round to the nearest MHz
|
||||||
|
apb_freq_hz += MHZ / 2;
|
||||||
|
uint32_t remainder = apb_freq_hz % MHZ;
|
||||||
|
return apb_freq_hz - remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_SLOW_CLK_CAL_REG has to be in the same format as returned by rtc_clk_cal (microseconds,
|
||||||
|
* in Q13.19 fixed-point format).
|
||||||
|
*
|
||||||
|
* @param cal_value The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||||
|
{
|
||||||
|
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the calibration value of RTC_SLOW_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* This value gets updated (i.e. rtc slow clock gets calibrated) every time RTC_SLOW_CLK source switches
|
||||||
|
*
|
||||||
|
* @return The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rtc_slow_load_cal(void)
|
||||||
|
{
|
||||||
|
return REG_READ(RTC_SLOW_CLK_CAL_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
44
components/hal/esp32c3/include/hal/regi2c_ctrl_ll.h
Normal file
44
components/hal/esp32c3/include/hal/regi2c_ctrl_ll.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/regi2c_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset (Disable) the I2C internal bus for all regi2c registers
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_reset(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start BBPLL self-calibration
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||||
|
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
572
components/hal/esp32h2/include/hal/clk_tree_ll.h
Normal file
572
components/hal/esp32h2/include/hal/clk_tree_ll.h
Normal file
@@ -0,0 +1,572 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/clk_tree_defs.h"
|
||||||
|
#include "soc/rtc.h"
|
||||||
|
#include "soc/system_reg.h"
|
||||||
|
#include "soc/clkrst_reg.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "esp_private/regi2c_ctrl.h"
|
||||||
|
#include "regi2c_bbpll.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "hal/log.h"
|
||||||
|
#include "esp32h2/rom/rtc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MHZ (1000000)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_96M_FREQ_MHZ (96)
|
||||||
|
|
||||||
|
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
|
||||||
|
.dac = 3, \
|
||||||
|
.dres = 3, \
|
||||||
|
.dgm = 3, \
|
||||||
|
.dbuf = 1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CLK_LL_RC32K_DFREQ_DEFAULT 707
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK enable modes
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
|
||||||
|
} clk_ll_xtal32k_enable_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK configuration structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t dac : 6;
|
||||||
|
uint32_t dres : 3;
|
||||||
|
uint32_t dgm : 3;
|
||||||
|
uint32_t dbuf: 1;
|
||||||
|
} clk_ll_xtal32k_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||||
|
{
|
||||||
|
REG_SET_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the 32kHz crystal oscillator
|
||||||
|
*
|
||||||
|
* @param mode Used to determine the xtal32k configuration parameters
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
|
||||||
|
{
|
||||||
|
// Configure xtal32k (or only for mode == CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL?)
|
||||||
|
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
||||||
|
// Enable xtal32k xpd status
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||||
|
if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
|
||||||
|
// Not supported yet?
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the 32kHz crystal oscillator
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_disable(void)
|
||||||
|
{
|
||||||
|
// Set xtal32k xpd to be controlled by software
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
||||||
|
// Disable xtal32k xpd status
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the 32kHz crystal clock
|
||||||
|
*
|
||||||
|
* @return True if the 32kHz XTAL is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_is_enabled(void)
|
||||||
|
{
|
||||||
|
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
||||||
|
/* If xtal xpd is controlled by software */
|
||||||
|
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
||||||
|
/* If xtal xpd software control is on */
|
||||||
|
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
||||||
|
// disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled
|
||||||
|
bool enabled = !xtal_xpd_sw || xtal_xpd_st;
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the internal oscillator output for RC32K_CLK
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc32k_enable(void)
|
||||||
|
{
|
||||||
|
// Configure rc32k
|
||||||
|
REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_DFREQ, CLK_LL_RC32K_DFREQ_DEFAULT);
|
||||||
|
// Enable rc32k xpd status
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_XPD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the internal oscillator output for RC32k_CLK
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc32k_disable(void)
|
||||||
|
{
|
||||||
|
// Configure rc32k
|
||||||
|
REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_DFREQ, CLK_LL_RC32K_DFREQ_DEFAULT);
|
||||||
|
// Disable rc32k xpd status
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_XPD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital RC_FAST_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc32k_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc32k_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital RC32K_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital RC32K_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc32k_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital XTAL32K_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital XTAL32K_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get PLL_CLK frequency
|
||||||
|
*
|
||||||
|
* @return PLL clock frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||||
|
{
|
||||||
|
uint32_t bbpll_freq = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SPLL_FREQ);
|
||||||
|
HAL_ASSERT(bbpll_freq == CLK_LL_PLL_96M_FREQ_MHZ);
|
||||||
|
return bbpll_freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Digital part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
|
||||||
|
{
|
||||||
|
(void)pll_freq_mhz;
|
||||||
|
// ESP32H2 bbpll frequency cannot be changed, fixed to 96MHz
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Analog part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
(void)xtal_freq_mhz;
|
||||||
|
switch (pll_freq_mhz) {
|
||||||
|
case CLK_LL_PLL_96M_FREQ_MHZ: // PLL_96M
|
||||||
|
/* set up PLL by analog control registers */
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, 0);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DIV, 1); // I2C_BBPLL_OC_DIV_5_0
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 3);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_cpu_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 2);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL_D2:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_cpu_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_CPU_CLK_SRC_XTAL;
|
||||||
|
case 1:
|
||||||
|
return SOC_CPU_CLK_SRC_PLL;
|
||||||
|
case 2:
|
||||||
|
return SOC_CPU_CLK_SRC_RC_FAST;
|
||||||
|
case 3:
|
||||||
|
return SOC_CPU_CLK_SRC_XTAL_D2;
|
||||||
|
default:
|
||||||
|
return SOC_CPU_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU_CLK divider. freq of CPU_CLK = freq of CPU clock source / divider
|
||||||
|
*
|
||||||
|
* @param divider Divider. CPU_DIV_NUM = divider - 1.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
REG_SET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_CPU_DIV_NUM, divider - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (CPU_DIV_NUM + 1).
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_CPU_DIV_NUM) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set AHB_CLK divider. freq of AHB_CLK = freq of CPU_CLK / divider
|
||||||
|
*
|
||||||
|
* @param divider Divider. AHB_DIV_NUM = divider - 1.
|
||||||
|
*/
|
||||||
|
static 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get AHB_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (AHB_DIV_NUM + 1).
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_ahb_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set APB_CLK divider. freq of APB_CLK = freq of AHB_CLK / divider
|
||||||
|
*
|
||||||
|
* @param divider Divider. APB_DIV_NUM = divider - 1.
|
||||||
|
*/
|
||||||
|
static 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get APB_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (APB_DIV_NUM + 1).
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_apb_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_slow_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC32K:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_SLOW_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_slow_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
||||||
|
case 2:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC32K;
|
||||||
|
default:
|
||||||
|
// Invalid ANA_CLK_RTC_SEL value
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_fast_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_FAST_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_fast_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_FAST_CLK divider. The output from the divider is passed into rtc_fast_clk MUX.
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_FAST_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get RC_FAST_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (CK8M_DIV_SEL + 1).
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rc_fast_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_SLOW_CLK divider
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/
|
||||||
|
/**
|
||||||
|
* @brief Store XTAL_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load XTAL_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
|
||||||
|
{
|
||||||
|
// ESP32H2 has a fixed crystal frequency (32MHz), but we will still read from the RTC storage register
|
||||||
|
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
||||||
|
if ((xtal_freq_reg & UINT16_MAX) != RTC_XTAL_FREQ_32M) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (uint32_t)RTC_XTAL_FREQ_32M;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store APB_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param apb_freq_hz APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_apb_store_freq_hz(uint32_t apb_freq_hz)
|
||||||
|
{
|
||||||
|
uint32_t val = apb_freq_hz >> 12;
|
||||||
|
WRITE_PERI_REG(RTC_APB_FREQ_REG, (val & UINT16_MAX) | ((val & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_SLOW_CLK_CAL_REG has to be in the same format as returned by rtc_clk_cal (microseconds,
|
||||||
|
* in Q13.19 fixed-point format).
|
||||||
|
*
|
||||||
|
* @param cal_value The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||||
|
{
|
||||||
|
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the calibration value of RTC_SLOW_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* This value gets updated (i.e. rtc slow clock gets calibrated) every time RTC_SLOW_CLK source switches
|
||||||
|
*
|
||||||
|
* @return The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rtc_slow_load_cal(void)
|
||||||
|
{
|
||||||
|
return REG_READ(RTC_SLOW_CLK_CAL_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
69
components/hal/esp32h2/include/hal/regi2c_ctrl_ll.h
Normal file
69
components/hal/esp32h2/include/hal/regi2c_ctrl_ll.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/regi2c_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset (Disable) the I2C internal bus for all regi2c registers
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_reset(void)
|
||||||
|
{
|
||||||
|
// On ESP32-H2, don't need to do anything (indeed do need? not fully supported yet?)
|
||||||
|
|
||||||
|
// SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
// On ESP32-H2, don't need to do anything (indeed do need? not fully supported yet?)
|
||||||
|
|
||||||
|
// CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start BBPLL self-calibration
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||||
|
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop BBPLL self-calibration
|
||||||
|
*
|
||||||
|
* This helps to prevent BBPLL jitter (phenomenon is significant on ESP32H2)
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_stop(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||||
|
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whether BBPLL calibration is done
|
||||||
|
*
|
||||||
|
* @return True if calibration is done; otherwise false
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibration_is_done(void)
|
||||||
|
{
|
||||||
|
return REG_GET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
749
components/hal/esp32s2/include/hal/clk_tree_ll.h
Normal file
749
components/hal/esp32s2/include/hal/clk_tree_ll.h
Normal file
@@ -0,0 +1,749 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/clk_tree_defs.h"
|
||||||
|
#include "soc/rtc.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "soc/dport_reg.h"
|
||||||
|
#include "soc/syscon_reg.h"
|
||||||
|
#include "esp_private/regi2c_ctrl.h"
|
||||||
|
#include "regi2c_bbpll.h"
|
||||||
|
#include "regi2c_apll.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "esp32s2/rom/rtc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MHZ (1000000)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
|
||||||
|
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
|
||||||
|
#define CLK_LL_PLL_240M_FREQ_MHZ (240)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
|
||||||
|
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
|
||||||
|
|
||||||
|
// ESP32S2 only supports 40MHz crystal
|
||||||
|
#define CLK_LL_XTAL_FREQ_MHZ (40)
|
||||||
|
|
||||||
|
/* APLL configuration parameters */
|
||||||
|
#define CLK_LL_APLL_SDM_STOP_VAL_1 0x09
|
||||||
|
#define CLK_LL_APLL_SDM_STOP_VAL_2_REV0 0x69
|
||||||
|
#define CLK_LL_APLL_SDM_STOP_VAL_2_REV1 0x49
|
||||||
|
|
||||||
|
/* APLL calibration parameters */
|
||||||
|
#define CLK_LL_APLL_CAL_DELAY_1 0x0f
|
||||||
|
#define CLK_LL_APLL_CAL_DELAY_2 0x3f
|
||||||
|
#define CLK_LL_APLL_CAL_DELAY_3 0x1f
|
||||||
|
|
||||||
|
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
|
||||||
|
.dac = 3, \
|
||||||
|
.dres = 3, \
|
||||||
|
.dgm = 3, \
|
||||||
|
.dbuf = 1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK enable modes
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
|
||||||
|
} clk_ll_xtal32k_enable_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK configuration structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t dac : 6;
|
||||||
|
uint32_t dres : 3;
|
||||||
|
uint32_t dgm : 3;
|
||||||
|
uint32_t dbuf: 1;
|
||||||
|
} clk_ll_xtal32k_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up APLL circuit
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_apll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down APLL circuit
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_apll_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set APLL configuration
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_apll_set_config(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
|
||||||
|
{
|
||||||
|
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2);
|
||||||
|
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0);
|
||||||
|
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1);
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_1);
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_2_REV1);
|
||||||
|
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set APLL calibration parameters
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_apll_set_calibration(void)
|
||||||
|
{
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, CLK_LL_APLL_CAL_DELAY_1);
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, CLK_LL_APLL_CAL_DELAY_2);
|
||||||
|
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, CLK_LL_APLL_CAL_DELAY_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whether APLL calibration is done
|
||||||
|
*
|
||||||
|
* @return True if calibration is done; otherwise false
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_apll_calibration_is_done(void)
|
||||||
|
{
|
||||||
|
return REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_CAL_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the 32kHz crystal oscillator
|
||||||
|
*
|
||||||
|
* @param mode Used to determine the xtal32k configuration parameters
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
|
||||||
|
{
|
||||||
|
// Configure xtal32k
|
||||||
|
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
||||||
|
// Enable xtal32k xpd status
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||||
|
if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
|
||||||
|
/* TODO: external 32k source may need different settings */
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the 32kHz crystal oscillator
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_disable(void)
|
||||||
|
{
|
||||||
|
// Set xtal32k xpd to be controlled by software
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
||||||
|
// Disable xtal32k xpd status
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the 32kHz crystal clock
|
||||||
|
*
|
||||||
|
* @return True if the 32kHz XTAL is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_is_enabled(void)
|
||||||
|
{
|
||||||
|
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
||||||
|
/* If xtal xpd is controlled by software */
|
||||||
|
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
||||||
|
/* If xtal xpd software control is on */
|
||||||
|
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
||||||
|
// disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled
|
||||||
|
bool enabled = !xtal_xpd_sw || xtal_xpd_st;
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the internal oscillator for RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the oscillator is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the output from the internal oscillator to be passed into a configurable divider,
|
||||||
|
* which by default divides the input clock frequency by 256. i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Divider values other than 256 may be configured, but this facility is not currently needed,
|
||||||
|
* so is not exposed in the code.
|
||||||
|
* The output of the divider, RC_FAST_D256_CLK, is referred as 8md256 or simply d256 in reg. descriptions.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the output from the internal oscillator to be passed into a configurable divider.
|
||||||
|
* i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Disabling this divider could reduce power consumption.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the divider which is applied to the output from the internal oscillator (RC_FAST_CLK)
|
||||||
|
*
|
||||||
|
* @return True if the divided output is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_d256_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital RC_FAST_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital XTAL32K_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital XTAL32K_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get PLL_CLK frequency
|
||||||
|
*
|
||||||
|
* @return PLL clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||||
|
{
|
||||||
|
uint32_t pll_freq_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_PLL_FREQ_SEL);
|
||||||
|
switch (pll_freq_sel) {
|
||||||
|
case 0: // PLL_320M
|
||||||
|
return CLK_LL_PLL_320M_FREQ_MHZ;
|
||||||
|
case 1: // PLL_480M
|
||||||
|
return CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (digital part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
|
||||||
|
{
|
||||||
|
switch (pll_freq_mhz) {
|
||||||
|
case CLK_LL_PLL_320M_FREQ_MHZ: // PLL_320M
|
||||||
|
CLEAR_PERI_REG_MASK(DPORT_CPU_PER_CONF_REG, DPORT_PLL_FREQ_SEL);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_480M_FREQ_MHZ: // PLL_480M
|
||||||
|
SET_PERI_REG_MASK(DPORT_CPU_PER_CONF_REG, DPORT_PLL_FREQ_SEL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Analog part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
(void)xtal_freq_mhz;
|
||||||
|
uint8_t div_ref;
|
||||||
|
uint8_t div7_0;
|
||||||
|
uint8_t dr1;
|
||||||
|
uint8_t dr3;
|
||||||
|
uint8_t dchgp;
|
||||||
|
uint8_t dcur;
|
||||||
|
|
||||||
|
if (pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) {
|
||||||
|
/* Configure 480M PLL */
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 8;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 4;
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
|
||||||
|
} else {
|
||||||
|
/* Configure 320M PLL */
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 4;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 5;
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
|
||||||
|
}
|
||||||
|
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
||||||
|
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
||||||
|
uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable BBPLL self-calibration
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_calibration_enable(void)
|
||||||
|
{
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_IR_CAL_ENX_CAP, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whether BBPLL calibration is done
|
||||||
|
*
|
||||||
|
* @param ext_cap Steps write to I2C_BBPLL_IR_CAL_EXT_CAP
|
||||||
|
*
|
||||||
|
* @return True if calibration is done; otherwise false
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) bool clk_ll_bbpll_calibration_is_done(uint32_t ext_cap)
|
||||||
|
{
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, ext_cap);
|
||||||
|
return REGI2C_READ_MASK(I2C_BBPLL, I2C_BBPLL_OR_CAL_CAP) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_cpu_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL, 2);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_APLL:
|
||||||
|
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL, 3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_cpu_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_SOC_CLK_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_CPU_CLK_SRC_XTAL;
|
||||||
|
case 1:
|
||||||
|
return SOC_CPU_CLK_SRC_PLL;
|
||||||
|
case 2:
|
||||||
|
return SOC_CPU_CLK_SRC_RC_FAST;
|
||||||
|
case 3:
|
||||||
|
return SOC_CPU_CLK_SRC_APLL;
|
||||||
|
default:
|
||||||
|
return SOC_CPU_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU frequency from PLL clock
|
||||||
|
*
|
||||||
|
* @param cpu_mhz CPU frequency value, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_freq_mhz_from_pll(uint32_t cpu_mhz)
|
||||||
|
{
|
||||||
|
switch (cpu_mhz) {
|
||||||
|
case CLK_LL_PLL_80M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 0);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_160M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 1);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_240M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK freq from PLL
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK frequency from PLL_CLK source
|
||||||
|
*
|
||||||
|
* @return CPU clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_freq_mhz_from_pll(void)
|
||||||
|
{
|
||||||
|
uint32_t cpu_freq_sel = DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL);
|
||||||
|
switch (cpu_freq_sel) {
|
||||||
|
case 0:
|
||||||
|
return CLK_LL_PLL_80M_FREQ_MHZ;
|
||||||
|
case 1:
|
||||||
|
return CLK_LL_PLL_160M_FREQ_MHZ;
|
||||||
|
case 2:
|
||||||
|
// When PLL frequency selection is 320MHz but CPU frequency selection is 240MHz, it is an undetermined state.
|
||||||
|
// It is checked in the upper layer.
|
||||||
|
return CLK_LL_PLL_240M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
// Invalid CPUPERIOD_SEL value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @param divider Divider. Usually this divider is set to 1 in bootloader stage. PRE_DIV_CNT = divider - 1.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
REG_SET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_PRE_DIV_CNT, divider - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (PRE_DIV_CNT + 1).
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(DPORT_SYSCLK_CONF_REG, DPORT_PRE_DIV_CNT) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set REF_TICK divider to make REF_TICK frequency at 1MHz
|
||||||
|
*
|
||||||
|
* @param cpu_clk_src Selected CPU clock source (one of soc_cpu_clk_src_t values)
|
||||||
|
*
|
||||||
|
* When PLL, APLL, or XTAL is set as CPU clock source, divider = XTAL_CLK freq in Hz / 1MHz.
|
||||||
|
* When RC_FAST is set as CPU clock source, divider = RC_FAST_CLK freq in Hz / 1MHz.
|
||||||
|
* Value in register = divider - 1.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_ref_tick_set_divider(soc_cpu_clk_src_t cpu_clk_src)
|
||||||
|
{
|
||||||
|
switch (cpu_clk_src) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
case SOC_CPU_CLK_SRC_APLL:
|
||||||
|
REG_SET_FIELD(SYSCON_TICK_CONF_REG, SYSCON_XTAL_TICK_NUM, CLK_LL_XTAL_FREQ_MHZ - 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(SYSCON_TICK_CONF_REG, SYSCON_CK8M_TICK_NUM, 8 - 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_slow_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_SLOW_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_slow_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
||||||
|
case 2:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256;
|
||||||
|
default:
|
||||||
|
// Invalid ANA_CLK_RTC_SEL value
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_fast_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_XTAL_D4:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_FAST_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_fast_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_XTAL_D4;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_FAST_CLK divider. The output from the divider is passed into rtc_fast_clk MUX.
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_FAST_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get RC_FAST_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (CK8M_DIV_SEL + 1).
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rc_fast_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_SLOW_CLK divider
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/
|
||||||
|
/**
|
||||||
|
* @brief Store APB_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param apb_freq_hz APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_apb_store_freq_hz(uint32_t apb_freq_hz)
|
||||||
|
{
|
||||||
|
uint32_t val = apb_freq_hz >> 12;
|
||||||
|
WRITE_PERI_REG(RTC_APB_FREQ_REG, (val & UINT16_MAX) | ((val & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load APB_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return The stored APB frequency, in Hz
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_apb_load_freq_hz(void)
|
||||||
|
{
|
||||||
|
// Read from RTC storage register
|
||||||
|
uint32_t apb_freq_hz = (READ_PERI_REG(RTC_APB_FREQ_REG) & UINT16_MAX) << 12;
|
||||||
|
// Round to the nearest MHz
|
||||||
|
apb_freq_hz += MHZ / 2;
|
||||||
|
uint32_t remainder = apb_freq_hz % MHZ;
|
||||||
|
return apb_freq_hz - remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_SLOW_CLK_CAL_REG has to be in the same format as returned by rtc_clk_cal (microseconds,
|
||||||
|
* in Q13.19 fixed-point format).
|
||||||
|
*
|
||||||
|
* @param cal_value The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||||
|
{
|
||||||
|
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the calibration value of RTC_SLOW_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* This value gets updated (i.e. rtc slow clock gets calibrated) every time RTC_SLOW_CLK source switches
|
||||||
|
*
|
||||||
|
* @return The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rtc_slow_load_cal(void)
|
||||||
|
{
|
||||||
|
return REG_READ(RTC_SLOW_CLK_CAL_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
43
components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h
Normal file
43
components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/regi2c_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset (Disable) the I2C internal bus for all regi2c registers
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_reset(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_BBPLL_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the APLL configuration register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_apll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_APLL_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
677
components/hal/esp32s3/include/hal/clk_tree_ll.h
Normal file
677
components/hal/esp32s3/include/hal/clk_tree_ll.h
Normal file
@@ -0,0 +1,677 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/clk_tree_defs.h"
|
||||||
|
#include "soc/rtc.h"
|
||||||
|
#include "soc/system_reg.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "esp_private/regi2c_ctrl.h"
|
||||||
|
#include "regi2c_bbpll.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "hal/log.h"
|
||||||
|
#include "esp32s3/rom/rtc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MHZ (1000000)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
|
||||||
|
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
|
||||||
|
#define CLK_LL_PLL_240M_FREQ_MHZ (240)
|
||||||
|
|
||||||
|
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
|
||||||
|
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
|
||||||
|
|
||||||
|
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
|
||||||
|
.dac = 3, \
|
||||||
|
.dres = 3, \
|
||||||
|
.dgm = 3, \
|
||||||
|
.dbuf = 1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK enable modes
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK
|
||||||
|
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
|
||||||
|
} clk_ll_xtal32k_enable_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XTAL32K_CLK configuration structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t dac : 6;
|
||||||
|
uint32_t dres : 3;
|
||||||
|
uint32_t dgm : 3;
|
||||||
|
uint32_t dbuf: 1;
|
||||||
|
} clk_ll_xtal32k_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power down BBPLL circuit
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||||
|
{
|
||||||
|
REG_SET_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||||
|
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the 32kHz crystal oscillator
|
||||||
|
*
|
||||||
|
* @param mode Used to determine the xtal32k configuration parameters
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
|
||||||
|
{
|
||||||
|
// Configure xtal32k
|
||||||
|
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
||||||
|
// Enable xtal32k xpd status
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||||
|
if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
|
||||||
|
/* TODO: external 32k oscillator may need different settings */
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the 32kHz crystal oscillator
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_disable(void)
|
||||||
|
{
|
||||||
|
// Set xtal32k xpd to be controlled by software
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
||||||
|
// Disable xtal32k xpd status
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the 32kHz crystal clock
|
||||||
|
*
|
||||||
|
* @return True if the 32kHz XTAL is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_is_enabled(void)
|
||||||
|
{
|
||||||
|
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
||||||
|
/* If xtal xpd is controlled by software */
|
||||||
|
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
||||||
|
/* If xtal xpd software control is on */
|
||||||
|
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
||||||
|
// disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled
|
||||||
|
bool enabled = !xtal_xpd_sw || xtal_xpd_st;
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the internal oscillator output for RC_FAST_CLK
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the internal oscillator for RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the oscillator is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the output from the internal oscillator to be passed into a configurable divider,
|
||||||
|
* which by default divides the input clock frequency by 256. i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Divider values other than 256 may be configured, but this facility is not currently needed,
|
||||||
|
* so is not exposed in the code.
|
||||||
|
* The output of the divider, RC_FAST_D256_CLK, is referred as 8md256 or simply d256 in reg. descriptions.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the output from the internal oscillator to be passed into a configurable divider.
|
||||||
|
* i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
|
||||||
|
*
|
||||||
|
* Disabling this divider could reduce power consumption.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_disable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the divider which is applied to the output from the internal oscillator (RC_FAST_CLK)
|
||||||
|
*
|
||||||
|
* @return True if the divided output is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_d256_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital RC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital RC_FAST_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_rc_fast_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital RC_FAST_D256_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_d256_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_enable(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal32k_digi_disable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of the digital XTAL32K_CLK
|
||||||
|
*
|
||||||
|
* @return True if the digital XTAL32K_CLK is enabled
|
||||||
|
*/
|
||||||
|
static inline bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get PLL_CLK frequency
|
||||||
|
*
|
||||||
|
* @return PLL clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||||
|
{
|
||||||
|
uint32_t pll_freq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
|
||||||
|
switch (pll_freq_sel) {
|
||||||
|
case 0: // PLL_320M
|
||||||
|
return CLK_LL_PLL_320M_FREQ_MHZ;
|
||||||
|
case 1: // PLL_480M
|
||||||
|
return CLK_LL_PLL_480M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Digital part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
|
||||||
|
{
|
||||||
|
switch (pll_freq_mhz) {
|
||||||
|
case CLK_LL_PLL_320M_FREQ_MHZ: // PLL_320M
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL, 0);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_480M_FREQ_MHZ: // PLL_480M
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set BBPLL frequency from XTAL source (Analog part)
|
||||||
|
*
|
||||||
|
* @param pll_freq_mhz PLL frequency, in MHz
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
uint8_t div_ref;
|
||||||
|
uint8_t div7_0;
|
||||||
|
uint8_t dr1;
|
||||||
|
uint8_t dr3;
|
||||||
|
uint8_t dchgp;
|
||||||
|
uint8_t dcur;
|
||||||
|
uint8_t dbias;
|
||||||
|
|
||||||
|
if (pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) {
|
||||||
|
/* Configure 480M PLL */
|
||||||
|
switch (xtal_freq_mhz) {
|
||||||
|
case RTC_XTAL_FREQ_40M:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 8;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_32M:
|
||||||
|
div_ref = 1;
|
||||||
|
div7_0 = 26;
|
||||||
|
dr1 = 1;
|
||||||
|
dr3 = 1;
|
||||||
|
dchgp = 4;
|
||||||
|
dcur = 0;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 8;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
|
||||||
|
} else {
|
||||||
|
/* Configure 320M PLL */
|
||||||
|
switch (xtal_freq_mhz) {
|
||||||
|
case RTC_XTAL_FREQ_40M:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 4;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_32M:
|
||||||
|
div_ref = 1;
|
||||||
|
div7_0 = 6;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
div_ref = 0;
|
||||||
|
div7_0 = 4;
|
||||||
|
dr1 = 0;
|
||||||
|
dr3 = 0;
|
||||||
|
dchgp = 5;
|
||||||
|
dcur = 3;
|
||||||
|
dbias = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
|
||||||
|
}
|
||||||
|
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
||||||
|
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
||||||
|
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
||||||
|
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
||||||
|
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_cpu_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_CPU_CLK_SRC_XTAL:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_PLL:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for CPU_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_cpu_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_CPU_CLK_SRC_XTAL;
|
||||||
|
case 1:
|
||||||
|
return SOC_CPU_CLK_SRC_PLL;
|
||||||
|
case 2:
|
||||||
|
return SOC_CPU_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
// Invalid SOC_CLK_SEL value
|
||||||
|
return SOC_CPU_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU frequency from PLL clock
|
||||||
|
*
|
||||||
|
* @param cpu_mhz CPU frequency value, in MHz
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_freq_mhz_from_pll(uint32_t cpu_mhz)
|
||||||
|
{
|
||||||
|
switch (cpu_mhz) {
|
||||||
|
case CLK_LL_PLL_80M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 0);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_160M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 1);
|
||||||
|
break;
|
||||||
|
case CLK_LL_PLL_240M_FREQ_MHZ:
|
||||||
|
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported CPU_CLK freq from PLL
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK frequency from PLL_CLK source
|
||||||
|
*
|
||||||
|
* @return CPU clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_freq_mhz_from_pll(void)
|
||||||
|
{
|
||||||
|
uint32_t cpu_freq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
|
||||||
|
switch (cpu_freq_sel) {
|
||||||
|
case 0:
|
||||||
|
return CLK_LL_PLL_80M_FREQ_MHZ;
|
||||||
|
case 1:
|
||||||
|
return CLK_LL_PLL_160M_FREQ_MHZ;
|
||||||
|
case 2:
|
||||||
|
// When PLL frequency selection is 320MHz but CPU frequency selection is 240MHz, it is an undetermined state.
|
||||||
|
// It is checked in the upper layer.
|
||||||
|
return CLK_LL_PLL_240M_FREQ_MHZ;
|
||||||
|
default:
|
||||||
|
// Invalid CPUPERIOD_SEL value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @param divider Divider. Usually this divider is set to 1 in bootloader stage. PRE_DIV_CNT = divider - 1.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, divider - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (PRE_DIV_CNT + 1).
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_slow_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_SLOW_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_SLOW_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_slow_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
||||||
|
case 2:
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256;
|
||||||
|
default:
|
||||||
|
// Invalid ANA_CLK_RTC_SEL value
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @param in_sel One of the clock sources in soc_rtc_fast_clk_src_t
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||||
|
{
|
||||||
|
switch (in_sel) {
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 0);
|
||||||
|
break;
|
||||||
|
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported RTC_FAST_CLK mux input sel
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the clock source for RTC_FAST_CLK
|
||||||
|
*
|
||||||
|
* @return Currently selected clock source (one of soc_rtc_fast_clk_src_t values)
|
||||||
|
*/
|
||||||
|
static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
||||||
|
switch (clk_sel) {
|
||||||
|
case 0:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
|
||||||
|
case 1:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||||
|
default:
|
||||||
|
return SOC_RTC_FAST_CLK_SRC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_FAST_CLK divider. The output from the divider is passed into rtc_fast_clk MUX.
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_FAST_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get RC_FAST_CLK divider
|
||||||
|
*
|
||||||
|
* @return Divider. Divider = (CK8M_DIV_SEL + 1).
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rc_fast_get_divider(void)
|
||||||
|
{
|
||||||
|
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set RC_SLOW_CLK divider
|
||||||
|
*
|
||||||
|
* @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(divider > 0);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, divider - 1);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/
|
||||||
|
/**
|
||||||
|
* @brief Store XTAL_CLK frequency in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
|
||||||
|
{
|
||||||
|
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load XTAL_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||||
|
* halves. These are the routines to work with that representation.
|
||||||
|
*
|
||||||
|
* @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid.
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
|
||||||
|
{
|
||||||
|
// Read from the RTC storage register
|
||||||
|
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
||||||
|
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
|
||||||
|
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
|
||||||
|
return xtal_freq_reg & UINT16_MAX;
|
||||||
|
}
|
||||||
|
// If the format in reg is invalid
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
|
||||||
|
*
|
||||||
|
* Value of RTC_SLOW_CLK_CAL_REG has to be in the same format as returned by rtc_clk_cal (microseconds,
|
||||||
|
* in Q13.19 fixed-point format).
|
||||||
|
*
|
||||||
|
* @param cal_value The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||||
|
{
|
||||||
|
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the calibration value of RTC_SLOW_CLK frequency from RTC storage register
|
||||||
|
*
|
||||||
|
* This value gets updated (i.e. rtc slow clock gets calibrated) every time RTC_SLOW_CLK source switches
|
||||||
|
*
|
||||||
|
* @return The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||||
|
*/
|
||||||
|
static inline uint32_t clk_ll_rtc_slow_load_cal(void)
|
||||||
|
{
|
||||||
|
return REG_READ(RTC_SLOW_CLK_CAL_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
72
components/hal/esp32s3/include/hal/regi2c_ctrl_ll.h
Normal file
72
components/hal/esp32s3/include/hal/regi2c_ctrl_ll.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/regi2c_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset (Disable) the I2C internal bus for all regi2c registers
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_reset(void)
|
||||||
|
{
|
||||||
|
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_BBPLL_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register
|
||||||
|
*/
|
||||||
|
static inline void regi2c_ctrl_ll_i2c_saradc_enable(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M);
|
||||||
|
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start BBPLL self-calibration
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||||
|
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop BBPLL self-calibration
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_stop(void)
|
||||||
|
{
|
||||||
|
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||||
|
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whether BBPLL calibration is done
|
||||||
|
*
|
||||||
|
* @return True if calibration is done; otherwise false
|
||||||
|
*/
|
||||||
|
static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibration_is_done(void)
|
||||||
|
{
|
||||||
|
return REG_GET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -66,6 +66,7 @@ typedef enum {
|
|||||||
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
|
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
|
||||||
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
||||||
SOC_CPU_CLK_SRC_APLL = 3, /*!< Select APLL_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_APLL = 3, /*!< Select APLL_CLK as CPU_CLK source */
|
||||||
|
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
|
||||||
} soc_cpu_clk_src_t;
|
} soc_cpu_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,6 +77,7 @@ typedef enum {
|
|||||||
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
||||||
|
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
||||||
} soc_rtc_slow_clk_src_t;
|
} soc_rtc_slow_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,6 +88,7 @@ typedef enum {
|
|||||||
SOC_RTC_FAST_CLK_SRC_XTAL_D4 = 0, /*!< Select XTAL_D4_CLK (may referred as XTAL_CLK_DIV_4) as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_XTAL_D4 = 0, /*!< Select XTAL_D4_CLK (may referred as XTAL_CLK_DIV_4) as RTC_FAST_CLK source */
|
||||||
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D4, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D4` */
|
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D4, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D4` */
|
||||||
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
||||||
|
SOC_RTC_FAST_CLK_SRC_INVALID, /*!< Invalid RTC_FAST_CLK source */
|
||||||
} soc_rtc_fast_clk_src_t;
|
} soc_rtc_fast_clk_src_t;
|
||||||
|
|
||||||
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
||||||
|
@@ -1,16 +1,8 @@
|
|||||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
*
|
||||||
// you may not use this file except in compliance with the License.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// You may obtain a copy of the License at
|
*/
|
||||||
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
#ifndef _SOC_DPORT_REG_H_
|
#ifndef _SOC_DPORT_REG_H_
|
||||||
#define _SOC_DPORT_REG_H_
|
#define _SOC_DPORT_REG_H_
|
||||||
|
|
||||||
@@ -179,9 +171,6 @@
|
|||||||
#define DPORT_CPUPERIOD_SEL_M ((DPORT_CPUPERIOD_SEL_V)<<(DPORT_CPUPERIOD_SEL_S))
|
#define DPORT_CPUPERIOD_SEL_M ((DPORT_CPUPERIOD_SEL_V)<<(DPORT_CPUPERIOD_SEL_S))
|
||||||
#define DPORT_CPUPERIOD_SEL_V 0x3
|
#define DPORT_CPUPERIOD_SEL_V 0x3
|
||||||
#define DPORT_CPUPERIOD_SEL_S 0
|
#define DPORT_CPUPERIOD_SEL_S 0
|
||||||
#define DPORT_CPUPERIOD_SEL_80 0
|
|
||||||
#define DPORT_CPUPERIOD_SEL_160 1
|
|
||||||
#define DPORT_CPUPERIOD_SEL_240 2
|
|
||||||
|
|
||||||
#define DPORT_PRO_CACHE_CTRL_REG (DR_REG_DPORT_BASE + 0x040)
|
#define DPORT_PRO_CACHE_CTRL_REG (DR_REG_DPORT_BASE + 0x040)
|
||||||
/* DPORT_PRO_DRAM_HL : R/W ;bitpos:[16] ;default: 1'b0 ; */
|
/* DPORT_PRO_DRAM_HL : R/W ;bitpos:[16] ;default: 1'b0 ; */
|
||||||
|
@@ -1,16 +1,8 @@
|
|||||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
*
|
||||||
// you may not use this file except in compliance with the License.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// You may obtain a copy of the License at
|
*/
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
#ifndef _SOC_IO_MUX_REG_H_
|
#ifndef _SOC_IO_MUX_REG_H_
|
||||||
#define _SOC_IO_MUX_REG_H_
|
#define _SOC_IO_MUX_REG_H_
|
||||||
|
|
||||||
@@ -98,6 +90,8 @@
|
|||||||
#define SPI_D_GPIO_NUM 8
|
#define SPI_D_GPIO_NUM 8
|
||||||
#define SPI_WP_GPIO_NUM 10
|
#define SPI_WP_GPIO_NUM 10
|
||||||
#define SPI_HD_GPIO_NUM 9
|
#define SPI_HD_GPIO_NUM 9
|
||||||
|
#define XTAL32K_P_GPIO_NUM 32
|
||||||
|
#define XTAL32K_N_GPIO_NUM 33
|
||||||
|
|
||||||
#define PIN_CTRL (DR_REG_IO_MUX_BASE +0x00)
|
#define PIN_CTRL (DR_REG_IO_MUX_BASE +0x00)
|
||||||
#define CLK_OUT3 0xf
|
#define CLK_OUT3 0xf
|
||||||
|
@@ -47,6 +47,33 @@ extern "C" {
|
|||||||
* - rtc_init: initialization
|
* - rtc_init: initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Delays for various clock sources to be enabled/switched.
|
||||||
|
* All values are in microseconds.
|
||||||
|
*/
|
||||||
|
#define SOC_DELAY_PLL_DBIAS_RAISE 3
|
||||||
|
#define SOC_DELAY_PLL_ENABLE_WITH_150K 80
|
||||||
|
#define SOC_DELAY_PLL_ENABLE_WITH_32K 160
|
||||||
|
#define SOC_DELAY_RTC_FAST_CLK_SWITCH 3
|
||||||
|
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
|
||||||
|
#define SOC_DELAY_RC_FAST_ENABLE 50
|
||||||
|
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
|
||||||
|
|
||||||
|
/* Core voltage needs to be increased in two cases:
|
||||||
|
* 1. running at 240 MHz
|
||||||
|
* 2. running with 80MHz Flash frequency
|
||||||
|
*
|
||||||
|
* There is a record in efuse which indicates the proper voltage for these two cases.
|
||||||
|
*/
|
||||||
|
#define RTC_CNTL_DBIAS_HP_VOLT (RTC_CNTL_DBIAS_1V25 - efuse_ll_get_vol_level_hp_inv())
|
||||||
|
#ifdef CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
||||||
|
#define DIG_DBIAS_80M_160M RTC_CNTL_DBIAS_HP_VOLT
|
||||||
|
#else
|
||||||
|
#define DIG_DBIAS_80M_160M RTC_CNTL_DBIAS_1V10
|
||||||
|
#endif
|
||||||
|
#define DIG_DBIAS_240M RTC_CNTL_DBIAS_HP_VOLT
|
||||||
|
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
||||||
|
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Possible main XTAL frequency values.
|
* @brief Possible main XTAL frequency values.
|
||||||
*
|
*
|
||||||
@@ -84,7 +111,7 @@ typedef enum {
|
|||||||
typedef struct rtc_clk_config_s {
|
typedef struct rtc_clk_config_s {
|
||||||
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
||||||
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
||||||
soc_rtc_fast_clk_src_t fast_clk_src : 1; //!< RTC_FAST_CLK clock source to choose
|
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 : 2; //!< RTC_SLOW_CLK clock source to choose
|
soc_rtc_slow_clk_src_t slow_clk_src : 2; //!< RTC_SLOW_CLK clock source to choose
|
||||||
uint32_t clk_8m_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
uint32_t clk_8m_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
||||||
uint32_t slow_clk_dcap : 8; //!< RTC 150k clock adjustment parameter (higher value leads to lower frequency)
|
uint32_t slow_clk_dcap : 8; //!< RTC 150k clock adjustment parameter (higher value leads to lower frequency)
|
||||||
@@ -241,9 +268,9 @@ void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_SLOW_CLK
|
* @brief Select source for RTC_SLOW_CLK
|
||||||
* @param slow_freq clock source (one of soc_rtc_slow_clk_src_t values)
|
* @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 slow_freq);
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_SLOW_CLK source
|
* @brief Get the RTC_SLOW_CLK source
|
||||||
@@ -267,9 +294,9 @@ uint32_t rtc_clk_slow_freq_get_hz(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_FAST_CLK
|
* @brief Select source for RTC_FAST_CLK
|
||||||
* @param fast_freq clock source (one of soc_rtc_fast_clk_src_t values)
|
* @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 fast_freq);
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_FAST_CLK source
|
* @brief Get the RTC_FAST_CLK source
|
||||||
|
@@ -893,10 +893,6 @@
|
|||||||
#define RTC_CNTL_SOC_CLK_SEL_M ((RTC_CNTL_SOC_CLK_SEL_V)<<(RTC_CNTL_SOC_CLK_SEL_S))
|
#define RTC_CNTL_SOC_CLK_SEL_M ((RTC_CNTL_SOC_CLK_SEL_V)<<(RTC_CNTL_SOC_CLK_SEL_S))
|
||||||
#define RTC_CNTL_SOC_CLK_SEL_V 0x3
|
#define RTC_CNTL_SOC_CLK_SEL_V 0x3
|
||||||
#define RTC_CNTL_SOC_CLK_SEL_S 27
|
#define RTC_CNTL_SOC_CLK_SEL_S 27
|
||||||
#define RTC_CNTL_SOC_CLK_SEL_XTL 0
|
|
||||||
#define RTC_CNTL_SOC_CLK_SEL_PLL 1
|
|
||||||
#define RTC_CNTL_SOC_CLK_SEL_8M 2
|
|
||||||
#define RTC_CNTL_SOC_CLK_SEL_APLL 3
|
|
||||||
/* RTC_CNTL_CK8M_FORCE_PU : R/W ;bitpos:[26] ;default: 1'd0 ; */
|
/* RTC_CNTL_CK8M_FORCE_PU : R/W ;bitpos:[26] ;default: 1'd0 ; */
|
||||||
/*description: CK8M force power up*/
|
/*description: CK8M force power up*/
|
||||||
#define RTC_CNTL_CK8M_FORCE_PU (BIT(26))
|
#define RTC_CNTL_CK8M_FORCE_PU (BIT(26))
|
||||||
|
@@ -62,6 +62,7 @@ typedef enum {
|
|||||||
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
|
||||||
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, 480MHz) */
|
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, 480MHz) */
|
||||||
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
||||||
|
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
|
||||||
} soc_cpu_clk_src_t;
|
} soc_cpu_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,6 +73,7 @@ typedef enum {
|
|||||||
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 1, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 1, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
||||||
|
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
||||||
} soc_rtc_slow_clk_src_t;
|
} soc_rtc_slow_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,6 +84,7 @@ typedef enum {
|
|||||||
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
|
||||||
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
|
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
|
||||||
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
||||||
|
SOC_RTC_FAST_CLK_SRC_INVALID, /*!< Invalid RTC_FAST_CLK source */
|
||||||
} soc_rtc_fast_clk_src_t;
|
} soc_rtc_fast_clk_src_t;
|
||||||
|
|
||||||
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
||||||
|
@@ -125,6 +125,8 @@
|
|||||||
#define SPI_D_GPIO_NUM 16
|
#define SPI_D_GPIO_NUM 16
|
||||||
#define SPI_Q_GPIO_NUM 17
|
#define SPI_Q_GPIO_NUM 17
|
||||||
|
|
||||||
|
#define EXT_OSC_SLOW_GPIO_NUM 0
|
||||||
|
|
||||||
#define MAX_RTC_GPIO_NUM 5
|
#define MAX_RTC_GPIO_NUM 5
|
||||||
#define MAX_PAD_GPIO_NUM 20
|
#define MAX_PAD_GPIO_NUM 20
|
||||||
#define MAX_GPIO_NUM 24
|
#define MAX_GPIO_NUM 24
|
||||||
|
@@ -67,18 +67,17 @@ extern "C" {
|
|||||||
#define RTC_CNTL_DBIAS_1V25 30
|
#define RTC_CNTL_DBIAS_1V25 30
|
||||||
#define RTC_CNTL_DBIAS_1V30 31 //voltage is about 1.34v in fact
|
#define RTC_CNTL_DBIAS_1V30 31 //voltage is about 1.34v in fact
|
||||||
|
|
||||||
#define DELAY_FAST_CLK_SWITCH 3
|
/* Delays for various clock sources to be enabled/switched.
|
||||||
#define DELAY_SLOW_CLK_SWITCH 300
|
* All values are in microseconds.
|
||||||
#define DELAY_8M_ENABLE 50
|
|
||||||
|
|
||||||
/* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
|
|
||||||
* 10 cycles will take approximately 300 microseconds.
|
|
||||||
*/
|
*/
|
||||||
#define XTAL_FREQ_EST_CYCLES 10
|
#define SOC_DELAY_RTC_FAST_CLK_SWITCH 3
|
||||||
|
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
|
||||||
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
|
#define SOC_DELAY_RC_FAST_ENABLE 50
|
||||||
#define DIG_DBIAS_160M RTC_CNTL_DBIAS_1V20
|
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
|
||||||
|
|
||||||
|
/* Core voltage (to be supported) */
|
||||||
|
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
|
||||||
|
#define DIG_DBIAS_120M RTC_CNTL_DBIAS_1V20
|
||||||
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
||||||
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
||||||
|
|
||||||
@@ -161,7 +160,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
||||||
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
||||||
soc_rtc_fast_clk_src_t fast_clk_src : 1; //!< RTC_FAST_CLK clock source to choose
|
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 : 2; //!< RTC_SLOW_CLK clock source to choose
|
soc_rtc_slow_clk_src_t slow_clk_src : 2; //!< RTC_SLOW_CLK clock source to choose
|
||||||
uint32_t clk_rtc_clk_div : 8;
|
uint32_t clk_rtc_clk_div : 8;
|
||||||
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
||||||
@@ -277,9 +276,9 @@ bool rtc_clk_8md256_enabled(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_SLOW_CLK
|
* @brief Select source for RTC_SLOW_CLK
|
||||||
* @param slow_freq clock source (one of soc_rtc_slow_clk_src_t values)
|
* @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 slow_freq);
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_SLOW_CLK source
|
* @brief Get the RTC_SLOW_CLK source
|
||||||
@@ -303,9 +302,9 @@ uint32_t rtc_clk_slow_freq_get_hz(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_FAST_CLK
|
* @brief Select source for RTC_FAST_CLK
|
||||||
* @param fast_freq clock source (one of soc_rtc_fast_clk_src_t values)
|
* @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 fast_freq);
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_FAST_CLK source
|
* @brief Get the RTC_FAST_CLK source
|
||||||
|
@@ -63,6 +63,7 @@ typedef enum {
|
|||||||
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
|
||||||
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
|
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
|
||||||
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
||||||
|
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
|
||||||
} soc_cpu_clk_src_t;
|
} soc_cpu_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,6 +74,7 @@ typedef enum {
|
|||||||
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
||||||
|
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
||||||
} soc_rtc_slow_clk_src_t;
|
} soc_rtc_slow_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +85,7 @@ typedef enum {
|
|||||||
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
|
||||||
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
|
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
|
||||||
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
||||||
|
SOC_RTC_FAST_CLK_SRC_INVALID, /*!< Invalid RTC_FAST_CLK source */
|
||||||
} soc_rtc_fast_clk_src_t;
|
} soc_rtc_fast_clk_src_t;
|
||||||
|
|
||||||
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
||||||
|
@@ -67,18 +67,20 @@ extern "C" {
|
|||||||
#define RTC_CNTL_DBIAS_1V25 30
|
#define RTC_CNTL_DBIAS_1V25 30
|
||||||
#define RTC_CNTL_DBIAS_1V30 31 //voltage is about 1.34v in fact
|
#define RTC_CNTL_DBIAS_1V30 31 //voltage is about 1.34v in fact
|
||||||
|
|
||||||
#define DELAY_FAST_CLK_SWITCH 3
|
/* Delays for various clock sources to be enabled/switched.
|
||||||
#define DELAY_SLOW_CLK_SWITCH 300
|
* All values are in microseconds.
|
||||||
#define DELAY_8M_ENABLE 50
|
|
||||||
|
|
||||||
/* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
|
|
||||||
* 10 cycles will take approximately 300 microseconds.
|
|
||||||
*/
|
*/
|
||||||
#define XTAL_FREQ_EST_CYCLES 10
|
#define SOC_DELAY_RTC_FAST_CLK_SWITCH 3
|
||||||
|
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
|
||||||
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
|
#define SOC_DELAY_RC_FAST_ENABLE 50
|
||||||
#define DIG_DBIAS_160M RTC_CNTL_DBIAS_1V20
|
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
|
||||||
|
|
||||||
|
/* Core voltage:
|
||||||
|
* Currently, ESP32C3 never adjust its wake voltage in runtime
|
||||||
|
* Only sets dig/rtc voltage dbias at startup time
|
||||||
|
*/
|
||||||
|
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
|
||||||
|
#define DIG_DBIAS_160M RTC_CNTL_DBIAS_1V20
|
||||||
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
||||||
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
||||||
|
|
||||||
@@ -163,7 +165,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
||||||
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
||||||
soc_rtc_fast_clk_src_t fast_clk_src : 1; //!< RTC_FAST_CLK clock source to choose
|
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 : 2; //!< RTC_SLOW_CLK clock source to choose
|
soc_rtc_slow_clk_src_t slow_clk_src : 2; //!< RTC_SLOW_CLK clock source to choose
|
||||||
uint32_t clk_rtc_clk_div : 8;
|
uint32_t clk_rtc_clk_div : 8;
|
||||||
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
||||||
@@ -185,20 +187,6 @@ typedef struct {
|
|||||||
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t dac : 6;
|
|
||||||
uint32_t dres : 3;
|
|
||||||
uint32_t dgm : 3;
|
|
||||||
uint32_t dbuf: 1;
|
|
||||||
} x32k_config_t;
|
|
||||||
|
|
||||||
#define X32K_CONFIG_DEFAULT() { \
|
|
||||||
.dac = 3, \
|
|
||||||
.dres = 3, \
|
|
||||||
.dgm = 3, \
|
|
||||||
.dbuf = 1, \
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t wifi_powerup_cycles : 7;
|
uint16_t wifi_powerup_cycles : 7;
|
||||||
uint16_t wifi_wait_cycles : 9;
|
uint16_t wifi_wait_cycles : 9;
|
||||||
@@ -317,9 +305,9 @@ bool rtc_clk_8md256_enabled(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_SLOW_CLK
|
* @brief Select source for RTC_SLOW_CLK
|
||||||
* @param slow_freq clock source (one of soc_rtc_slow_clk_src_t values)
|
* @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 slow_freq);
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_SLOW_CLK source
|
* @brief Get the RTC_SLOW_CLK source
|
||||||
@@ -343,9 +331,9 @@ uint32_t rtc_clk_slow_freq_get_hz(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_FAST_CLK
|
* @brief Select source for RTC_FAST_CLK
|
||||||
* @param fast_freq clock source (one of soc_rtc_fast_clk_src_t values)
|
* @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 fast_freq);
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_FAST_CLK source
|
* @brief Get the RTC_FAST_CLK source
|
||||||
|
@@ -152,6 +152,9 @@
|
|||||||
#define USB_DM_GPIO_NUM 18
|
#define USB_DM_GPIO_NUM 18
|
||||||
#define USB_DP_GPIO_NUM 19
|
#define USB_DP_GPIO_NUM 19
|
||||||
|
|
||||||
|
#define XTAL32K_P_GPIO_NUM 0
|
||||||
|
#define XTAL32K_N_GPIO_NUM 1
|
||||||
|
|
||||||
#define MAX_RTC_GPIO_NUM 5
|
#define MAX_RTC_GPIO_NUM 5
|
||||||
#define MAX_PAD_GPIO_NUM 40
|
#define MAX_PAD_GPIO_NUM 40
|
||||||
#define MAX_GPIO_NUM 44
|
#define MAX_GPIO_NUM 44
|
||||||
|
@@ -127,6 +127,9 @@
|
|||||||
#define USB_DM_GPIO_NUM 24
|
#define USB_DM_GPIO_NUM 24
|
||||||
#define USB_DP_GPIO_NUM 25
|
#define USB_DP_GPIO_NUM 25
|
||||||
|
|
||||||
|
#define XTAL32K_P_GPIO_NUM 10
|
||||||
|
#define XTAL32K_N_GPIO_NUM 11
|
||||||
|
|
||||||
#define MAX_RTC_GPIO_NUM 12 // GPIO7~12 are the rtc_io pads
|
#define MAX_RTC_GPIO_NUM 12 // GPIO7~12 are the rtc_io pads
|
||||||
#define MAX_PAD_GPIO_NUM 25
|
#define MAX_PAD_GPIO_NUM 25
|
||||||
#define MAX_GPIO_NUM 29
|
#define MAX_GPIO_NUM 29
|
||||||
|
@@ -70,6 +70,7 @@ typedef enum {
|
|||||||
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 32MHz crystal oscillator frequency multiplier, 96MHz) */
|
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 32MHz crystal oscillator frequency multiplier, 96MHz) */
|
||||||
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
||||||
SOC_CPU_CLK_SRC_XTAL_D2 = 3, /*!< Select XTAL_D2_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_XTAL_D2 = 3, /*!< Select XTAL_D2_CLK as CPU_CLK source */
|
||||||
|
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
|
||||||
} soc_cpu_clk_src_t;
|
} soc_cpu_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,6 +81,7 @@ typedef enum {
|
|||||||
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
|
||||||
|
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
||||||
} soc_rtc_slow_clk_src_t;
|
} soc_rtc_slow_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,6 +92,7 @@ typedef enum {
|
|||||||
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
|
||||||
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
|
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
|
||||||
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
||||||
|
SOC_RTC_FAST_CLK_SRC_INVALID, /*!< Invalid RTC_FAST_CLK source */
|
||||||
} soc_rtc_fast_clk_src_t;
|
} soc_rtc_fast_clk_src_t;
|
||||||
|
|
||||||
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -12,7 +12,8 @@
|
|||||||
/* Analog function control register */
|
/* Analog function control register */
|
||||||
#define I2C_MST_ANA_CONF0_REG 0x6000E040
|
#define I2C_MST_ANA_CONF0_REG 0x6000E040
|
||||||
#define I2C_MST_BBPLL_STOP_FORCE_HIGH (BIT(2))
|
#define I2C_MST_BBPLL_STOP_FORCE_HIGH (BIT(2))
|
||||||
#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3))
|
#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3))
|
||||||
|
#define I2C_MST_BBPLL_CAL_DONE (BIT(24))
|
||||||
|
|
||||||
#define ANA_CONFIG_REG 0x6000E044
|
#define ANA_CONFIG_REG 0x6000E044
|
||||||
#define ANA_CONFIG_S (8)
|
#define ANA_CONFIG_S (8)
|
||||||
@@ -21,7 +22,6 @@
|
|||||||
#define ANA_I2C_SAR_FORCE_PD BIT(18)
|
#define ANA_I2C_SAR_FORCE_PD BIT(18)
|
||||||
#define ANA_I2C_BBPLL_M BIT(17) /* Clear to enable BBPLL */
|
#define ANA_I2C_BBPLL_M BIT(17) /* Clear to enable BBPLL */
|
||||||
|
|
||||||
|
|
||||||
#define ANA_CONFIG2_REG 0x6000E048
|
#define ANA_CONFIG2_REG 0x6000E048
|
||||||
#define ANA_CONFIG2_M BIT(18)
|
#define ANA_CONFIG2_M BIT(18)
|
||||||
|
|
||||||
|
@@ -87,18 +87,16 @@ extern "C" {
|
|||||||
#define RTC_CNTL_DIG_DBIAS_1V15 6
|
#define RTC_CNTL_DIG_DBIAS_1V15 6
|
||||||
#define RTC_CNTL_DIG_DBIAS_1V20 7
|
#define RTC_CNTL_DIG_DBIAS_1V20 7
|
||||||
|
|
||||||
#define DELAY_FAST_CLK_SWITCH 3
|
/* Delays for various clock sources to be enabled/switched.
|
||||||
#define DELAY_SLOW_CLK_SWITCH 300
|
* All values are in microseconds.
|
||||||
#define DELAY_8M_ENABLE 50
|
|
||||||
|
|
||||||
/* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
|
|
||||||
* 10 cycles will take approximately 300 microseconds.
|
|
||||||
*/
|
*/
|
||||||
#define XTAL_FREQ_EST_CYCLES 10
|
#define SOC_DELAY_RTC_FAST_CLK_SWITCH 3
|
||||||
|
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
|
||||||
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
|
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
|
||||||
#define DIG_DBIAS_160M RTC_CNTL_DBIAS_1V20
|
|
||||||
|
|
||||||
|
/* Core voltage (to be supported) */
|
||||||
|
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
|
||||||
|
#define DIG_DBIAS_160M RTC_CNTL_DBIAS_1V20
|
||||||
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
||||||
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
||||||
|
|
||||||
@@ -109,7 +107,6 @@ extern "C" {
|
|||||||
|
|
||||||
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 600
|
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 600
|
||||||
#define RTC_CNTL_SCK_DCAP_DEFAULT 128
|
#define RTC_CNTL_SCK_DCAP_DEFAULT 128
|
||||||
#define RTC_CNTL_RC32K_DFREQ_DEFAULT 707
|
|
||||||
|
|
||||||
|
|
||||||
/* Various delays to be programmed into power control state machines */
|
/* Various delays to be programmed into power control state machines */
|
||||||
@@ -140,7 +137,6 @@ set sleep_init default param
|
|||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RTC_XTAL_FREQ_32M = 32,
|
RTC_XTAL_FREQ_32M = 32,
|
||||||
RTC_XTAL_FREQ_40M = 40, //!< 40 MHz XTAL
|
|
||||||
} rtc_xtal_freq_t;
|
} rtc_xtal_freq_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,7 +169,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
||||||
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
||||||
soc_rtc_fast_clk_src_t fast_clk_src : 1; //!< RTC_FAST_CLK clock source to choose
|
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 : 2; //!< RTC_SLOW_CLK clock source to choose
|
soc_rtc_slow_clk_src_t slow_clk_src : 2; //!< RTC_SLOW_CLK clock source to choose
|
||||||
uint32_t clk_rtc_clk_div : 8;
|
uint32_t clk_rtc_clk_div : 8;
|
||||||
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
||||||
@@ -197,29 +193,6 @@ typedef struct {
|
|||||||
.root_clk_slt = 0, \
|
.root_clk_slt = 0, \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t dac : 6;
|
|
||||||
uint32_t dres : 3;
|
|
||||||
uint32_t dgm : 3;
|
|
||||||
uint32_t dbuf: 1;
|
|
||||||
} x32k_config_t;
|
|
||||||
|
|
||||||
|
|
||||||
#define X32K_CONFIG_DEFAULT() { \
|
|
||||||
.dac = 3, \
|
|
||||||
.dres = 3, \
|
|
||||||
.dgm = 3, \
|
|
||||||
.dbuf = 1, \
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t dfreq : 10;
|
|
||||||
} rc32k_config_t;
|
|
||||||
|
|
||||||
#define RC32K_CONFIG_DEFAULT() {\
|
|
||||||
.dfreq = RTC_CNTL_RC32K_DFREQ_DEFAULT,\
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t wifi_powerup_cycles : 7;
|
uint16_t wifi_powerup_cycles : 7;
|
||||||
uint16_t wifi_wait_cycles : 9;
|
uint16_t wifi_wait_cycles : 9;
|
||||||
@@ -344,9 +317,9 @@ bool rtc_clk_8md256_enabled(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_SLOW_CLK
|
* @brief Select source for RTC_SLOW_CLK
|
||||||
* @param slow_freq clock source (one of soc_rtc_slow_clk_src_t values)
|
* @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 slow_freq);
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_SLOW_CLK source
|
* @brief Get the RTC_SLOW_CLK source
|
||||||
@@ -370,9 +343,9 @@ uint32_t rtc_clk_slow_freq_get_hz(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_FAST_CLK
|
* @brief Select source for RTC_FAST_CLK
|
||||||
* @param fast_freq clock source (one of soc_rtc_fast_clk_src_t values)
|
* @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 fast_freq);
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_FAST_CLK source
|
* @brief Get the RTC_FAST_CLK source
|
||||||
@@ -455,18 +428,13 @@ void rtc_clk_apb_freq_update(uint32_t apb_freq);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the current stored APB frequency.
|
* @brief Get the current stored APB frequency.
|
||||||
* @return The APB frequency value as last set via rtc_clk_apb_freq_update(), in Hz.
|
* @return The APB frequency value computed from upstream, in Hz.
|
||||||
*/
|
*/
|
||||||
uint32_t rtc_clk_apb_freq_get(void);
|
uint32_t rtc_clk_apb_freq_get(void);
|
||||||
|
|
||||||
void rtc_clk_cpu_freq_set(uint32_t source, uint32_t div);
|
void rtc_clk_cpu_freq_set(uint32_t source, uint32_t div);
|
||||||
|
|
||||||
/**
|
uint32_t rtc_clk_select_root_clk(soc_cpu_clk_src_t cpu_clk_src);
|
||||||
* @brief Get the current stored AHB frequency.
|
|
||||||
* @return The AHB frequency value as last set via rtc_clk_ahb_freq_set(), in Hz.
|
|
||||||
*/
|
|
||||||
uint32_t rtc_clk_ahb_freq_get(void);
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
|
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
|
||||||
|
|
||||||
@@ -910,12 +878,6 @@ rtc_vddsdio_config_t rtc_vddsdio_get_config(void);
|
|||||||
*/
|
*/
|
||||||
void rtc_vddsdio_set_config(rtc_vddsdio_config_t config);
|
void rtc_vddsdio_set_config(rtc_vddsdio_config_t config);
|
||||||
|
|
||||||
|
|
||||||
/* Select clock root source for esp32h2. return source clk freq_mhz
|
|
||||||
*/
|
|
||||||
uint32_t root_clk_slt(uint32_t source);
|
|
||||||
uint32_t root_clk_get(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regulator config
|
* Regulator config
|
||||||
*/
|
*/
|
||||||
@@ -946,12 +908,6 @@ typedef struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gpio hangup
|
|
||||||
*/
|
|
||||||
void rtc_gpio_hangup(uint32_t gpio_no);
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------- CLOCK TREE DEFS ALIAS ----------------------------
|
// -------------------------- CLOCK TREE DEFS ALIAS ----------------------------
|
||||||
// **WARNING**: The following are only for backwards compatibility.
|
// **WARNING**: The following are only for backwards compatibility.
|
||||||
// Please use the declarations in soc/clk_tree_defs.h instead.
|
// Please use the declarations in soc/clk_tree_defs.h instead.
|
||||||
|
@@ -64,6 +64,7 @@ typedef enum {
|
|||||||
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
|
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
|
||||||
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
||||||
SOC_CPU_CLK_SRC_APLL = 3, /*!< Select APLL_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_APLL = 3, /*!< Select APLL_CLK as CPU_CLK source */
|
||||||
|
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
|
||||||
} soc_cpu_clk_src_t;
|
} soc_cpu_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,6 +75,7 @@ typedef enum {
|
|||||||
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
||||||
|
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
||||||
} soc_rtc_slow_clk_src_t;
|
} soc_rtc_slow_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,6 +86,7 @@ typedef enum {
|
|||||||
SOC_RTC_FAST_CLK_SRC_XTAL_D4 = 0, /*!< Select XTAL_D4_CLK (may referred as XTAL_CLK_DIV_4) as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_XTAL_D4 = 0, /*!< Select XTAL_D4_CLK (may referred as XTAL_CLK_DIV_4) as RTC_FAST_CLK source */
|
||||||
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D4, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D4` */
|
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D4, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D4` */
|
||||||
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
||||||
|
SOC_RTC_FAST_CLK_SRC_INVALID, /*!< Invalid RTC_FAST_CLK source */
|
||||||
} soc_rtc_fast_clk_src_t;
|
} soc_rtc_fast_clk_src_t;
|
||||||
|
|
||||||
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
||||||
|
@@ -66,14 +66,13 @@ extern "C" {
|
|||||||
#define RTC_CNTL_DBIAS_1V20 6
|
#define RTC_CNTL_DBIAS_1V20 6
|
||||||
#define RTC_CNTL_DBIAS_1V25 7
|
#define RTC_CNTL_DBIAS_1V25 7
|
||||||
|
|
||||||
#define DELAY_FAST_CLK_SWITCH 3
|
/* Delays for various clock sources to be enabled/switched.
|
||||||
#define DELAY_SLOW_CLK_SWITCH 300
|
* All values are in microseconds.
|
||||||
#define DELAY_8M_ENABLE 50
|
|
||||||
|
|
||||||
/* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
|
|
||||||
* 10 cycles will take approximately 300 microseconds.
|
|
||||||
*/
|
*/
|
||||||
#define XTAL_FREQ_EST_CYCLES 10
|
#define SOC_DELAY_RTC_FAST_CLK_SWITCH 3
|
||||||
|
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
|
||||||
|
#define SOC_DELAY_RC_FAST_ENABLE 50
|
||||||
|
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
|
||||||
|
|
||||||
/* Core voltage needs to be increased in two cases:
|
/* Core voltage needs to be increased in two cases:
|
||||||
* 1. running at 240 MHz
|
* 1. running at 240 MHz
|
||||||
@@ -119,13 +118,6 @@ set sleep_init default param
|
|||||||
#define RTC_CNTL_PD_CUR_SLEEP_ON 0
|
#define RTC_CNTL_PD_CUR_SLEEP_ON 0
|
||||||
#define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1
|
#define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1
|
||||||
|
|
||||||
#define APLL_SDM_STOP_VAL_1 0x09
|
|
||||||
#define APLL_SDM_STOP_VAL_2_REV0 0x69
|
|
||||||
#define APLL_SDM_STOP_VAL_2_REV1 0x49
|
|
||||||
#define APLL_CAL_DELAY_1 0x0f
|
|
||||||
#define APLL_CAL_DELAY_2 0x3f
|
|
||||||
#define APLL_CAL_DELAY_3 0x1f
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Possible main XTAL frequency values.
|
* @brief Possible main XTAL frequency values.
|
||||||
*
|
*
|
||||||
@@ -135,13 +127,6 @@ typedef enum {
|
|||||||
RTC_XTAL_FREQ_40M = 40, //!< 40 MHz XTAL
|
RTC_XTAL_FREQ_40M = 40, //!< 40 MHz XTAL
|
||||||
} rtc_xtal_freq_t;
|
} rtc_xtal_freq_t;
|
||||||
|
|
||||||
/** @brief Fixed crystal frequency for this SoC
|
|
||||||
|
|
||||||
On an SoC where only one crystal frequency is supported,
|
|
||||||
using this macro is an alternative to calling rtc_clk_xtal_freq_get()
|
|
||||||
*/
|
|
||||||
#define RTC_XTAL_FREQ RTC_XTAL_FREQ_40M
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CPU clock configuration structure
|
* @brief CPU clock configuration structure
|
||||||
*/
|
*/
|
||||||
@@ -173,7 +158,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
||||||
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
||||||
soc_rtc_fast_clk_src_t fast_clk_src : 1; //!< RTC_FAST_CLK clock source to choose
|
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 : 2; //!< RTC_SLOW_CLK clock source to choose
|
soc_rtc_slow_clk_src_t slow_clk_src : 2; //!< RTC_SLOW_CLK clock source to choose
|
||||||
uint32_t clk_rtc_clk_div : 8;
|
uint32_t clk_rtc_clk_div : 8;
|
||||||
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
||||||
@@ -195,42 +180,6 @@ typedef struct {
|
|||||||
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t dac : 6;
|
|
||||||
uint32_t dres : 3;
|
|
||||||
uint32_t dgm : 3;
|
|
||||||
uint32_t dbuf: 1;
|
|
||||||
} x32k_config_t;
|
|
||||||
|
|
||||||
#define X32K_CONFIG_DEFAULT() { \
|
|
||||||
.dac = 3, \
|
|
||||||
.dres = 3, \
|
|
||||||
.dgm = 3, \
|
|
||||||
.dbuf = 1, \
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define X32K_CONFIG_BOOTSTRAP_DEFAULT() { \
|
|
||||||
.dac = 3, \
|
|
||||||
.dres = 3, \
|
|
||||||
.dgm = 0, \
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
x32k_config_t x32k_cfg;
|
|
||||||
uint32_t bt_lpck_div_num : 12;
|
|
||||||
uint32_t bt_lpck_div_a : 12;
|
|
||||||
uint32_t bt_lpck_div_b : 12;
|
|
||||||
} x32k_bootstrap_config_t;
|
|
||||||
|
|
||||||
#define X32K_BOOTSTRAP_CONFIG_DEFAULT() { \
|
|
||||||
.x32k_cfg = X32K_CONFIG_BOOTSTRAP_DEFAULT(), \
|
|
||||||
.bt_lpck_div_num = 2441, \
|
|
||||||
.bt_lpck_div_a = 32, \
|
|
||||||
.bt_lpck_div_b = 13, \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t wifi_powerup_cycles : 7;
|
uint16_t wifi_powerup_cycles : 7;
|
||||||
uint16_t wifi_wait_cycles : 9;
|
uint16_t wifi_wait_cycles : 9;
|
||||||
@@ -274,10 +223,10 @@ void rtc_clk_init(rtc_clk_config_t cfg);
|
|||||||
* Result is a constant as XTAL frequency is fixed.
|
* Result is a constant as XTAL frequency is fixed.
|
||||||
*
|
*
|
||||||
* @note Function is included for ESP32 compatible code only. Code which only
|
* @note Function is included for ESP32 compatible code only. Code which only
|
||||||
* needs to support this SoC can use the macro RTC_XTAL_FREQ for this SoC's
|
* needs to support this SoC can use the macro CLK_LL_XTAL_FREQ_MHZ for this SoC's
|
||||||
* fixed crystal value.
|
* fixed crystal value.
|
||||||
*
|
*
|
||||||
* @return XTAL frequency in MHz, RTC_XTAL_FREQ_40M
|
* @return XTAL frequency in MHz
|
||||||
*/
|
*/
|
||||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void);
|
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void);
|
||||||
|
|
||||||
@@ -381,9 +330,9 @@ void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_SLOW_CLK
|
* @brief Select source for RTC_SLOW_CLK
|
||||||
* @param slow_freq clock source (one of soc_rtc_slow_clk_src_t values)
|
* @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 slow_freq);
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_SLOW_CLK source
|
* @brief Get the RTC_SLOW_CLK source
|
||||||
@@ -407,9 +356,9 @@ uint32_t rtc_clk_slow_freq_get_hz(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_FAST_CLK
|
* @brief Select source for RTC_FAST_CLK
|
||||||
* @param fast_freq clock source (one of soc_rtc_fast_clk_src_t values)
|
* @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 fast_freq);
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_FAST_CLK source
|
* @brief Get the RTC_FAST_CLK source
|
||||||
|
@@ -1,16 +1,8 @@
|
|||||||
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
*
|
||||||
// you may not use this file except in compliance with the License.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// You may obtain a copy of the License at
|
*/
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
#ifndef _SOC_SYSTEM_REG_H_
|
#ifndef _SOC_SYSTEM_REG_H_
|
||||||
#define _SOC_SYSTEM_REG_H_
|
#define _SOC_SYSTEM_REG_H_
|
||||||
|
|
||||||
@@ -886,10 +878,6 @@ extern "C" {
|
|||||||
#define DPORT_SOC_CLK_SEL_M ((DPORT_SOC_CLK_SEL_V)<<(DPORT_SOC_CLK_SEL_S))
|
#define DPORT_SOC_CLK_SEL_M ((DPORT_SOC_CLK_SEL_V)<<(DPORT_SOC_CLK_SEL_S))
|
||||||
#define DPORT_SOC_CLK_SEL_V 0x3
|
#define DPORT_SOC_CLK_SEL_V 0x3
|
||||||
#define DPORT_SOC_CLK_SEL_S 10
|
#define DPORT_SOC_CLK_SEL_S 10
|
||||||
#define DPORT_SOC_CLK_SEL_XTL 0
|
|
||||||
#define DPORT_SOC_CLK_SEL_PLL 1
|
|
||||||
#define DPORT_SOC_CLK_SEL_8M 2
|
|
||||||
#define DPORT_SOC_CLK_SEL_APLL 3
|
|
||||||
/* DPORT_PRE_DIV_CNT : R/W ;bitpos:[9:0] ;default: 10'h1 ; */
|
/* DPORT_PRE_DIV_CNT : R/W ;bitpos:[9:0] ;default: 10'h1 ; */
|
||||||
/*description: */
|
/*description: */
|
||||||
#define DPORT_PRE_DIV_CNT 0x000003FF
|
#define DPORT_PRE_DIV_CNT 0x000003FF
|
||||||
|
@@ -63,6 +63,7 @@ typedef enum {
|
|||||||
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
|
||||||
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
|
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
|
||||||
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
|
||||||
|
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
|
||||||
} soc_cpu_clk_src_t;
|
} soc_cpu_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,6 +74,7 @@ typedef enum {
|
|||||||
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
|
||||||
|
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
||||||
} soc_rtc_slow_clk_src_t;
|
} soc_rtc_slow_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +85,7 @@ typedef enum {
|
|||||||
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
|
||||||
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
|
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
|
||||||
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
||||||
|
SOC_RTC_FAST_CLK_SRC_INVALID, /*!< Invalid RTC_FAST_CLK source */
|
||||||
} soc_rtc_fast_clk_src_t;
|
} soc_rtc_fast_clk_src_t;
|
||||||
|
|
||||||
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
// Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr]
|
||||||
|
@@ -156,6 +156,8 @@
|
|||||||
#define SD_DATA3_GPIO_NUM 10
|
#define SD_DATA3_GPIO_NUM 10
|
||||||
#define USB_DM_GPIO_NUM 19
|
#define USB_DM_GPIO_NUM 19
|
||||||
#define USB_DP_GPIO_NUM 20
|
#define USB_DP_GPIO_NUM 20
|
||||||
|
#define XTAL32K_P_GPIO_NUM 15
|
||||||
|
#define XTAL32K_N_GPIO_NUM 16
|
||||||
|
|
||||||
#define MAX_RTC_GPIO_NUM 21
|
#define MAX_RTC_GPIO_NUM 21
|
||||||
#define MAX_PAD_GPIO_NUM 48
|
#define MAX_PAD_GPIO_NUM 48
|
||||||
|
@@ -11,8 +11,8 @@
|
|||||||
/* Analog function control register */
|
/* Analog function control register */
|
||||||
#define I2C_MST_ANA_CONF0_REG 0x6000E040
|
#define I2C_MST_ANA_CONF0_REG 0x6000E040
|
||||||
#define I2C_MST_BBPLL_STOP_FORCE_HIGH (BIT(2))
|
#define I2C_MST_BBPLL_STOP_FORCE_HIGH (BIT(2))
|
||||||
#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3))
|
#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3))
|
||||||
#define I2C_MST_BBPLL_CAL_DONE (BIT(24))
|
#define I2C_MST_BBPLL_CAL_DONE (BIT(24))
|
||||||
|
|
||||||
#define ANA_CONFIG_REG 0x6000E044
|
#define ANA_CONFIG_REG 0x6000E044
|
||||||
#define ANA_CONFIG_S (8)
|
#define ANA_CONFIG_S (8)
|
||||||
|
@@ -68,14 +68,13 @@ extern "C" {
|
|||||||
#define RTC_CNTL_DBIAS_1V25 30
|
#define RTC_CNTL_DBIAS_1V25 30
|
||||||
#define RTC_CNTL_DBIAS_1V30 31 ///< voltage is about 1.34v in fact
|
#define RTC_CNTL_DBIAS_1V30 31 ///< voltage is about 1.34v in fact
|
||||||
|
|
||||||
#define DELAY_FAST_CLK_SWITCH 3
|
/* Delays for various clock sources to be enabled/switched.
|
||||||
#define DELAY_SLOW_CLK_SWITCH 300
|
* All values are in microseconds.
|
||||||
#define DELAY_8M_ENABLE 50
|
|
||||||
|
|
||||||
/* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
|
|
||||||
* 10 cycles will take approximately 300 microseconds.
|
|
||||||
*/
|
*/
|
||||||
#define XTAL_FREQ_EST_CYCLES 10
|
#define SOC_DELAY_RTC_FAST_CLK_SWITCH 3
|
||||||
|
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
|
||||||
|
#define SOC_DELAY_RC_FAST_ENABLE 50
|
||||||
|
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
|
||||||
|
|
||||||
/* Core voltage needs to be increased in two cases:
|
/* Core voltage needs to be increased in two cases:
|
||||||
* 1. running at 240 MHz
|
* 1. running at 240 MHz
|
||||||
@@ -168,7 +167,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
||||||
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
||||||
soc_rtc_fast_clk_src_t fast_clk_src : 1; //!< RTC_FAST_CLK clock source to choose
|
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 : 2; //!< RTC_SLOW_CLK clock source to choose
|
soc_rtc_slow_clk_src_t slow_clk_src : 2; //!< RTC_SLOW_CLK clock source to choose
|
||||||
uint32_t clk_rtc_clk_div : 8;
|
uint32_t clk_rtc_clk_div : 8;
|
||||||
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
|
||||||
@@ -190,20 +189,6 @@ typedef struct {
|
|||||||
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t dac : 6;
|
|
||||||
uint32_t dres : 3;
|
|
||||||
uint32_t dgm : 3;
|
|
||||||
uint32_t dbuf: 1;
|
|
||||||
} x32k_config_t;
|
|
||||||
|
|
||||||
#define X32K_CONFIG_DEFAULT() { \
|
|
||||||
.dac = 3, \
|
|
||||||
.dres = 3, \
|
|
||||||
.dgm = 3, \
|
|
||||||
.dbuf = 1, \
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t wifi_powerup_cycles : 7;
|
uint16_t wifi_powerup_cycles : 7;
|
||||||
uint16_t wifi_wait_cycles : 9;
|
uint16_t wifi_wait_cycles : 9;
|
||||||
@@ -330,9 +315,9 @@ bool rtc_clk_8md256_enabled(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_SLOW_CLK
|
* @brief Select source for RTC_SLOW_CLK
|
||||||
* @param slow_freq clock source (one of soc_rtc_slow_clk_src_t values)
|
* @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 slow_freq);
|
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_SLOW_CLK source
|
* @brief Get the RTC_SLOW_CLK source
|
||||||
@@ -356,9 +341,9 @@ uint32_t rtc_clk_slow_freq_get_hz(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select source for RTC_FAST_CLK
|
* @brief Select source for RTC_FAST_CLK
|
||||||
* @param fast_freq clock source (one of soc_rtc_fast_clk_src_t values)
|
* @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 fast_freq);
|
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the RTC_FAST_CLK source
|
* @brief Get the RTC_FAST_CLK source
|
||||||
|
@@ -1154,7 +1154,6 @@ components/soc/esp32/include/soc/can_periph.h
|
|||||||
components/soc/esp32/include/soc/can_struct.h
|
components/soc/esp32/include/soc/can_struct.h
|
||||||
components/soc/esp32/include/soc/clkout_channel.h
|
components/soc/esp32/include/soc/clkout_channel.h
|
||||||
components/soc/esp32/include/soc/dac_channel.h
|
components/soc/esp32/include/soc/dac_channel.h
|
||||||
components/soc/esp32/include/soc/dport_reg.h
|
|
||||||
components/soc/esp32/include/soc/emac_dma_struct.h
|
components/soc/esp32/include/soc/emac_dma_struct.h
|
||||||
components/soc/esp32/include/soc/emac_ext_struct.h
|
components/soc/esp32/include/soc/emac_ext_struct.h
|
||||||
components/soc/esp32/include/soc/emac_mac_struct.h
|
components/soc/esp32/include/soc/emac_mac_struct.h
|
||||||
@@ -1173,7 +1172,6 @@ components/soc/esp32/include/soc/host_struct.h
|
|||||||
components/soc/esp32/include/soc/hwcrypto_reg.h
|
components/soc/esp32/include/soc/hwcrypto_reg.h
|
||||||
components/soc/esp32/include/soc/i2c_reg.h
|
components/soc/esp32/include/soc/i2c_reg.h
|
||||||
components/soc/esp32/include/soc/i2c_struct.h
|
components/soc/esp32/include/soc/i2c_struct.h
|
||||||
components/soc/esp32/include/soc/io_mux_reg.h
|
|
||||||
components/soc/esp32/include/soc/ledc_reg.h
|
components/soc/esp32/include/soc/ledc_reg.h
|
||||||
components/soc/esp32/include/soc/ledc_struct.h
|
components/soc/esp32/include/soc/ledc_struct.h
|
||||||
components/soc/esp32/include/soc/nrx_reg.h
|
components/soc/esp32/include/soc/nrx_reg.h
|
||||||
@@ -1371,7 +1369,6 @@ components/soc/esp32s2/include/soc/spi_reg.h
|
|||||||
components/soc/esp32s2/include/soc/spi_struct.h
|
components/soc/esp32s2/include/soc/spi_struct.h
|
||||||
components/soc/esp32s2/include/soc/syscon_reg.h
|
components/soc/esp32s2/include/soc/syscon_reg.h
|
||||||
components/soc/esp32s2/include/soc/syscon_struct.h
|
components/soc/esp32s2/include/soc/syscon_struct.h
|
||||||
components/soc/esp32s2/include/soc/system_reg.h
|
|
||||||
components/soc/esp32s2/include/soc/systimer_reg.h
|
components/soc/esp32s2/include/soc/systimer_reg.h
|
||||||
components/soc/esp32s2/include/soc/systimer_struct.h
|
components/soc/esp32s2/include/soc/systimer_struct.h
|
||||||
components/soc/esp32s2/include/soc/touch_sensor_channel.h
|
components/soc/esp32s2/include/soc/touch_sensor_channel.h
|
||||||
|
Reference in New Issue
Block a user