mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/esp32c6_clock_basic_support' into 'master'
clk: Add basic clock support for esp32c6 Closes IDF-5630, IDF-5973, IDF-5346, and IDF-6050 See merge request espressif/esp-idf!21149
This commit is contained in:
commit
edd815af2e
1
Kconfig
1
Kconfig
@ -13,7 +13,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
config IDF_ENV_FPGA
|
||||
# This option is for internal use only
|
||||
bool
|
||||
default "y" if IDF_TARGET_ESP32C6 # TODO: IDF-5630
|
||||
option env="IDF_ENV_FPGA"
|
||||
|
||||
config IDF_CI_BUILD
|
||||
|
@ -52,15 +52,28 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
||||
|
||||
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();
|
||||
|
||||
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
|
||||
|
||||
// Use RTC_SLOW clock source sel register field's default value, RC_SLOW, for 2nd stage bootloader
|
||||
// RTC_SLOW clock source will be switched according to Kconfig selection at application startup
|
||||
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;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C6
|
||||
// TODO: IDF-5781 Some of esp32c6 SOC_RTC_FAST_CLK_SRC_XTAL_D2 rtc_fast clock has timing issue
|
||||
// Force to use SOC_RTC_FAST_CLK_SRC_RC_FAST since 2nd stage bootloader
|
||||
clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||
#else
|
||||
// Use RTC_FAST clock source sel register field's default value, XTAL_DIV, for 2nd stage bootloader
|
||||
// RTC_FAST clock source will be switched to RC_FAST at application startup
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
rtc_clk_init(clk_cfg);
|
||||
}
|
||||
|
||||
@ -82,15 +95,15 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
||||
CLEAR_PERI_REG_MASK(LP_TIMER_LP_INT_ENA_REG, LP_TIMER_MAIN_TIMER_LP_INT_ENA); /* MAIN_TIMER */
|
||||
CLEAR_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_ENA_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_ENA); /* BROWN_OUT */
|
||||
CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA); /* WDT */
|
||||
CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); /* SLP_REJECT */
|
||||
CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */
|
||||
// CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); // TODO: IDF-5348 /* SLP_REJECT */
|
||||
// CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */
|
||||
// SET CLR
|
||||
SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); /* SWD */
|
||||
SET_PERI_REG_MASK(LP_TIMER_LP_INT_CLR_REG, LP_TIMER_MAIN_TIMER_LP_INT_CLR); /* MAIN_TIMER */
|
||||
SET_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_CLR_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_CLR); /* BROWN_OUT */
|
||||
SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR); /* WDT */
|
||||
SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); /* SLP_REJECT */
|
||||
SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR); /* SLP_WAKEUP */
|
||||
// SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); // TODO: IDF-5348 /* SLP_REJECT */
|
||||
// SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR); /* SLP_WAKEUP */
|
||||
#else
|
||||
REG_WRITE(RTC_CNTL_INT_ENA_REG, 0);
|
||||
REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX);
|
||||
|
@ -227,7 +227,7 @@ static void bootloader_super_wdt_auto_feed(void)
|
||||
static inline void bootloader_hardware_init(void)
|
||||
{
|
||||
// TODO: IDF-5990 need update, enable i2c mst clk by force on temporarily
|
||||
SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
|
||||
SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_FORCE_ON_REG, MODEM_LPCON_CLK_I2C_MST_FO);
|
||||
SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,11 @@ esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_
|
||||
case TIMER_SRC_CLK_PLL_F40M:
|
||||
*time = (double)timer_val * div / (40 * 1000 * 1000);
|
||||
break;
|
||||
#endif
|
||||
#if SOC_TIMER_GROUP_SUPPORT_PLL_F80M
|
||||
case TIMER_SRC_CLK_PLL_F80M:
|
||||
*time = (double)timer_val * div / (80 * 1000 * 1000);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_ARG, TIMER_TAG, "invalid clock source");
|
||||
|
@ -411,6 +411,18 @@ static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_sou
|
||||
#endif
|
||||
break;
|
||||
#endif // SOC_TIMER_GROUP_SUPPORT_PLL_F40M
|
||||
#if SOC_TIMER_GROUP_SUPPORT_PLL_F80M
|
||||
case GPTIMER_CLK_SRC_PLL_F80M:
|
||||
counter_src_hz = 80 * 1000 * 1000;
|
||||
#if CONFIG_PM_ENABLE
|
||||
sprintf(timer->pm_lock_name, "gptimer_%d_%d", timer->group->group_id, timer_id); // e.g. gptimer_0_0
|
||||
// ESP32C6 PLL_F80M is available when SOC_ROOT_CLK switchs to XTAL
|
||||
ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, timer->pm_lock_name, &timer->pm_lock);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "create NO_LIGHT_SLEEP lock failed");
|
||||
ESP_LOGD(TAG, "install NO_LIGHT_SLEEP lock for timer (%d,%d)", timer->group->group_id, timer_id);
|
||||
#endif
|
||||
break;
|
||||
#endif // SOC_TIMER_GROUP_SUPPORT_PLL_F80M
|
||||
#if SOC_TIMER_GROUP_SUPPORT_AHB
|
||||
case GPTIMER_CLK_SRC_AHB:
|
||||
// TODO: decide which kind of PM lock we should use for such clock
|
||||
|
@ -488,8 +488,19 @@ uint32_t i2s_get_source_clk_freq(i2s_clock_src_t clk_src, uint32_t mclk_freq_hz)
|
||||
(void)mclk_freq_hz;
|
||||
return esp_clk_xtal_freq();
|
||||
#endif
|
||||
default: // I2S_CLK_SRC_PLL_160M
|
||||
return esp_clk_apb_freq() * 2;
|
||||
#if SOC_I2S_SUPPORTS_PLL_F160M
|
||||
case I2S_CLK_SRC_PLL_160M:
|
||||
(void)mclk_freq_hz;
|
||||
return I2S_LL_PLL_F160M_CLK_FREQ;
|
||||
#endif
|
||||
#if SOC_I2S_SUPPORTS_PLL_F96M
|
||||
case I2S_CLK_SRC_PLL_96M:
|
||||
(void)mclk_freq_hz;
|
||||
return I2S_LL_PLL_F96M_CLK_FREQ;
|
||||
#endif
|
||||
default:
|
||||
// Invalid clock source
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -535,10 +535,8 @@ TEST_CASE("LEDC timer select specific clock source", "[ledc]")
|
||||
TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
|
||||
|
||||
if (test_speed_mode == LEDC_LOW_SPEED_MODE) {
|
||||
#if !CONFIG_IDF_TARGET_ESP32C6 // Temporary. RC_FAST not able to calibrate currently. Can be removed once IDF-5346 done.
|
||||
printf("Check LEDC_USE_RTC8M_CLK for a 100Hz signal\n");
|
||||
timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_RTC8M_CLK, 10, 100);
|
||||
#endif
|
||||
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
|
||||
printf("Check LEDC_USE_XTAL_CLK for a 400Hz signal\n");
|
||||
timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_XTAL_CLK, 13, 400);
|
||||
|
@ -123,6 +123,10 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]")
|
||||
|
||||
printf("generate rising edge glitch signal\r\n");
|
||||
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
|
||||
asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
|
||||
// should timeout, because the glitch is filtered out
|
||||
@ -133,6 +137,10 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]")
|
||||
|
||||
printf("generate rising edge glitch signal again\r\n");
|
||||
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
|
||||
asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
|
||||
// this time we should see the GPIO interrupt fired up
|
||||
|
@ -71,7 +71,12 @@ int IRAM_ATTR esp_clk_cpu_freq(void)
|
||||
|
||||
int IRAM_ATTR esp_clk_apb_freq(void)
|
||||
{
|
||||
// TODO: IDF-5173 Require cleanup, implementation should be unified
|
||||
#if CONFIG_IDF_TARGET_ESP32C6
|
||||
return rtc_clk_apb_freq_get();
|
||||
#else
|
||||
return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ);
|
||||
#endif
|
||||
}
|
||||
|
||||
int IRAM_ATTR esp_clk_xtal_freq(void)
|
||||
|
@ -167,7 +167,7 @@ static void calibrate_ocode(void)
|
||||
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
|
||||
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
|
||||
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
|
||||
cal_clk = RTC_CAL_EXT_32K;
|
||||
cal_clk = RTC_CAL_32K_OSC_SLOW;
|
||||
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
|
||||
cal_clk = RTC_CAL_8MD256;
|
||||
}
|
||||
|
@ -40,14 +40,14 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
if (cal_clk == RTC_CAL_RTC_MUX) {
|
||||
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
|
||||
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
|
||||
cal_clk = RTC_CAL_EXT_32K;
|
||||
cal_clk = RTC_CAL_32K_OSC_SLOW;
|
||||
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
|
||||
cal_clk = RTC_CAL_8MD256;
|
||||
}
|
||||
}
|
||||
/* Enable requested clock (150k clock is always on) */
|
||||
bool dig_ext_clk_enabled = clk_ll_xtal32k_digi_is_enabled();
|
||||
if (cal_clk == RTC_CAL_EXT_32K && !dig_ext_clk_enabled) {
|
||||
if (cal_clk == RTC_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) {
|
||||
clk_ll_xtal32k_digi_enable();
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
|
||||
/* Set timeout reg and expect time delay*/
|
||||
uint32_t expected_freq;
|
||||
if (cal_clk == RTC_CAL_EXT_32K) {
|
||||
if (cal_clk == RTC_CAL_32K_OSC_SLOW) {
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||
expected_freq = SOC_CLK_OSC_SLOW_FREQ_APPROX;
|
||||
} else if (cal_clk == RTC_CAL_8MD256) {
|
||||
@ -109,7 +109,7 @@ 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);
|
||||
|
||||
/* if dig_ext_clk was originally off and enabled due to calibration, then set back to off state */
|
||||
if (cal_clk == RTC_CAL_EXT_32K && !dig_ext_clk_enabled) {
|
||||
if (cal_clk == RTC_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) {
|
||||
clk_ll_xtal32k_digi_disable();
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
|
||||
|
||||
if ((cal_clk == RTC_CAL_EXT_32K) && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
|
||||
if ((cal_clk == RTC_CAL_32K_OSC_SLOW) && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -238,8 +238,8 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
||||
div = clk_ll_cpu_get_divider();
|
||||
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL: {
|
||||
freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
|
||||
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||
|
@ -1,6 +1,6 @@
|
||||
set(srcs "rtc_clk_init.c"
|
||||
"rtc_clk.c"
|
||||
# "rtc_init.c" // TODO: IDF-5645
|
||||
"rtc_init.c"
|
||||
# "rtc_pm.c" // TODO: IDF-5645
|
||||
# "rtc_sleep.c" // TODO: IDF-5645
|
||||
"rtc_time.c"
|
||||
|
@ -1,5 +1,4 @@
|
||||
choice RTC_CLK_SRC
|
||||
# TODO: IDF-5346
|
||||
prompt "RTC clock source"
|
||||
default RTC_CLK_SRC_INT_RC
|
||||
help
|
||||
@ -13,8 +12,8 @@ choice RTC_CLK_SRC
|
||||
config RTC_CLK_SRC_EXT_OSC
|
||||
bool "External 32kHz oscillator at 32K_XP pin"
|
||||
select ESP_SYSTEM_RTC_EXT_OSC
|
||||
config RTC_CLK_SRC_INT_8MD256
|
||||
bool "Internal 17.5MHz oscillator, divided by 256"
|
||||
config RTC_CLK_SRC_INT_RC32K
|
||||
bool "Internal 32kHz RC oscillator"
|
||||
endchoice
|
||||
|
||||
config RTC_CLK_CAL_CYCLES
|
||||
|
@ -15,98 +15,147 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_hw_log.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "hal/usb_serial_jtag_ll.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/regi2c_ctrl_ll.h"
|
||||
#include "soc/lp_clkrst_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/lp_aon_reg.h"
|
||||
|
||||
static const char *TAG = "rtc_clk";
|
||||
|
||||
// Current PLL frequency, in 480MHz. Zero if PLL is not enabled.
|
||||
static int s_cur_pll_freq;
|
||||
|
||||
void rtc_clk_32k_enable(bool enable)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
if (enable) {
|
||||
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
|
||||
} else {
|
||||
clk_ll_xtal32k_disable();
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_32k_enable_external(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
// EXT_OSC_SLOW_GPIO_NUM == GPIO_NUM_0
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG);
|
||||
REG_SET_BIT(LP_AON_GPIO_HOLD0_REG, BIT(EXT_OSC_SLOW_GPIO_NUM));
|
||||
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
|
||||
}
|
||||
|
||||
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
/* No special bootstrapping needed for ESP32-C6, 'cycle' argument is to keep the signature
|
||||
* same as for the ESP32. Just enable the XTAL here.
|
||||
*/
|
||||
(void)cycle;
|
||||
rtc_clk_32k_enable(true);
|
||||
}
|
||||
|
||||
bool rtc_clk_32k_enabled(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
return clk_ll_xtal32k_is_enabled();
|
||||
}
|
||||
|
||||
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
|
||||
void rtc_clk_rc32k_enable(bool enable)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
if (enable) {
|
||||
clk_ll_rc32k_enable();
|
||||
esp_rom_delay_us(SOC_DELAY_RC32K_ENABLE);
|
||||
} else {
|
||||
clk_ll_rc32k_disable();
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_8m_enable(bool clk_8m_en)
|
||||
{
|
||||
if (clk_8m_en) {
|
||||
clk_ll_rc_fast_enable();
|
||||
esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
|
||||
} else {
|
||||
clk_ll_rc_fast_disable();
|
||||
}
|
||||
}
|
||||
|
||||
bool rtc_clk_8m_enabled(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool rtc_clk_8md256_enabled(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
return clk_ll_rc_fast_is_enabled();
|
||||
}
|
||||
|
||||
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
clk_ll_rtc_slow_set_src(clk_src);
|
||||
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
|
||||
}
|
||||
|
||||
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return REG_GET_FIELD(LP_CLKRST_LP_CLK_CONF_REG, LP_CLKRST_SLOW_CLK_SEL);
|
||||
return clk_ll_rtc_slow_get_src();
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
switch (rtc_clk_slow_freq_get()) {
|
||||
case RTC_SLOW_FREQ_RTC: return RTC_SLOW_CLK_FREQ_150K;
|
||||
case RTC_SLOW_FREQ_32K_XTAL: return RTC_SLOW_CLK_FREQ_32K;
|
||||
case RTC_SLOW_FREQ_8MD256: return RTC_SLOW_CLK_FREQ_8MD256;
|
||||
default: return 0;
|
||||
switch (rtc_clk_slow_src_get()) {
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
clk_ll_rtc_fast_set_src(clk_src);
|
||||
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
|
||||
}
|
||||
|
||||
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
return clk_ll_rtc_fast_get_src();
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void rtc_clk_bbpll_disable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
clk_ll_bbpll_disable();
|
||||
s_cur_pll_freq = 0;
|
||||
}
|
||||
|
||||
static void rtc_clk_bbpll_enable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
clk_ll_bbpll_enable();
|
||||
}
|
||||
|
||||
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
/* Digital part */
|
||||
clk_ll_bbpll_set_freq_mhz(pll_freq);
|
||||
/* Analog part */
|
||||
/* BBPLL CALIBRATION START */
|
||||
regi2c_ctrl_ll_bbpll_calibration_start();
|
||||
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||
/* WAIT CALIBRATION DONE */
|
||||
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
|
||||
/* BBPLL CALIBRATION STOP */
|
||||
regi2c_ctrl_ll_bbpll_calibration_stop();
|
||||
|
||||
s_cur_pll_freq = pll_freq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to XTAL frequency. Does not disable the PLL.
|
||||
*/
|
||||
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
||||
{
|
||||
clk_ll_cpu_set_ls_divider(div);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||
ets_update_cpu_frequency(freq);
|
||||
}
|
||||
|
||||
static void rtc_clk_cpu_freq_to_8m(void)
|
||||
{
|
||||
clk_ll_cpu_set_ls_divider(1);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||
ets_update_cpu_frequency(20);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,110 +165,203 @@ static 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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
clk_ll_cpu_set_hs_divider(CLK_LL_PLL_480M_FREQ_MHZ / cpu_freq_mhz);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||
ets_update_cpu_frequency(cpu_freq_mhz);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
uint32_t source_freq_mhz;
|
||||
soc_cpu_clk_src_t source;
|
||||
uint32_t divider; // divider = freq of SOC_ROOT_CLK / freq of CPU_CLK
|
||||
uint32_t real_freq_mhz;
|
||||
|
||||
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
if (freq_mhz <= xtal_freq && freq_mhz != 0) {
|
||||
divider = xtal_freq / freq_mhz;
|
||||
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
||||
if (real_freq_mhz != freq_mhz) {
|
||||
// no suitable divider
|
||||
return false;
|
||||
}
|
||||
|
||||
source_freq_mhz = xtal_freq;
|
||||
source = SOC_CPU_CLK_SRC_XTAL;
|
||||
} else if (freq_mhz == 80) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
divider = 6;
|
||||
} else if (freq_mhz == 120) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
divider = 4;
|
||||
} else if (freq_mhz == 160) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
divider = 3;
|
||||
} else {
|
||||
// unsupported frequency
|
||||
return false;
|
||||
}
|
||||
*out_config = (rtc_cpu_freq_config_t) {
|
||||
.source = source,
|
||||
.div = divider,
|
||||
.source_freq_mhz = source_freq_mhz,
|
||||
.freq_mhz = real_freq_mhz
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) {
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
||||
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
|
||||
rtc_clk_bbpll_enable();
|
||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
|
||||
}
|
||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||
rtc_clk_cpu_freq_to_8m();
|
||||
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) {
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||
uint32_t source_freq_mhz;
|
||||
uint32_t div; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
|
||||
uint32_t freq_mhz;
|
||||
switch (source) {
|
||||
case SOC_CPU_CLK_SRC_XTAL: {
|
||||
div = clk_ll_cpu_get_ls_divider();
|
||||
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
case SOC_CPU_CLK_SRC_PLL: {
|
||||
div = clk_ll_cpu_get_hs_divider();
|
||||
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
div = clk_ll_cpu_get_ls_divider();
|
||||
source_freq_mhz = 20;
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
default:
|
||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||
abort();
|
||||
}
|
||||
*out_config = (rtc_cpu_freq_config_t) {
|
||||
.source = source,
|
||||
.source_freq_mhz = source_freq_mhz,
|
||||
.div = div,
|
||||
.freq_mhz = freq_mhz
|
||||
};
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL &&
|
||||
s_cur_pll_freq == config->source_freq_mhz) {
|
||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||
rtc_clk_cpu_freq_to_8m();
|
||||
} else {
|
||||
/* fallback */
|
||||
rtc_clk_cpu_freq_set_config(config);
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set_xtal(void)
|
||||
{
|
||||
ESP_EARLY_LOGW(TAG, "rtc_clk_cpu_freq_set_xtal() has not been implemented yet");
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Switch to XTAL frequency. Does not disable the PLL.
|
||||
*/
|
||||
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
|
||||
static void rtc_clk_cpu_freq_to_8m(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
#endif
|
||||
|
||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||
{
|
||||
ESP_EARLY_LOGW(TAG, "rtc_clk_xtal_freq_get() has not been implemented yet");
|
||||
// TODO: IDF-5645
|
||||
return 40;
|
||||
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||
if (xtal_freq_mhz == 0) {
|
||||
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
|
||||
return RTC_XTAL_FREQ_40M;
|
||||
}
|
||||
return (rtc_xtal_freq_t)xtal_freq_mhz;
|
||||
}
|
||||
|
||||
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
clk_ll_xtal_store_freq_mhz(xtal_freq);
|
||||
}
|
||||
|
||||
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
||||
static uint32_t rtc_clk_ahb_freq_get(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||
uint32_t soc_root_freq_mhz;
|
||||
uint32_t divider;
|
||||
switch (source) {
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
soc_root_freq_mhz = rtc_clk_xtal_freq_get();
|
||||
divider = clk_ll_ahb_get_ls_divider();
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||
divider = clk_ll_ahb_get_hs_divider();
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
soc_root_freq_mhz = 20;
|
||||
divider = clk_ll_ahb_get_ls_divider();
|
||||
break;
|
||||
default:
|
||||
// Unknown SOC_ROOT clock source
|
||||
soc_root_freq_mhz = 0;
|
||||
divider = 1;
|
||||
ESP_HW_LOGE(TAG, "Invalid SOC_ROOT_CLK");
|
||||
break;
|
||||
}
|
||||
return soc_root_freq_mhz / divider;
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_apb_freq_get(void)
|
||||
{
|
||||
ESP_EARLY_LOGW(TAG, "rtc_clk_apb_freq_get() has not been implemented yet");
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtc_clk_divider_set(uint32_t div)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
|
||||
void rtc_clk_8m_divider_set(uint32_t div)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return rtc_clk_ahb_freq_get() / clk_ll_apb_get_divider() * MHZ;
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_enable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
clk_ll_rc_fast_digi_enable();
|
||||
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_disable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
clk_ll_rc_fast_digi_disable();
|
||||
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||
}
|
||||
|
||||
bool rtc_dig_8m_enabled(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
return clk_ll_rc_fast_digi_is_enabled();
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool rtc_clk_set_bbpll_always_on(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Name used in libphy.a:phy_chip_v7.o
|
||||
* TODO: update the library to use rtc_clk_xtal_freq_get
|
||||
*/
|
||||
|
@ -13,45 +13,41 @@
|
||||
#include "esp32c6/rom/uart.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "hal/regi2c_ctrl_ll.h"
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "soc/lp_clkrst_reg.h"
|
||||
#include "soc/regi2c_dig_reg.h"
|
||||
#include "esp_hw_log.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
|
||||
static const char *TAG = "rtc_clk_init";
|
||||
|
||||
void rtc_clk_init(rtc_clk_config_t cfg)
|
||||
{
|
||||
ESP_HW_LOGW(TAG, "rtc_clk_init() has not been implemented yet");
|
||||
#if 0 // TODO: IDF-5645
|
||||
rtc_cpu_freq_config_t old_config, new_config;
|
||||
|
||||
/* Set tuning parameters for 8M and 150k clocks.
|
||||
/* Set tuning parameters for RC_FAST, RC_SLOW, and RC32K clocks.
|
||||
* Note: this doesn't attempt to set the clocks to precise frequencies.
|
||||
* Instead, we calibrate these clocks against XTAL frequency later, when necessary.
|
||||
* - SCK_DCAP value controls tuning of 150k clock.
|
||||
* - SCK_DCAP value controls tuning of RC_SLOW clock.
|
||||
* The higher the value of DCAP is, the lower is the frequency.
|
||||
* - CK8M_DFREQ value controls tuning of 8M clock.
|
||||
* - CK8M_DFREQ value controls tuning of RC_FAST clock.
|
||||
* CLK_8M_DFREQ constant gives the best temperature characteristics.
|
||||
* - RC32K_DFREQ value controls tuning of RC32K clock.
|
||||
*/
|
||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, cfg.slow_clk_dcap);
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
|
||||
|
||||
/* Configure 150k clock division */
|
||||
rtc_clk_divider_set(cfg.clk_rtc_clk_div);
|
||||
|
||||
/* Configure 8M clock division */
|
||||
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 BBPLL */
|
||||
regi2c_ctrl_ll_i2c_bbpll_enable(); // TODO: This should be moved to bbpll_set_config
|
||||
REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq);
|
||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, cfg.slow_clk_dcap);
|
||||
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq);
|
||||
|
||||
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
||||
esp_rom_uart_tx_wait_idle(0);
|
||||
rtc_clk_xtal_freq_update(xtal_freq);
|
||||
rtc_clk_apb_freq_update(xtal_freq * MHZ);
|
||||
|
||||
// On ESP32C6, MSPI source clock's default HS divider leads to 120MHz, which is unusable before calibration
|
||||
// Therefore, before switching SOC_ROOT_CLK to HS, we need to set MSPI source clock HS divider to make it run at
|
||||
// 80MHz after the switch. PLL = 480MHz, so divider is 6.
|
||||
clk_ll_mspi_fast_set_hs_divider(6);
|
||||
|
||||
/* Set CPU frequency */
|
||||
rtc_clk_cpu_freq_get_config(&old_config);
|
||||
@ -70,14 +66,14 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
||||
// We will not power off RC_FAST in bootloader stage even if it is not being used as any
|
||||
// cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage.
|
||||
bool need_rc_fast_en = true;
|
||||
bool need_rc_fast_d256_en = false;
|
||||
if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
rtc_clk_32k_enable(true);
|
||||
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
|
||||
need_rc_fast_d256_en = true;
|
||||
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
|
||||
rtc_clk_32k_enable_external();
|
||||
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
|
||||
rtc_clk_rc32k_enable(true);
|
||||
}
|
||||
rtc_clk_8m_enable(need_rc_fast_en, need_rc_fast_d256_en);
|
||||
rtc_clk_8m_enable(need_rc_fast_en);
|
||||
rtc_clk_fast_src_set(cfg.fast_clk_src);
|
||||
rtc_clk_slow_src_set(cfg.slow_clk_src);
|
||||
#endif
|
||||
}
|
||||
|
@ -4,4 +4,21 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// TODO: IDF-5645
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/pmu_reg.h"
|
||||
#include "soc/regi2c_dig_reg.h"
|
||||
#include "regi2c_ctrl.h"
|
||||
|
||||
// TODO: IDF-5781
|
||||
|
||||
void rtc_init(rtc_config_t cfg)
|
||||
{
|
||||
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB);
|
||||
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
|
||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1);
|
||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1);
|
||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
|
||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
|
||||
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 25);
|
||||
REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, 26);
|
||||
}
|
||||
|
@ -7,10 +7,13 @@
|
||||
#include <stdint.h>
|
||||
#include "esp32c6/rom/ets_sys.h"
|
||||
#include "soc/rtc.h"
|
||||
// #include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/lp_timer_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "assert.h"
|
||||
|
||||
static const char *TAG = "rtc_time";
|
||||
|
||||
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||
* This feature counts the number of XTAL clock cycles within a given number of
|
||||
@ -24,55 +27,189 @@
|
||||
* enabled using TIMG_RTC_CALI_START bit.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
|
||||
* @param cal_clk which clock to calibrate
|
||||
* @param slowclk_cycles number of slow clock cycles to count
|
||||
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
||||
/* On ESP32C6, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3
|
||||
* 0 or 3: calibrate RC_SLOW clock
|
||||
* 1: calibrate RC_FAST clock
|
||||
* 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0
|
||||
*/
|
||||
// TODO: IDF-5645
|
||||
static const char *TAG = "rtc_time";
|
||||
#define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0
|
||||
#define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1
|
||||
#define TIMG_RTC_CALI_CLK_SEL_32K 2
|
||||
|
||||
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
ESP_EARLY_LOGW(TAG, "rtc_clk_cal_internal() has not been implemented yet");
|
||||
return 0;
|
||||
assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
|
||||
|
||||
uint32_t cali_clk_sel = 0;
|
||||
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
|
||||
soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target();
|
||||
if (cal_clk == RTC_CAL_RTC_MUX) {
|
||||
cal_clk = (rtc_cal_sel_t)slow_clk_src;
|
||||
}
|
||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST;
|
||||
} else if (cal_clk == RTC_CAL_RC_SLOW) {
|
||||
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW;
|
||||
} else {
|
||||
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K;
|
||||
clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk);
|
||||
}
|
||||
|
||||
|
||||
/* Enable requested clock (150k clock is always on) */
|
||||
// All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock
|
||||
// Only enable if orignally was disabled, and set back to the disable state after calibration is done
|
||||
// If the clock is already on, then do nothing
|
||||
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||
clk_ll_xtal32k_digi_enable();
|
||||
}
|
||||
|
||||
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
|
||||
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
|
||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
if (!rc_fast_enabled) {
|
||||
rtc_clk_8m_enable(true);
|
||||
}
|
||||
if (!dig_rc_fast_enabled) {
|
||||
rtc_dig_clk8m_enable();
|
||||
}
|
||||
}
|
||||
|
||||
bool rc32k_enabled = clk_ll_rc32k_is_enabled();
|
||||
bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
|
||||
if (cal_clk == RTC_CAL_RC32K) {
|
||||
if (!rc32k_enabled) {
|
||||
rtc_clk_rc32k_enable(true);
|
||||
}
|
||||
if (!dig_rc32k_enabled) {
|
||||
clk_ll_rc32k_digi_enable();
|
||||
}
|
||||
}
|
||||
|
||||
/* There may be another calibration process already running during we call this function,
|
||||
* so we should wait the last process is done.
|
||||
*/
|
||||
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) {
|
||||
/**
|
||||
* Set a small timeout threshold to accelerate the generation of timeout.
|
||||
* The internal circuit will be reset when the timeout occurs and will not affect the next calibration.
|
||||
*/
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1);
|
||||
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)
|
||||
&& !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
|
||||
}
|
||||
|
||||
/* Prepare calibration */
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
|
||||
/* Figure out how long to wait for calibration to finish */
|
||||
|
||||
/* Set timeout reg and expect time delay*/
|
||||
uint32_t expected_freq;
|
||||
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) {
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||
} else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
|
||||
} else {
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
|
||||
}
|
||||
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
|
||||
/* Start calibration */
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
|
||||
/* Wait for calibration to finish up to another us_time_estimate */
|
||||
esp_rom_delay_us(us_time_estimate);
|
||||
uint32_t cal_val;
|
||||
while (true) {
|
||||
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
|
||||
cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
|
||||
break;
|
||||
}
|
||||
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
|
||||
cal_val = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
|
||||
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||
clk_ll_xtal32k_digi_disable();
|
||||
}
|
||||
|
||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
if (!dig_rc_fast_enabled) {
|
||||
rtc_dig_clk8m_disable();
|
||||
}
|
||||
if (!rc_fast_enabled) {
|
||||
rtc_clk_8m_enable(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (cal_clk == RTC_CAL_RC32K) {
|
||||
if (!dig_rc32k_enabled) {
|
||||
clk_ll_rc32k_digi_disable();
|
||||
}
|
||||
if (!rc32k_enabled) {
|
||||
rtc_clk_rc32k_enable(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Always set back the calibration 32kHz clock selection
|
||||
if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
|
||||
clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
|
||||
}
|
||||
|
||||
return cal_val;
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
ESP_EARLY_LOGW(TAG, "rtc_clk_cal_ratio() has not been implemented yet");
|
||||
return 0;
|
||||
uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768
|
||||
uint64_t delta = expected_xtal_cycles / 2000; // 5/10000 = 0.05% error range
|
||||
return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta));
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
ESP_EARLY_LOGW(TAG, "rtc_clk_cal() has not been implemented yet");
|
||||
return 0;
|
||||
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
|
||||
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
|
||||
uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider;
|
||||
uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
|
||||
return period;
|
||||
}
|
||||
|
||||
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
ESP_EARLY_LOGW(TAG, "rtc_time_us_to_slowclk() has not been implemented yet");
|
||||
return 0;
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
ESP_EARLY_LOGW(TAG, "rtc_time_slowclk_to_us() has not been implemented yet");
|
||||
return 0;
|
||||
return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT;
|
||||
}
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
ESP_EARLY_LOGW(TAG, "rtc_time_get() has not been implemented yet");
|
||||
return 0;
|
||||
SET_PERI_REG_MASK(LP_TIMER_UPDATE_REG, LP_TIMER_MAIN_TIMER_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(LP_TIMER_MAIN_BUF0_LOW_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(LP_TIMER_MAIN_BUF0_HIGH_REG)) << 32;
|
||||
return t;
|
||||
}
|
||||
|
||||
uint64_t rtc_light_slp_time_get(void)
|
||||
@ -84,20 +221,22 @@ uint64_t rtc_light_slp_time_get(void)
|
||||
|
||||
uint64_t rtc_deep_slp_time_get(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
ESP_EARLY_LOGW(TAG, "rtc_deep_slp_time_get() has not been implemented yet");
|
||||
return 0;
|
||||
uint64_t t_slp = READ_PERI_REG(LP_TIMER_MAIN_BUF1_LOW_REG);
|
||||
t_slp |= ((uint64_t) READ_PERI_REG(LP_TIMER_MAIN_BUF1_HIGH_REG)) << 32;
|
||||
uint64_t t_wake = rtc_time_get();
|
||||
return (t_wake - t_slp);
|
||||
}
|
||||
|
||||
void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
// TODO: IDF-5781
|
||||
ESP_EARLY_LOGW(TAG, "rtc_clk_wait_for_slow_cycle() has not been implemented yet");
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
ESP_EARLY_LOGW(TAG, "rtc_clk_freq_cal() has not been implemented yet");
|
||||
return 0;
|
||||
if (cal_val == 0) {
|
||||
return 0; // cal_val will be denominator, return 0 as the symbol of failure.
|
||||
}
|
||||
return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ out:
|
||||
esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, uint32_t rtc_intr_mask, uint32_t flags)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5645
|
||||
ESP_LOGW(TAG, "rtc_isr_register() has not been implemented yet");
|
||||
ESP_EARLY_LOGW(TAG, "rtc_isr_register() has not been implemented yet");
|
||||
return ESP_OK;
|
||||
#else
|
||||
esp_err_t err = rtc_isr_ensure_installed();
|
||||
@ -132,7 +132,7 @@ esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, uint32_t r
|
||||
esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5645
|
||||
ESP_LOGW(TAG, "rtc_isr_deregister() has not been implemented yet");
|
||||
ESP_EARLY_LOGW(TAG, "rtc_isr_deregister() has not been implemented yet");
|
||||
return ESP_OK;
|
||||
#else
|
||||
rtc_isr_handler_t* it;
|
||||
|
@ -83,7 +83,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
|
||||
CALIBRATE_ONE(RTC_CAL_8MD256);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C2
|
||||
uint32_t cal_ext_slow_clk = CALIBRATE_ONE(RTC_CAL_EXT_32K);
|
||||
uint32_t cal_ext_slow_clk = CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
|
||||
if (cal_ext_slow_clk == 0) {
|
||||
printf("EXT CLOCK by PIN has not started up");
|
||||
} else {
|
||||
@ -93,7 +93,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
|
||||
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
CALIBRATE_ONE(RTC_CAL_8MD256);
|
||||
CALIBRATE_ONE(RTC_CAL_EXT_32K);
|
||||
CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
|
||||
}
|
||||
#else
|
||||
uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
@ -116,7 +116,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
CALIBRATE_ONE(RTC_CAL_8MD256);
|
||||
#if CONFIG_IDF_TARGET_ESP32C2
|
||||
CALIBRATE_ONE(RTC_CAL_EXT_32K);
|
||||
CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
|
||||
#else
|
||||
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
#endif
|
||||
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
ESP32C6 ECO3 ROM address table
|
||||
Version 3 API's imported from the ROM
|
||||
*/
|
||||
|
||||
esf_buf_alloc_dynamic = 0x400015c0;
|
||||
esf_buf_recycle = 0x400015c4;
|
||||
/*lmacTxDone = 0x4000162c;*/
|
||||
/*ppMapTxQueue = 0x400016d8;*/
|
||||
rcGetSched = 0x40001764;
|
||||
wDevCheckBlockError = 0x400017b4;
|
||||
/*ppProcTxDone = 0x40001804;*/
|
||||
sta_input = rom_sta_input;
|
||||
|
||||
/***************************************
|
||||
Group rom_phy
|
||||
***************************************/
|
||||
|
||||
/* Functions */
|
||||
rom_index_to_txbbgain = 0x40001964;
|
||||
rom_pbus_xpd_tx_on = 0x400019b0;
|
||||
rom_set_tx_dig_gain = 0x400019f0;
|
||||
rom_set_txcap_reg = 0x400019f4;
|
||||
rom_txbbgain_to_index = 0x40001a0c;
|
||||
rom_agc_reg_init = 0x40001a54;
|
||||
rom_bb_reg_init = 0x40001a58;
|
||||
rom_set_pbus_reg = 0x40001a70;
|
||||
rom_phy_xpd_rf = 0x40001a78;
|
||||
rom_write_txrate_power_offset = 0x40001a8c;
|
||||
rom_temp_to_power = 0x40001ab4;
|
||||
rom_open_i2c_xpd = 0x40001af8;
|
||||
rom_tsens_read_init = 0x40001b00;
|
||||
rom_tsens_code_read = 0x40001b04;
|
||||
rom_tsens_dac_cal = 0x40001b10;
|
||||
rom_pll_vol_cal = 0x40001b28;
|
||||
|
||||
/***************************************
|
||||
Group eco3_wifi
|
||||
***************************************/
|
||||
|
||||
/* Functions */
|
||||
wdev_is_data_in_rxlist = 0x40001b2c;
|
||||
ppProcTxCallback = 0x40001b30;
|
||||
ieee80211_gettid = 0x40001b34;
|
||||
|
||||
|
||||
/***************************************
|
||||
Group eco3_bluetooth
|
||||
***************************************/
|
||||
|
||||
/* Functions */
|
||||
r_lld_legacy_adv_dynamic_pti_get = 0x40001b38;
|
||||
r_lld_legacy_adv_dynamic_pti_process = 0x40001b3c;
|
||||
r_lld_ext_adv_dynamic_pti_get = 0x40001b40;
|
||||
r_lld_ext_adv_dynamic_aux_pti_process = 0x40001b44;
|
||||
r_lld_ext_adv_dynamic_pti_process = 0x40001b48;
|
||||
r_lld_adv_ext_pkt_prepare_set = 0x40001b4c;
|
||||
r_lld_adv_ext_chain_none_construct = 0x40001b50;
|
||||
r_lld_adv_ext_chain_connectable_construct = 0x40001b54;
|
||||
r_lld_adv_ext_chain_scannable_construct = 0x40001b58;
|
||||
r_lld_adv_pkt_rx_connect_post = 0x40001b5c;
|
||||
r_lld_adv_start_init_evt_param = 0x40001b60;
|
||||
r_lld_adv_start_set_cs = 0x40001b64;
|
||||
r_lld_adv_start_update_filter_policy = 0x40001b68;
|
||||
r_lld_adv_start_schedule_asap = 0x40001b6c;
|
||||
r_lld_con_tx_prog_new_packet_coex = 0x40001b70;
|
||||
r_lld_con_tx_prog_new_packet = 0x40001b74;
|
||||
r_lld_per_adv_dynamic_pti_get = 0x40001b78;
|
||||
r_lld_per_adv_evt_start_chm_upd = 0x40001b7c;
|
||||
r_lld_ext_scan_dynamic_pti_get = 0x40001b80;
|
||||
r_lld_scan_try_sched = 0x40001b84;
|
||||
r_lld_sync_insert = 0x40001b88;
|
||||
r_sch_prog_ble_push = 0x40001b8c;
|
||||
r_sch_prog_bt_push = 0x40001b90;
|
||||
r_lld_init_evt_end_type_set = 0x40001b94;
|
||||
r_lld_init_evt_end_type_get = 0x40001b98;
|
||||
r_lld_adv_direct_adv_use_rpa_addr_state_set = 0x40001b9c;
|
||||
r_lld_adv_direct_adv_use_rpa_addr_state_get = 0x40001ba0;
|
||||
r_lld_init_evt_end_type_check_state_set = 0x40001ba4;
|
||||
r_lld_init_evt_end_type_check_state_get = 0x40001ba8;
|
||||
|
||||
|
||||
/***************************************
|
||||
Group eco3_phy
|
||||
***************************************/
|
||||
|
||||
/* Functions */
|
||||
rom_wrtie_pll_cap = 0x40001bac;
|
||||
rom_set_tx_gain_mem = 0x40001bb0;
|
||||
rom_bt_tx_dig_gain = 0x40001bb4;
|
||||
rom_bt_get_tx_gain = 0x40001bb8;
|
||||
rom_get_chan_target_power = 0x40001bbc;
|
||||
rom_get_tx_gain_value = 0x40001bc0;
|
||||
rom_wifi_tx_dig_gain = 0x40001bc4;
|
||||
rom_wifi_get_tx_gain = 0x40001bc8;
|
||||
rom_fe_i2c_reg_renew = 0x40001bcc;
|
||||
rom_wifi_agc_sat_gain = 0x40001bd0;
|
||||
rom_i2c_master_reset = 0x40001bd4;
|
||||
rom_bt_filter_reg = 0x40001bd8;
|
||||
rom_phy_bbpll_cal = 0x40001bdc;
|
||||
rom_i2c_sar2_init_code = 0x40001be0;
|
||||
rom_phy_param_addr = 0x40001be4;
|
||||
rom_phy_reg_init = 0x40001be8;
|
||||
rom_set_chan_reg = 0x40001bec;
|
||||
rom_phy_wakeup_init = 0x40001bf0;
|
||||
rom_phy_i2c_init1 = 0x40001bf4;
|
||||
rom_tsens_temp_read = 0x40001bf8;
|
||||
rom_bt_track_pll_cap = 0x40001bfc;
|
||||
rom_wifi_track_pll_cap = 0x40001c00;
|
||||
rom_wifi_set_tx_gain = 0x40001c04;
|
||||
rom_txpwr_cal_track = 0x40001c08;
|
||||
rom_tx_pwctrl_background = 0x40001c0c;
|
||||
rom_bt_set_tx_gain = 0x40001c10;
|
||||
rom_noise_check_loop = 0x40001c14;
|
||||
rom_phy_close_rf = 0x40001c18;
|
||||
rom_phy_xpd_tsens = 0x40001c1c;
|
||||
rom_phy_freq_mem_backup = 0x40001c20;
|
||||
rom_phy_ant_init = 0x40001c24;
|
||||
rom_bt_track_tx_power = 0x40001c28;
|
||||
rom_wifi_track_tx_power = 0x40001c2c;
|
||||
rom_phy_dig_reg_backup = 0x40001c30;
|
||||
chip726_phyrom_version_num = 0x40001c34;
|
||||
/* Data (.data, .bss, .rodata) */
|
||||
phy_param_rom = 0x3fcdf830;
|
||||
|
||||
/***************************************
|
||||
Group eco3_esp_flash
|
||||
***************************************/
|
||||
|
||||
/* Functions */
|
||||
PROVIDE( esp_flash_read_chip_id = 0x40001c38 );
|
||||
PROVIDE( detect_spi_flash_chip = 0x40001c3c );
|
||||
PROVIDE( esp_rom_spiflash_write_disable = 0x40001c40 );
|
@ -149,7 +149,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(RTC_CAL_EXT_32K, SLOW_CLK_CAL_CYCLES);
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_OSC_SLOW, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0) {
|
||||
if (retry_ext_clk-- > 0) {
|
||||
continue;
|
||||
|
@ -10,6 +10,8 @@ choice ESP_DEFAULT_CPU_FREQ_MHZ
|
||||
depends on IDF_ENV_FPGA
|
||||
config ESP_DEFAULT_CPU_FREQ_MHZ_80
|
||||
bool "80 MHz"
|
||||
config ESP_DEFAULT_CPU_FREQ_MHZ_120
|
||||
bool "120 MHz"
|
||||
config ESP_DEFAULT_CPU_FREQ_MHZ_160
|
||||
bool "160 MHz"
|
||||
endchoice
|
||||
@ -18,4 +20,5 @@ config ESP_DEFAULT_CPU_FREQ_MHZ
|
||||
int
|
||||
default 40 if ESP_DEFAULT_CPU_FREQ_MHZ_40
|
||||
default 80 if ESP_DEFAULT_CPU_FREQ_MHZ_80
|
||||
default 120 if ESP_DEFAULT_CPU_FREQ_MHZ_120
|
||||
default 160 if ESP_DEFAULT_CPU_FREQ_MHZ_160
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "esp_clk_internal.h"
|
||||
#include "esp32c6/rom/ets_sys.h"
|
||||
#include "esp32c6/rom/uart.h"
|
||||
// #include "soc/system_reg.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
@ -23,8 +22,6 @@
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "bootloader_clock.h"
|
||||
// #include "soc/syscon_reg.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
@ -36,28 +33,7 @@
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
|
||||
* The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
|
||||
*/
|
||||
#define MIN_32K_XTAL_CAL_VAL 15000000L
|
||||
|
||||
/* Indicates that this 32k oscillator gets input from external oscillator, rather
|
||||
* than a crystal.
|
||||
*/
|
||||
#define EXT_OSC_FLAG BIT(3)
|
||||
|
||||
/* This is almost the same as soc_rtc_slow_clk_src_t, except that we define
|
||||
* an extra enum member for the external 32k oscillator.
|
||||
* For convenience, lower 2 bits should correspond to soc_rtc_slow_clk_src_t values.
|
||||
*/
|
||||
typedef enum {
|
||||
SLOW_CLK_RTC = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150 kHz RC oscillator
|
||||
SLOW_CLK_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32 kHz XTAL
|
||||
SLOW_CLK_8MD256 = SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256, //!< Internal 8 MHz RC oscillator, divided by 256
|
||||
SLOW_CLK_32K_EXT_OSC = SOC_RTC_SLOW_CLK_SRC_XTAL32K | EXT_OSC_FLAG //!< External 32k oscillator connected to 32K_XP pin
|
||||
} slow_clk_sel_t;
|
||||
|
||||
static void select_rtc_slow_clk(slow_clk_sel_t slow_clk);
|
||||
static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src);
|
||||
|
||||
static const char *TAG = "clk";
|
||||
|
||||
@ -75,8 +51,7 @@ static const char *TAG = "clk";
|
||||
|
||||
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
|
||||
|
||||
bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled();
|
||||
rtc_clk_8m_enable(true, rc_fast_d256_is_enabled);
|
||||
rtc_clk_8m_enable(true);
|
||||
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
|
||||
#endif
|
||||
|
||||
@ -96,13 +71,13 @@ static const char *TAG = "clk";
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_RTC_CLK_SRC_EXT_CRYS)
|
||||
select_rtc_slow_clk(SLOW_CLK_32K_XTAL);
|
||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K);
|
||||
#elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC)
|
||||
select_rtc_slow_clk(SLOW_CLK_32K_EXT_OSC);
|
||||
#elif defined(CONFIG_RTC_CLK_SRC_INT_8MD256)
|
||||
select_rtc_slow_clk(SLOW_CLK_8MD256);
|
||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW);
|
||||
#elif defined(CONFIG_RTC_CLK_SRC_INT_RC32K)
|
||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC32K);
|
||||
#else
|
||||
select_rtc_slow_clk(SLOW_CLK_RTC);
|
||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
||||
@ -134,11 +109,8 @@ static const char *TAG = "clk";
|
||||
esp_cpu_set_cycle_count( (uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz );
|
||||
}
|
||||
|
||||
static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
|
||||
{
|
||||
ESP_EARLY_LOGW(TAG, "select_rtc_slow_clk() has not been implemented yet");
|
||||
#if 0 // TODO: IDF-5645
|
||||
soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V;
|
||||
uint32_t cal_val = 0;
|
||||
/* number of times to repeat 32k XTAL calibration
|
||||
* before giving up and switching to the internal RC
|
||||
@ -146,7 +118,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
int retry_32k_xtal = 3;
|
||||
|
||||
do {
|
||||
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K || rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
|
||||
/* 32k XTAL oscillator needs to be enabled and running before it can
|
||||
* be used. Hardware doesn't have a direct way of checking if the
|
||||
* oscillator is running. Here we use rtc_clk_cal function to count
|
||||
@ -155,24 +127,27 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
* will time out, returning 0.
|
||||
*/
|
||||
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
|
||||
if (slow_clk == SLOW_CLK_32K_XTAL) {
|
||||
rtc_cal_sel_t cal_sel = 0;
|
||||
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
rtc_clk_32k_enable(true);
|
||||
} else if (slow_clk == SLOW_CLK_32K_EXT_OSC) {
|
||||
cal_sel = RTC_CAL_32K_XTAL;
|
||||
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
|
||||
rtc_clk_32k_enable_external();
|
||||
cal_sel = RTC_CAL_32K_OSC_SLOW;
|
||||
}
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
|
||||
cal_val = rtc_clk_cal(cal_sel, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0) {
|
||||
if (retry_32k_xtal-- > 0) {
|
||||
continue;
|
||||
}
|
||||
ESP_EARLY_LOGW(TAG, "32 kHz XTAL not found, switching to internal 150 kHz oscillator");
|
||||
ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 150 kHz oscillator");
|
||||
rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||
}
|
||||
}
|
||||
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
|
||||
rtc_clk_8m_enable(true, true);
|
||||
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
|
||||
rtc_clk_rc32k_enable(true);
|
||||
}
|
||||
rtc_clk_slow_src_set(rtc_slow_clk_src);
|
||||
|
||||
@ -188,12 +163,11 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
} while (cal_val == 0);
|
||||
ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val);
|
||||
esp_clk_slowclk_cal_set(cal_val);
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtc_clk_select_rtc_slow_clk(void)
|
||||
{
|
||||
select_rtc_slow_clk(SLOW_CLK_32K_XTAL);
|
||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K);
|
||||
}
|
||||
|
||||
/* This function is not exposed as an API at this point.
|
||||
|
@ -88,7 +88,7 @@ menu "Serial flasher config"
|
||||
choice ESPTOOLPY_FLASHFREQ
|
||||
prompt "Flash SPI speed"
|
||||
default ESPTOOLPY_FLASHFREQ_40M if IDF_TARGET_ESP32
|
||||
default ESPTOOLPY_FLASHFREQ_80M if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3
|
||||
default ESPTOOLPY_FLASHFREQ_80M if ESPTOOLPY_FLASHFREQ_80M_DEFAULT
|
||||
default ESPTOOLPY_FLASHFREQ_60M if IDF_TARGET_ESP32C2
|
||||
default ESPTOOLPY_FLASHFREQ_48M if IDF_TARGET_ESP32H4
|
||||
config ESPTOOLPY_FLASHFREQ_120M
|
||||
@ -124,6 +124,12 @@ menu "Serial flasher config"
|
||||
depends on SOC_MEMSPI_SRC_FREQ_15M_SUPPORTED
|
||||
endchoice
|
||||
|
||||
config ESPTOOLPY_FLASHFREQ_80M_DEFAULT
|
||||
bool
|
||||
default y if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C6
|
||||
help
|
||||
This is an invisible item, used to define the targets that defaults to use 80MHz Flash SPI speed.
|
||||
|
||||
config ESPTOOLPY_FLASHFREQ
|
||||
string
|
||||
# On some of the ESP chips, max boot frequency would be equal to (or even lower than) 80m.
|
||||
|
@ -45,6 +45,8 @@ extern "C" {
|
||||
#define I2S_LL_TX_EVENT_MASK I2S_LL_EVENT_TX_EOF
|
||||
#define I2S_LL_RX_EVENT_MASK I2S_LL_EVENT_RX_EOF
|
||||
|
||||
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
||||
|
||||
/* I2S clock configuration structure */
|
||||
typedef struct {
|
||||
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)
|
||||
|
@ -32,6 +32,8 @@ extern "C" {
|
||||
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
|
||||
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
|
||||
|
||||
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
||||
|
||||
/* I2S clock configuration structure */
|
||||
typedef struct {
|
||||
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)
|
||||
|
@ -10,7 +10,9 @@
|
||||
#include "soc/soc.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/pcr_reg.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
#include "soc/pmu_reg.h"
|
||||
#include "hal/regi2c_ctrl.h"
|
||||
#include "soc/regi2c_bbpll.h"
|
||||
#include "hal/assert.h"
|
||||
@ -24,9 +26,9 @@ extern "C" {
|
||||
#define MHZ (1000000)
|
||||
|
||||
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
|
||||
#define CLK_LL_PLL_120M_FREQ_MHZ (120)
|
||||
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
|
||||
|
||||
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
|
||||
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
|
||||
|
||||
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
|
||||
@ -41,7 +43,7 @@ extern "C" {
|
||||
*/
|
||||
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_EXTERNAL, //!< Enable the external clock signal for OSC_SLOW_CLK
|
||||
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
|
||||
} clk_ll_xtal32k_enable_mode_t;
|
||||
|
||||
@ -60,7 +62,9 @@ typedef struct {
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C |
|
||||
PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C);
|
||||
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG) ;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +72,8 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_BBPLL_ICG) ;
|
||||
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_BBPLL | PMU_TIE_LOW_XPD_BBPLL_I2C);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,7 +83,18 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||
*/
|
||||
static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
|
||||
// No need to configure anything for OSC_SLOW_CLK
|
||||
return;
|
||||
}
|
||||
// Configure xtal32k
|
||||
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
|
||||
LP_CLKRST.xtal32k.dac_xtal32k = cfg.dac;
|
||||
LP_CLKRST.xtal32k.dres_xtal32k = cfg.dres;
|
||||
LP_CLKRST.xtal32k.dgm_xtal32k = cfg.dgm;
|
||||
LP_CLKRST.xtal32k.dbuf_xtal32k = cfg.dbuf;
|
||||
// Enable xtal32k xpd
|
||||
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,7 +102,8 @@ static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
|
||||
*/
|
||||
static inline void clk_ll_xtal32k_disable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
// Disable xtal32k xpd
|
||||
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,8 +113,35 @@ static inline void clk_ll_xtal32k_disable(void)
|
||||
*/
|
||||
static inline bool clk_ll_xtal32k_is_enabled(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the internal oscillator output for RC32K_CLK
|
||||
*/
|
||||
static inline void clk_ll_rc32k_enable(void)
|
||||
{
|
||||
// Enable rc32k xpd status
|
||||
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the internal oscillator output for RC32K_CLK
|
||||
*/
|
||||
static inline void clk_ll_rc32k_disable(void)
|
||||
{
|
||||
// Disable rc32k xpd status
|
||||
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the state of the internal oscillator for RC32K_CLK
|
||||
*
|
||||
* @return True if the oscillator is enabled
|
||||
*/
|
||||
static inline bool clk_ll_rc32k_is_enabled(void)
|
||||
{
|
||||
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,7 +149,7 @@ static inline bool clk_ll_xtal32k_is_enabled(void)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,7 +157,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,43 +167,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
|
||||
*/
|
||||
static inline bool clk_ll_rc_fast_is_enabled(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 1;
|
||||
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,7 +175,7 @@ static inline bool clk_ll_rc_fast_d256_is_enabled(void)
|
||||
*/
|
||||
static inline void clk_ll_rc_fast_digi_enable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
LP_CLKRST.clk_to_hp.icg_hp_fosc = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,7 +183,7 @@ static inline void clk_ll_rc_fast_digi_enable(void)
|
||||
*/
|
||||
static inline void clk_ll_rc_fast_digi_disable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
LP_CLKRST.clk_to_hp.icg_hp_fosc = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -185,24 +193,7 @@ static inline void clk_ll_rc_fast_digi_disable(void)
|
||||
*/
|
||||
static inline bool clk_ll_rc_fast_digi_is_enabled(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return LP_CLKRST.clk_to_hp.icg_hp_fosc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,7 +201,7 @@ static inline void clk_ll_rc_fast_d256_digi_disable(void)
|
||||
*/
|
||||
static inline void clk_ll_xtal32k_digi_enable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,7 +209,7 @@ static inline void clk_ll_xtal32k_digi_enable(void)
|
||||
*/
|
||||
static inline void clk_ll_xtal32k_digi_disable(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,8 +219,33 @@ static inline void clk_ll_xtal32k_digi_disable(void)
|
||||
*/
|
||||
static inline bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
return LP_CLKRST.clk_to_hp.icg_hp_xtal32k;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the digital RC32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline void clk_ll_rc32k_digi_enable(void)
|
||||
{
|
||||
LP_CLKRST.clk_to_hp.icg_hp_osc32k = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the digital RC32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline void clk_ll_rc32k_digi_disable(void)
|
||||
{
|
||||
LP_CLKRST.clk_to_hp.icg_hp_osc32k = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 LP_CLKRST.clk_to_hp.icg_hp_osc32k;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -239,8 +255,8 @@ static inline bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
// The target has a fixed 480MHz SPLL
|
||||
return CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,7 +266,9 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
// The target SPLL is fixed to 480MHz
|
||||
// Do nothing
|
||||
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -261,42 +279,70 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_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;
|
||||
|
||||
/* Configure 480M PLL */
|
||||
switch (xtal_freq_mhz) {
|
||||
case RTC_XTAL_FREQ_40M:
|
||||
default:
|
||||
div_ref = 0;
|
||||
div7_0 = 8;
|
||||
dr1 = 0;
|
||||
dr3 = 0;
|
||||
dchgp = 5;
|
||||
dcur = 3;
|
||||
dbias = 2;
|
||||
break;
|
||||
}
|
||||
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
|
||||
* @brief Select the clock source for CPU_CLK (SOC Clock Root)
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
switch (in_sel) {
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 0);
|
||||
PCR.sysclk_conf.soc_clk_sel = 0;
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 1);
|
||||
PCR.sysclk_conf.soc_clk_sel = 1;
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 2);
|
||||
PCR.sysclk_conf.soc_clk_sel = 2;
|
||||
break;
|
||||
default:
|
||||
// Unsupported CPU_CLK mux input sel
|
||||
// Unsupported SOC_CLK mux input sel
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the clock source for CPU_CLK
|
||||
* @brief Get the clock source for CPU_CLK (SOC Clock Root)
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
uint32_t clk_sel = REG_GET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL);
|
||||
uint32_t clk_sel = PCR.sysclk_conf.soc_clk_sel;
|
||||
switch (clk_sel) {
|
||||
case 0:
|
||||
return SOC_CPU_CLK_SRC_XTAL;
|
||||
@ -311,45 +357,238 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CPU frequency from PLL clock
|
||||
* @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
|
||||
*
|
||||
* @param cpu_mhz CPU frequency value, in MHz
|
||||
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_cpu_set_freq_mhz_from_pll(uint32_t cpu_mhz)
|
||||
static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK
|
||||
// (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM)
|
||||
// Fixed at 3 for HS clock source
|
||||
// Corresponding register field value is PCR_HS_DIV_NUM=2
|
||||
// (2) configurable
|
||||
// HS divider option: 1, 2, 4 (PCR_CPU_HS_DIV_NUM=0, 1, 3)
|
||||
|
||||
HAL_ASSERT(divider == 3 || divider == 4 || divider == 6 || divider == 12);
|
||||
PCR.cpu_freq_conf.cpu_hs_div_num = (divider / 3) - 1;
|
||||
|
||||
// 120MHz CPU freq cannot be achieved through divider, need to set force_120m
|
||||
// This field is only valid if PCR_CPU_HS_DIV_NUM=0 and PCR_SOC_CLK_SEL=SOC_CPU_CLK_SRC_PLL
|
||||
bool force_120m = (divider == 4) ? 1 : 0;
|
||||
PCR.cpu_freq_conf.cpu_hs_120m_force = force_120m;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get CPU_CLK frequency from PLL_CLK source
|
||||
* @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
|
||||
*
|
||||
* @return CPU clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_freq_mhz_from_pll(void)
|
||||
static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK
|
||||
// (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM)
|
||||
// Fixed at 1 for LS clock source
|
||||
// Corresponding register field value is PCR_LS_DIV_NUM=0
|
||||
// (2) configurable
|
||||
// LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31)
|
||||
HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0));
|
||||
PCR.cpu_freq_conf.cpu_ls_div_num = divider - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||
* @brief Get CPU_CLK's high-speed divider
|
||||
*
|
||||
* @param divider Divider. Usually this divider is set to 1 in bootloader stage. PRE_DIV_CNT = divider - 1.
|
||||
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void)
|
||||
{
|
||||
// TODO: IDF-5645 not configurable for 761, fixed at 3 for HS, 1 for LS
|
||||
uint32_t force_120m = PCR.cpu_freq_conf.cpu_hs_120m_force;
|
||||
uint32_t cpu_hs_div = PCR.cpu_freq_conf.cpu_hs_div_num;
|
||||
if (cpu_hs_div == 0 && force_120m) {
|
||||
return 4;
|
||||
}
|
||||
return (PCR.sysclk_conf.hs_div_num + 1) * (cpu_hs_div + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get CPU_CLK's XTAL/FAST_RC clock source path divider
|
||||
* @brief Get CPU_CLK's low-speed divider
|
||||
*
|
||||
* @return Divider. Divider = (PRE_DIV_CNT + 1).
|
||||
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
return (PCR.sysclk_conf.ls_div_num + 1) * (PCR.cpu_freq_conf.cpu_ls_div_num + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set AHB_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
|
||||
*
|
||||
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1) = divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_ahb_set_hs_divider(uint32_t divider)
|
||||
{
|
||||
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK
|
||||
// (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM)
|
||||
// Fixed at 3 for HS clock source
|
||||
// Corresponding register field value is PCR_HS_DIV_NUM=2
|
||||
// (2) configurable
|
||||
// HS divider option: 4, 8, 16 (PCR_AHB_HS_DIV_NUM=3, 7, 15)
|
||||
HAL_ASSERT(divider == 12 || divider == 24 || divider == 48);
|
||||
PCR.ahb_freq_conf.ahb_hs_div_num = (divider / 3) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set AHB_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
|
||||
*
|
||||
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1) = divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_ahb_set_ls_divider(uint32_t divider)
|
||||
{
|
||||
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK
|
||||
// (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM)
|
||||
// Fixed at 1 for LS clock source
|
||||
// Corresponding register field value is PCR_LS_DIV_NUM=0
|
||||
// (2) configurable
|
||||
// LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31)
|
||||
HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0));
|
||||
PCR.ahb_freq_conf.ahb_ls_div_num = divider - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get AHB_CLK's high-speed divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void)
|
||||
{
|
||||
return (PCR.sysclk_conf.hs_div_num + 1) * (PCR.ahb_freq_conf.ahb_hs_div_num + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get AHB_CLK's low-speed divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_ls_divider(void)
|
||||
{
|
||||
return (PCR.sysclk_conf.ls_div_num + 1) * (PCR.ahb_freq_conf.ahb_ls_div_num + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set APB_CLK divider. freq of APB_CLK = freq of AHB_CLK / divider
|
||||
*
|
||||
* @param divider Divider. PCR_APB_DIV_NUM = divider - 1.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider)
|
||||
{
|
||||
// AHB ------> APB
|
||||
// Divider option: 1, 2, 4 (PCR_APB_DIV_NUM=0, 1, 3)
|
||||
HAL_ASSERT(divider == 1 || divider == 2 || divider == 4);
|
||||
PCR.apb_freq_conf.apb_div_num = divider - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get APB_CLK divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_APB_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void)
|
||||
{
|
||||
return PCR.apb_freq_conf.apb_div_num + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
|
||||
*
|
||||
* @param divider Divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider)
|
||||
{
|
||||
// SOC_ROOT_CLK ------> MSPI_FAST_CLK
|
||||
// HS divider option: 4, 5, 6 (PCR_MSPI_FAST_HS_DIV_NUM=3, 4, 5)
|
||||
switch (divider) {
|
||||
case 4:
|
||||
PCR.mspi_clk_conf.mspi_fast_hs_div_num = 3;
|
||||
break;
|
||||
case 5:
|
||||
PCR.mspi_clk_conf.mspi_fast_hs_div_num = 4;
|
||||
break;
|
||||
case 6:
|
||||
PCR.mspi_clk_conf.mspi_fast_hs_div_num = 5;
|
||||
break;
|
||||
default:
|
||||
// Unsupported HS MSPI_FAST divider
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set MSPI_FAST_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
|
||||
*
|
||||
* @param divider Divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_ls_divider(uint32_t divider)
|
||||
{
|
||||
// SOC_ROOT_CLK ------> MSPI_FAST_CLK
|
||||
// LS divider option: 1, 2, 4 (PCR_MSPI_FAST_LS_DIV_NUM=0, 1, 2)
|
||||
switch (divider) {
|
||||
case 1:
|
||||
PCR.mspi_clk_conf.mspi_fast_ls_div_num = 0;
|
||||
break;
|
||||
case 2:
|
||||
PCR.mspi_clk_conf.mspi_fast_ls_div_num = 1;
|
||||
break;
|
||||
case 4:
|
||||
PCR.mspi_clk_conf.mspi_fast_ls_div_num = 2;
|
||||
break;
|
||||
default:
|
||||
// Unsupported LS MSPI_FAST divider
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the calibration 32kHz clock source for timergroup0
|
||||
*
|
||||
* @param in_sel One of the 32kHz clock sources (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK)
|
||||
*/
|
||||
static inline void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel)
|
||||
{
|
||||
switch (in_sel) {
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC32K:
|
||||
PCR.ctrl_32k_conf.clk_32k_sel = 0;
|
||||
break;
|
||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||
PCR.ctrl_32k_conf.clk_32k_sel = 1;
|
||||
break;
|
||||
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
|
||||
PCR.ctrl_32k_conf.clk_32k_sel = 2;
|
||||
break;
|
||||
default:
|
||||
// Unsupported 32K_SEL mux input
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the calibration 32kHz clock source for timergroup0
|
||||
*
|
||||
* @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks)
|
||||
*/
|
||||
static inline soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void)
|
||||
{
|
||||
uint32_t clk_sel = PCR.ctrl_32k_conf.clk_32k_sel;
|
||||
switch (clk_sel) {
|
||||
case 0:
|
||||
return SOC_RTC_SLOW_CLK_SRC_RC32K;
|
||||
case 1:
|
||||
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
||||
case 2:
|
||||
return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW;
|
||||
default:
|
||||
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,7 +598,23 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
|
||||
*/
|
||||
static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
switch (in_sel) {
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||
LP_CLKRST.lp_clk_conf.slow_clk_sel = 0;
|
||||
break;
|
||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||
LP_CLKRST.lp_clk_conf.slow_clk_sel = 1;
|
||||
break;
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC32K:
|
||||
LP_CLKRST.lp_clk_conf.slow_clk_sel = 2;
|
||||
break;
|
||||
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
|
||||
LP_CLKRST.lp_clk_conf.slow_clk_sel = 3;
|
||||
break;
|
||||
default:
|
||||
// Unsupported RTC_SLOW_CLK mux input sel
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,8 +624,19 @@ static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||
*/
|
||||
static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
uint32_t clk_sel = LP_CLKRST.lp_clk_conf.slow_clk_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;
|
||||
case 3:
|
||||
return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW;
|
||||
default:
|
||||
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -380,7 +646,17 @@ static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||
*/
|
||||
static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
switch (in_sel) {
|
||||
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
|
||||
LP_CLKRST.lp_clk_conf.fast_clk_sel = 0;
|
||||
break;
|
||||
case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
|
||||
LP_CLKRST.lp_clk_conf.fast_clk_sel = 1;
|
||||
break;
|
||||
default:
|
||||
// Unsupported RTC_FAST_CLK mux input sel
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -390,8 +666,15 @@ static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||
*/
|
||||
static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
uint32_t clk_sel = LP_CLKRST.lp_clk_conf.fast_clk_sel;
|
||||
switch (clk_sel) {
|
||||
case 0:
|
||||
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||
case 1:
|
||||
return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
|
||||
default:
|
||||
return SOC_RTC_FAST_CLK_SRC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -401,7 +684,8 @@ static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||
*/
|
||||
static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
// No divider on the target
|
||||
HAL_ASSERT(divider == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -411,8 +695,8 @@ static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||
*/
|
||||
static inline uint32_t clk_ll_rc_fast_get_divider(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
// No divider on the target, always return divider = 1
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -422,7 +706,8 @@ static inline uint32_t clk_ll_rc_fast_get_divider(void)
|
||||
*/
|
||||
static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
// No divider on the target
|
||||
HAL_ASSERT(divider == 1);
|
||||
}
|
||||
|
||||
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/
|
||||
@ -436,7 +721,7 @@ static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||
*/
|
||||
static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -449,34 +734,13 @@ static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -490,7 +754,7 @@ static inline uint32_t clk_ll_apb_load_freq_hz(void)
|
||||
*/
|
||||
static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -502,8 +766,7 @@ static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||
*/
|
||||
static inline uint32_t clk_ll_rtc_slow_load_cal(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
return REG_READ(RTC_SLOW_CLK_CAL_REG);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -33,6 +33,8 @@ extern "C" {
|
||||
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
|
||||
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
|
||||
|
||||
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
||||
|
||||
/* I2S clock configuration structure */
|
||||
typedef struct {
|
||||
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)
|
||||
|
@ -14,21 +14,21 @@
|
||||
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 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 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
|
||||
@ -39,6 +39,25 @@ static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibrati
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register
|
||||
*/
|
||||
|
@ -550,6 +550,7 @@ static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_
|
||||
*/
|
||||
static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void)
|
||||
{
|
||||
// MAY CAN IMPROVE (ONLY rc_fast case is incorrect)!
|
||||
// TODO: Default is PLL480M, this is hard-coded.
|
||||
// In the future, we can get the CPU clock source by calling interface.
|
||||
uint8_t clock_val = 0;
|
||||
@ -584,8 +585,6 @@ static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void)
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
// Hard-coded line, will be removed when pll is enabled.
|
||||
clock_val = 80;
|
||||
|
||||
return clock_val;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
|
||||
case GPTIMER_CLK_SRC_XTAL:
|
||||
clk_id = 0;
|
||||
break;
|
||||
case GPTIMER_CLK_SRC_APB:
|
||||
case GPTIMER_CLK_SRC_PLL_F80M:
|
||||
clk_id = 1;
|
||||
break;
|
||||
default:
|
||||
|
@ -33,6 +33,8 @@ extern "C" {
|
||||
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
|
||||
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
|
||||
|
||||
#define I2S_LL_PLL_F96M_CLK_FREQ (96 * 1000000) // PLL_F96M_CLK: 96MHz
|
||||
|
||||
/* I2S clock configuration structure */
|
||||
typedef struct {
|
||||
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)
|
||||
|
@ -42,6 +42,8 @@ extern "C" {
|
||||
#define I2S_LL_TX_EVENT_MASK I2S_LL_EVENT_TX_EOF
|
||||
#define I2S_LL_RX_EVENT_MASK I2S_LL_EVENT_RX_EOF
|
||||
|
||||
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
||||
|
||||
/* I2S clock configuration structure */
|
||||
typedef struct {
|
||||
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)
|
||||
|
@ -33,6 +33,8 @@ extern "C" {
|
||||
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
|
||||
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
|
||||
|
||||
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
||||
|
||||
/* I2S clock configuration structure */
|
||||
typedef struct {
|
||||
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)
|
||||
|
@ -299,6 +299,10 @@ config SOC_I2S_SUPPORTS_APLL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PLL_F160M
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PDM
|
||||
bool
|
||||
default y
|
||||
|
@ -244,15 +244,15 @@ typedef enum {
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of I2S
|
||||
*/
|
||||
#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_D2, SOC_MOD_CLK_APLL}
|
||||
#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_APLL}
|
||||
|
||||
/**
|
||||
* @brief I2S clock source enum
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 as the default source clock */
|
||||
I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 as the source clock */
|
||||
I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default source clock */
|
||||
I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
|
||||
I2S_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as the source clock */
|
||||
} soc_periph_i2s_clk_src_t;
|
||||
|
||||
|
@ -185,6 +185,7 @@
|
||||
#define SOC_I2S_NUM (2U)
|
||||
#define SOC_I2S_HW_VERSION_1 (1)
|
||||
#define SOC_I2S_SUPPORTS_APLL (1)
|
||||
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM_TX (1)
|
||||
#define SOC_I2S_PDM_MAX_TX_LINES (1U)
|
||||
|
@ -154,7 +154,10 @@ typedef struct rtc_cpu_freq_config_s {
|
||||
typedef enum {
|
||||
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK
|
||||
RTC_CAL_8MD256 = 1, //!< Internal 8 MHz RC oscillator, divided by 256
|
||||
RTC_CAL_EXT_32K = 2 //!< External 32.768 KHz CLK
|
||||
RTC_CAL_32K_OSC_SLOW = 2, //!< External 32.768 KHz CLK
|
||||
|
||||
// deprecated name
|
||||
RTC_CAL_EXT_32K __attribute__((deprecated)) = RTC_CAL_32K_OSC_SLOW,
|
||||
} rtc_cal_sel_t;
|
||||
|
||||
/**
|
||||
|
@ -375,6 +375,10 @@ config SOC_I2S_SUPPORTS_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PLL_F160M
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PCM
|
||||
bool
|
||||
default y
|
||||
|
@ -184,6 +184,7 @@
|
||||
#define SOC_I2S_NUM (1)
|
||||
#define SOC_I2S_HW_VERSION_2 (1)
|
||||
#define SOC_I2S_SUPPORTS_XTAL (1)
|
||||
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
|
||||
#define SOC_I2S_SUPPORTS_PCM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM_TX (1)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -1,12 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "modem/reg_base.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -228,7 +227,9 @@ typedef volatile struct {
|
||||
uint32_t val;
|
||||
} date;
|
||||
} modem_lpcon_dev_t;
|
||||
|
||||
extern modem_lpcon_dev_t MODEM_LPCON;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -367,6 +367,10 @@ config SOC_I2S_SUPPORTS_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PLL_F160M
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PCM
|
||||
bool
|
||||
default y
|
||||
@ -751,7 +755,7 @@ config SOC_TIMER_GROUP_SUPPORT_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TIMER_GROUP_SUPPORT_APB
|
||||
config SOC_TIMER_GROUP_SUPPORT_PLL_F80M
|
||||
bool
|
||||
default y
|
||||
|
||||
|
@ -5,44 +5,50 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h" // TODO: IDF-5973
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// TODO: IDF-5346 Copied from C3, need to update
|
||||
/*
|
||||
************************* ESP32C6 Root Clock Source ****************************
|
||||
* 1) Internal 17.5MHz RC Oscillator: RC_FAST (usually referred as FOSC or CK8M/CLK8M in TRM and reg. description)
|
||||
* 1) Internal 17.5MHz RC Oscillator: RC_FAST (may also referred as FOSC in TRM and reg. description)
|
||||
*
|
||||
* This RC oscillator generates a ~17.5MHz clock signal output as the RC_FAST_CLK.
|
||||
* The ~17.5MHz signal output is also passed into a configurable divider, which by default divides the input clock
|
||||
* frequency by 256, to generate a RC_FAST_D256_CLK (usually referred as 8md256 or simply d256 in reg. description).
|
||||
*
|
||||
* The exact frequency of RC_FAST_CLK can be computed in runtime through calibration on the RC_FAST_D256_CLK.
|
||||
* The exact frequency of RC_FAST_CLK can be computed in runtime through calibration.
|
||||
*
|
||||
* 2) External 40MHz Crystal Clock: XTAL
|
||||
*
|
||||
* 3) Internal 136kHz RC Oscillator: RC_SLOW (usually referrred as RTC in TRM or reg. description)
|
||||
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referrred as SOSC in TRM or reg. description)
|
||||
*
|
||||
* This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock
|
||||
* can be computed in runtime through calibration.
|
||||
*
|
||||
* 4) External 32kHz Crystal Clock (optional): XTAL32K
|
||||
* 4) Internal 32kHz RC Oscillator: RC32K
|
||||
*
|
||||
* The clock source for this XTAL32K_CLK can be either a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N
|
||||
* pins or a 32kHz clock signal generated by an external circuit. The external signal must be connected to the
|
||||
* XTAL_32K_P pin.
|
||||
* The exact frequency of this clock can be computed in runtime through calibration.
|
||||
*
|
||||
* 5) External 32kHz Crystal Clock (optional): XTAL32K
|
||||
*
|
||||
* The clock source for this XTAL32K_CLK should be a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N
|
||||
* pins.
|
||||
*
|
||||
* XTAL32K_CLK can also be calibrated to get its exact frequency.
|
||||
*
|
||||
* 6) External Slow Clock (optional): OSC_SLOW
|
||||
*
|
||||
* A clock signal generated by an external circuit with frequency ~32kHz can be connected to GPIO0
|
||||
* to be the clock source for the RTC_SLOW_CLK.
|
||||
*
|
||||
* OSC_SLOW_CLK can also be calibrated to get its exact frequency.
|
||||
*/
|
||||
|
||||
/* With the default value of CK8M_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */
|
||||
/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */
|
||||
#define SOC_CLK_RC_FAST_FREQ_APPROX 17500000 /*!< Approximate RC_FAST_CLK frequency in Hz */
|
||||
#define SOC_CLK_RC_SLOW_FREQ_APPROX 136000 /*!< Approximate RC_SLOW_CLK frequency in Hz */
|
||||
#define SOC_CLK_RC_FAST_D256_FREQ_APPROX (SOC_CLK_RC_FAST_FREQ_APPROX / 256) /*!< Approximate RC_FAST_D256_CLK frequency in Hz */
|
||||
#define SOC_CLK_RC32K_FREQ_APPROX 32768 /*!< Approximate RC32K_CLK frequency in Hz */
|
||||
#define SOC_CLK_XTAL32K_FREQ_APPROX 32768 /*!< Approximate XTAL32K_CLK frequency in Hz */
|
||||
#define SOC_CLK_OSC_SLOW_FREQ_APPROX 32768 /*!< Approximate OSC_SLOW_CLK (external slow clock) frequency in Hz */
|
||||
|
||||
// Naming convention: SOC_ROOT_CLK_{loc}_{type}_[attr]
|
||||
// {loc}: EXT, INT
|
||||
@ -55,7 +61,9 @@ typedef enum {
|
||||
SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 17.5MHz RC oscillator */
|
||||
SOC_ROOT_CLK_INT_RC_SLOW, /*!< Internal 136kHz RC oscillator */
|
||||
SOC_ROOT_CLK_EXT_XTAL, /*!< External 40MHz crystal */
|
||||
SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal/clock signal */
|
||||
SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal */
|
||||
SOC_ROOT_CLK_INT_RC32K, /*!< Internal 32kHz RC oscillator */
|
||||
SOC_ROOT_CLK_EXT_OSC_SLOW, /*!< External slow clock signal at pin0, only support 32.768 kHz currently */
|
||||
} soc_root_clk_t;
|
||||
|
||||
/**
|
||||
@ -64,7 +72,7 @@ typedef enum {
|
||||
*/
|
||||
typedef enum {
|
||||
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, 480MHz) */
|
||||
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;
|
||||
@ -74,10 +82,11 @@ typedef enum {
|
||||
* @note Enum values are matched with the register field values on purpose
|
||||
*/
|
||||
typedef enum {
|
||||
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_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_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_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
|
||||
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
|
||||
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
||||
} soc_rtc_slow_clk_src_t;
|
||||
|
||||
/**
|
||||
@ -85,9 +94,9 @@ typedef enum {
|
||||
* @note Enum values are matched with the register field values on purpose
|
||||
*/
|
||||
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_RC_FAST = 0, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
|
||||
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 1, /*!< 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_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;
|
||||
|
||||
@ -106,13 +115,12 @@ typedef enum {
|
||||
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */
|
||||
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or RC_FAST_D256 by configuring soc_rtc_slow_clk_src_t */
|
||||
// For digital domain: peripherals, WIFI, BLE
|
||||
SOC_MOD_CLK_APB, /*!< APB_CLK is highly dependent on the CPU_CLK source */
|
||||
SOC_MOD_CLK_APB, /*!< APB_CLK is highly dependent on the CPU_CLK source */ // TODO: IDF-6343 This should be removed on ESP32C6! Impacts on all following peripheral drivers!
|
||||
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL, and has a fixed frequency of 80MHz */
|
||||
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from PLL, and has a fixed frequency of 160MHz */
|
||||
SOC_MOD_CLK_PLL_D2, /*!< PLL_D2_CLK is derived from PLL, it has a fixed divider of 2 */
|
||||
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from PLL, and has a fixed frequency of 240MHz */
|
||||
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_RC_FAST_D256, /*!< RC_FAST_D256_CLK comes from the internal 20MHz rc oscillator, divided by 256, and passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
|
||||
} soc_module_clk_t;
|
||||
|
||||
@ -141,32 +149,24 @@ typedef enum {
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_XTAL}
|
||||
#else
|
||||
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL}
|
||||
#endif
|
||||
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL}
|
||||
|
||||
/**
|
||||
* @brief Type of GPTimer clock source
|
||||
*/
|
||||
typedef enum {
|
||||
GPTIMER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
|
||||
GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
||||
#else
|
||||
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
||||
#endif
|
||||
GPTIMER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
|
||||
GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
|
||||
} soc_periph_gptimer_clk_src_t;
|
||||
|
||||
/**
|
||||
* @brief Type of Timer Group clock source, reserved for the legacy timer group driver
|
||||
*/
|
||||
typedef enum {
|
||||
TIMER_SRC_CLK_APB = SOC_MOD_CLK_APB, /*!< Timer group clock source is APB */
|
||||
TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL, /*!< Timer group clock source is XTAL */
|
||||
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_APB, /*!< Timer group clock source default choice is APB */
|
||||
TIMER_SRC_CLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source is PLL_F80M */
|
||||
TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL, /*!< Timer group clock source is XTAL */
|
||||
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source default choice is PLL_F80M */
|
||||
} soc_periph_tg_clk_src_legacy_t;
|
||||
|
||||
//////////////////////////////////////////////////RMT///////////////////////////////////////////////////////////////////
|
||||
@ -174,11 +174,7 @@ typedef enum {
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of RMT
|
||||
*/
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
#define SOC_RMT_CLKS {SOC_MOD_CLK_XTAL}
|
||||
#else
|
||||
#define SOC_RMT_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Type of RMT clock source
|
||||
@ -186,11 +182,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
RMT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
|
||||
RMT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
||||
#else
|
||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
||||
#endif
|
||||
} soc_periph_rmt_clk_src_t;
|
||||
|
||||
/**
|
||||
@ -227,11 +219,7 @@ typedef enum {
|
||||
UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */
|
||||
UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */
|
||||
UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< UART source clock default choice is XTAL for FPGA environment */
|
||||
#else
|
||||
UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */
|
||||
#endif
|
||||
} soc_periph_uart_clk_src_legacy_t;
|
||||
|
||||
//////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////
|
||||
@ -247,11 +235,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
MCPWM_TIMER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
|
||||
MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
|
||||
#else
|
||||
MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
|
||||
#endif
|
||||
} soc_periph_mcpwm_timer_clk_src_t;
|
||||
|
||||
/**
|
||||
@ -265,11 +249,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
MCPWM_CAPTURE_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
|
||||
MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
|
||||
#else
|
||||
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
|
||||
#endif
|
||||
} soc_periph_mcpwm_capture_clk_src_t;
|
||||
|
||||
///////////////////////////////////////////////////// I2S //////////////////////////////////////////////////////////////
|
||||
@ -277,21 +257,13 @@ typedef enum {
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of I2S
|
||||
*/
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
#define SOC_I2S_CLKS {SOC_MOD_CLK_XTAL}
|
||||
#else
|
||||
#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief I2S clock source enum
|
||||
*/
|
||||
typedef enum {
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
|
||||
#else
|
||||
I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default source clock */
|
||||
#endif
|
||||
I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
|
||||
I2S_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
} soc_periph_i2s_clk_src_t;
|
||||
|
@ -146,6 +146,8 @@
|
||||
#define USB_DM_GPIO_NUM 12
|
||||
#define USB_DP_GPIO_NUM 13
|
||||
|
||||
#define EXT_OSC_SLOW_GPIO_NUM 0
|
||||
|
||||
#define MAX_RTC_GPIO_NUM 8
|
||||
#define MAX_PAD_GPIO_NUM 30
|
||||
#define MAX_GPIO_NUM 34
|
||||
|
@ -11,7 +11,7 @@
|
||||
* @brief Register definitions for bias
|
||||
*
|
||||
* This file lists register fields of BIAS. These definitions are used via macros defined in regi2c_ctrl.h, by
|
||||
* bootloader_hardware_init function in bootloader_esp32c3.c.
|
||||
* bootloader_hardware_init function in bootloader_esp32c6.c.
|
||||
*/
|
||||
|
||||
#define I2C_BIAS 0X6A
|
||||
|
@ -9,11 +9,13 @@
|
||||
#include "esp_bit_defs.h"
|
||||
|
||||
/* Analog function control register */
|
||||
#define I2C_MST_ANA_CONF0_REG 0x6000E040
|
||||
#define I2C_MST_ANA_CONF0_REG 0x600AF818
|
||||
#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 0x600AF81C
|
||||
#define ANA_CONFIG_S (8)
|
||||
#define ANA_CONFIG_M (0x3FF)
|
||||
|
||||
@ -21,11 +23,12 @@
|
||||
#define ANA_I2C_BBPLL_M BIT(17) /* Clear to enable BBPLL */
|
||||
|
||||
|
||||
#define ANA_CONFIG2_REG 0x6000E048
|
||||
#define ANA_CONFIG2_REG 0x600AF820
|
||||
#define ANA_CONFIG2_M BIT(18)
|
||||
|
||||
#define ANA_I2C_SAR_FORCE_PU BIT(16)
|
||||
|
||||
|
||||
/**
|
||||
* Restore regi2c analog calibration related configuration registers.
|
||||
* This is a workaround, and is fixed on later chips
|
||||
|
64
components/soc/esp32c6/include/soc/regi2c_dig_reg.h
Normal file
64
components/soc/esp32c6/include/soc/regi2c_dig_reg.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file regi2c_dig_reg.h
|
||||
* @brief Register definitions for digital to get rtc voltage & digital voltage
|
||||
* by setting rtc_dbias_Wak & dig_dbias_wak or by analog self-calibration.
|
||||
*/
|
||||
|
||||
#define I2C_DIG_REG 0x6D
|
||||
#define I2C_DIG_REG_HOSTID 0
|
||||
|
||||
#define I2C_DIG_REG_EXT_RTC_DREG 4
|
||||
#define I2C_DIG_REG_EXT_RTC_DREG_MSB 4
|
||||
#define I2C_DIG_REG_EXT_RTC_DREG_LSB 0
|
||||
|
||||
#define I2C_DIG_REG_ENX_RTC_DREG 4
|
||||
#define I2C_DIG_REG_ENX_RTC_DREG_MSB 7
|
||||
#define I2C_DIG_REG_ENX_RTC_DREG_LSB 7
|
||||
|
||||
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP 5
|
||||
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB 4
|
||||
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB 0
|
||||
|
||||
#define I2C_DIG_REG_ENIF_RTC_DREG 5
|
||||
#define I2C_DIG_REG_ENIF_RTC_DREG_MSB 7
|
||||
#define I2C_DIG_REG_ENIF_RTC_DREG_LSB 7
|
||||
|
||||
#define I2C_DIG_REG_EXT_DIG_DREG 6
|
||||
#define I2C_DIG_REG_EXT_DIG_DREG_MSB 4
|
||||
#define I2C_DIG_REG_EXT_DIG_DREG_LSB 0
|
||||
|
||||
#define I2C_DIG_REG_ENX_DIG_DREG 6
|
||||
#define I2C_DIG_REG_ENX_DIG_DREG_MSB 7
|
||||
#define I2C_DIG_REG_ENX_DIG_DREG_LSB 7
|
||||
|
||||
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP 7
|
||||
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB 4
|
||||
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB 0
|
||||
|
||||
#define I2C_DIG_REG_ENIF_DIG_DREG 7
|
||||
#define I2C_DIG_REG_ENIF_DIG_DREG_MSB 7
|
||||
#define I2C_DIG_REG_ENIF_DIG_DREG_LSB 7
|
||||
|
||||
#define I2C_DIG_REG_OR_EN_CONT_CAL 9
|
||||
#define I2C_DIG_REG_OR_EN_CONT_CAL_MSB 7
|
||||
#define I2C_DIG_REG_OR_EN_CONT_CAL_LSB 7
|
||||
|
||||
#define I2C_DIG_REG_XPD_RTC_REG 13
|
||||
#define I2C_DIG_REG_XPD_RTC_REG_MSB 2
|
||||
#define I2C_DIG_REG_XPD_RTC_REG_LSB 2
|
||||
|
||||
#define I2C_DIG_REG_XPD_DIG_REG 13
|
||||
#define I2C_DIG_REG_XPD_DIG_REG_MSB 3
|
||||
#define I2C_DIG_REG_XPD_DIG_REG_LSB 3
|
||||
|
||||
#define I2C_DIG_REG_SCK_DCAP 14
|
||||
#define I2C_DIG_REG_SCK_DCAP_MSB 7
|
||||
#define I2C_DIG_REG_SCK_DCAP_LSB 0
|
@ -46,13 +46,14 @@ extern "C" {
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
#define RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
|
||||
#define RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
|
||||
#define RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(cycles) (cycles << 10)
|
||||
#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
|
||||
#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value
|
||||
|
||||
#define OTHER_BLOCKS_POWERUP 1
|
||||
#define OTHER_BLOCKS_WAIT 1
|
||||
|
||||
// TODO: IDF-5781
|
||||
/* Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP,
|
||||
* RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values.
|
||||
*/
|
||||
@ -74,9 +75,10 @@ extern "C" {
|
||||
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
|
||||
#define SOC_DELAY_RC_FAST_ENABLE 50
|
||||
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
|
||||
#define SOC_DELAY_RC32K_ENABLE 300
|
||||
|
||||
/* Core voltage:
|
||||
* Currently, ESP32C3 never adjust its wake voltage in runtime
|
||||
/* Core voltage: // TODO: IDF-5781
|
||||
* Currently, ESP32C6 never adjust its wake voltage in runtime
|
||||
* Only sets dig/rtc voltage dbias at startup time
|
||||
*/
|
||||
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
|
||||
@ -89,8 +91,9 @@ extern "C" {
|
||||
#define RTC_CNTL_CK8M_WAIT_DEFAULT 20
|
||||
#define RTC_CK8M_ENABLE_WAIT_DEFAULT 5
|
||||
|
||||
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100
|
||||
#define RTC_CNTL_SCK_DCAP_DEFAULT 255
|
||||
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100
|
||||
#define RTC_CNTL_SCK_DCAP_DEFAULT 128
|
||||
#define RTC_CNTL_RC32K_DFREQ_DEFAULT 700
|
||||
|
||||
/* Various delays to be programmed into power control state machines */
|
||||
#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (250)
|
||||
@ -140,7 +143,7 @@ typedef enum {
|
||||
typedef struct rtc_cpu_freq_config_s {
|
||||
soc_cpu_clk_src_t source; //!< The clock from which CPU clock is derived
|
||||
uint32_t source_freq_mhz; //!< Source clock frequency
|
||||
uint32_t div; //!< Divider, freq_mhz = source_freq_mhz / div
|
||||
uint32_t div; //!< Divider, freq_mhz = SOC_ROOT_CLK freq_mhz / div
|
||||
uint32_t freq_mhz; //!< CPU clock frequency
|
||||
} rtc_cpu_freq_config_t;
|
||||
|
||||
@ -151,12 +154,18 @@ typedef struct rtc_cpu_freq_config_s {
|
||||
|
||||
/**
|
||||
* @brief Clock source to be calibrated using rtc_clk_cal function
|
||||
*
|
||||
* @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL
|
||||
* However, this is not true on ESP32C6. The conversion to register field values is explicitly done in
|
||||
* rtc_clk_cal_internal
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK
|
||||
RTC_CAL_32K_XTAL = 2, //!< External 32 kHz XTAL
|
||||
RTC_CAL_INTERNAL_OSC = 3, //!< Internal 150 kHz oscillator
|
||||
RTC_CAL_RC_FAST, //!< Internal 20 MHz oscillator
|
||||
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
|
||||
RTC_CAL_RC_SLOW = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150kHz RC oscillator
|
||||
RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock
|
||||
RTC_CAL_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32kHz XTAL, as one type of 32k clock
|
||||
RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_OSC_SLOW, //!< External 32kHz clk signal input by lp_pad_gpio0, as one type of 32k clock
|
||||
RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator
|
||||
} rtc_cal_sel_t;
|
||||
|
||||
/**
|
||||
@ -166,11 +175,12 @@ typedef struct {
|
||||
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
|
||||
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
|
||||
soc_rtc_fast_clk_src_t fast_clk_src : 2; //!< RTC_FAST_CLK clock source to choose
|
||||
soc_rtc_slow_clk_src_t slow_clk_src : 2; //!< RTC_SLOW_CLK clock source to choose
|
||||
soc_rtc_slow_clk_src_t slow_clk_src : 3; //!< RTC_SLOW_CLK clock source to choose
|
||||
uint32_t clk_rtc_clk_div : 8;
|
||||
uint32_t clk_8m_clk_div : 3; //!< 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 clk_8m_dfreq : 8; //!< RTC 8m clock adjustment parameter (higher value leads to higher frequency)
|
||||
uint32_t clk_8m_clk_div : 3; //!< RC_FAST clock divider (division is by clk_8m_div+1, i.e. 0 means ~20MHz frequency)
|
||||
uint32_t slow_clk_dcap : 8; //!< RC_SLOW clock adjustment parameter (higher value leads to lower frequency)
|
||||
uint32_t clk_8m_dfreq : 8; //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency)
|
||||
uint32_t rc32k_dfreq : 10; //!< Internal RC32K clock adjustment parameter (higher value leads to higher frequency)
|
||||
} rtc_clk_config_t;
|
||||
|
||||
/**
|
||||
@ -185,6 +195,7 @@ typedef struct {
|
||||
.clk_8m_clk_div = 0, \
|
||||
.slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \
|
||||
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
||||
.rc32k_dfreq = RTC_CNTL_RC32K_DFREQ_DEFAULT, \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -213,10 +224,6 @@ typedef struct {
|
||||
.dg_peri_wait_cycles = OTHER_BLOCKS_WAIT, \
|
||||
}
|
||||
|
||||
void rtc_clk_divider_set(uint32_t div);
|
||||
|
||||
void rtc_clk_8m_divider_set(uint32_t div);
|
||||
|
||||
/**
|
||||
* Initialize clocks and set CPU frequency
|
||||
*
|
||||
@ -273,23 +280,18 @@ bool rtc_clk_32k_enabled(void);
|
||||
*/
|
||||
void rtc_clk_32k_bootstrap(uint32_t cycle);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable 32 kHz internal rc oscillator
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
void rtc_clk_rc32k_enable(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable 8 MHz internal oscillator
|
||||
*
|
||||
* Output from 8 MHz internal oscillator is passed into a configurable
|
||||
* divider, which by default divides the input clock frequency by 256.
|
||||
* Output of the divider may be used as RTC_SLOW_CLK source.
|
||||
* Output of the divider is referred to in register descriptions and code as
|
||||
* 8md256 or simply d256. Divider values other than 256 may be configured, but
|
||||
* this facility is not currently needed, so is not exposed in the code.
|
||||
*
|
||||
* When 8MHz/256 divided output is not needed, the divider should be disabled
|
||||
* to reduce power consumption.
|
||||
*
|
||||
* @param clk_8m_en true to enable 8MHz generator
|
||||
* @param d256_en true to enable /256 divider
|
||||
*/
|
||||
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en);
|
||||
void rtc_clk_8m_enable(bool clk_8m_en);
|
||||
|
||||
/**
|
||||
* @brief Get the state of 8 MHz internal oscillator
|
||||
@ -297,12 +299,6 @@ void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en);
|
||||
*/
|
||||
bool rtc_clk_8m_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Get the state of /256 divider which is applied to 8MHz clock
|
||||
* @return true if the divided output is enabled
|
||||
*/
|
||||
bool rtc_clk_8md256_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Select source for RTC_SLOW_CLK
|
||||
* @param clk_src clock source (one of soc_rtc_slow_clk_src_t values)
|
||||
@ -401,25 +397,29 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config);
|
||||
void rtc_clk_cpu_freq_set_xtal(void);
|
||||
|
||||
/**
|
||||
* @brief Store new APB frequency value into RTC_APB_FREQ_REG
|
||||
*
|
||||
* This function doesn't change any hardware clocks.
|
||||
*
|
||||
* Functions which perform frequency switching and change APB frequency call
|
||||
* this function to update the value of APB frequency stored in RTC_APB_FREQ_REG
|
||||
* (one of RTC general purpose retention registers). This should not normally
|
||||
* be called from application code.
|
||||
*
|
||||
* @param apb_freq new APB frequency, in Hz
|
||||
*/
|
||||
void rtc_clk_apb_freq_update(uint32_t apb_freq);
|
||||
|
||||
/**
|
||||
* @brief Get the current stored APB frequency.
|
||||
* @return The APB frequency value as last set via rtc_clk_apb_freq_update(), in Hz.
|
||||
* @brief Get the current APB frequency.
|
||||
* @return The calculated APB frequency value, in Hz.
|
||||
*/
|
||||
uint32_t rtc_clk_apb_freq_get(void);
|
||||
|
||||
/**
|
||||
* @brief Clock calibration function used by rtc_clk_cal
|
||||
*
|
||||
* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||
* This feature counts the number of XTAL clock cycles within a given number of
|
||||
* RTC_SLOW_CLK cycles.
|
||||
*
|
||||
* Slow clock calibration feature has two modes of operation: one-off and cycling.
|
||||
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
|
||||
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
|
||||
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
|
||||
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
|
||||
* enabled using TIMG_RTC_CALI_START bit.
|
||||
*
|
||||
* @param cal_clk which clock to calibrate
|
||||
* @param slowclk_cycles number of slow clock cycles to count
|
||||
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
||||
*/
|
||||
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
|
||||
|
||||
/**
|
||||
@ -430,6 +430,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
|
||||
* 32k XTAL is being calibrated, but the oscillator has not started up (due to
|
||||
* incorrect loading capacitance, board design issue, or lack of 32 XTAL on board).
|
||||
*
|
||||
* @note When 32k CLK is being calibrated, this function will check the accuracy
|
||||
* of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if
|
||||
* the check fails, then consider this an invalid 32k clock and return 0. This
|
||||
* check can filter some jamming signal.
|
||||
*
|
||||
* @param cal_clk clock to be measured
|
||||
* @param slow_clk_cycles number of slow clock cycles to average
|
||||
* @return average slow clock period in microseconds, Q13.19 fixed point format,
|
||||
@ -437,15 +442,6 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
|
||||
*/
|
||||
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles);
|
||||
|
||||
/**
|
||||
* @brief Measure ratio between XTAL frequency and RTC slow clock frequency
|
||||
* @param cal_clk slow clock to be measured
|
||||
* @param slow_clk_cycles number of slow clock cycles to average
|
||||
* @return average ratio between XTAL frequency and slow clock frequency,
|
||||
* Q13.19 fixed point format, or 0 if calibration has timed out.
|
||||
*/
|
||||
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles);
|
||||
|
||||
/**
|
||||
* @brief Convert time interval from microseconds to RTC_SLOW_CLK cycles
|
||||
* @param time_in_us Time interval in microseconds
|
||||
|
@ -140,19 +140,10 @@
|
||||
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
|
||||
#define EFUSE_CLK_FREQ_ROM ( 20*1000000)
|
||||
#define CPU_CLK_FREQ APB_CLK_FREQ
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
#define APB_CLK_FREQ ( 40*1000000 )
|
||||
#else
|
||||
#define APB_CLK_FREQ ( 80*1000000 )
|
||||
#endif
|
||||
#define APB_CLK_FREQ ( 80*1000000 ) // TODO: IDF-6343 APB clock freq is 40MHz indeed
|
||||
#define REF_CLK_FREQ ( 1000000 )
|
||||
#define RTC_CLK_FREQ (20*1000000)
|
||||
#define XTAL_CLK_FREQ (40*1000000)
|
||||
#define UART_CLK_FREQ APB_CLK_FREQ
|
||||
#define WDT_CLK_FREQ APB_CLK_FREQ
|
||||
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16
|
||||
#define SPI_CLK_DIV 4
|
||||
#define TICKS_PER_US_ROM 40 // CPU is 80MHz
|
||||
#define GPIO_MATRIX_DELAY_NS 0
|
||||
//}}
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
||||
#define SOC_I2S_NUM (1)
|
||||
#define SOC_I2S_HW_VERSION_2 (1)
|
||||
#define SOC_I2S_SUPPORTS_XTAL (1)
|
||||
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
|
||||
#define SOC_I2S_SUPPORTS_PCM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM_TX (1)
|
||||
@ -362,7 +363,7 @@
|
||||
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
|
||||
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
||||
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
||||
#define SOC_TIMER_GROUP_SUPPORT_APB (1)
|
||||
#define SOC_TIMER_GROUP_SUPPORT_PLL_F80M (1)
|
||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
|
||||
#define SOC_TIMER_SUPPORT_ETM (1)
|
||||
|
||||
|
@ -351,6 +351,10 @@ config SOC_I2S_SUPPORTS_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PLL_F96M
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PCM
|
||||
bool
|
||||
default y
|
||||
|
@ -58,3 +58,7 @@
|
||||
#define I2C_DIG_REG_XPD_DIG_REG 13
|
||||
#define I2C_DIG_REG_XPD_DIG_REG_MSB 3
|
||||
#define I2C_DIG_REG_XPD_DIG_REG_LSB 3
|
||||
|
||||
#define I2C_DIG_REG_SCK_DCAP 14
|
||||
#define I2C_DIG_REG_SCK_DCAP_MSB 7
|
||||
#define I2C_DIG_REG_SCK_DCAP_LSB 0
|
||||
|
@ -191,6 +191,7 @@
|
||||
#define SOC_I2S_NUM (1)
|
||||
#define SOC_I2S_HW_VERSION_2 (1)
|
||||
#define SOC_I2S_SUPPORTS_XTAL (1)
|
||||
#define SOC_I2S_SUPPORTS_PLL_F96M (1)
|
||||
#define SOC_I2S_SUPPORTS_PCM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM_TX (1)
|
||||
|
@ -363,6 +363,10 @@ config SOC_I2S_SUPPORTS_APLL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PLL_F160M
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_DMA_EQUAL
|
||||
bool
|
||||
default y
|
||||
|
@ -181,6 +181,7 @@
|
||||
#define SOC_I2S_NUM (1U)
|
||||
#define SOC_I2S_HW_VERSION_1 (1)
|
||||
#define SOC_I2S_SUPPORTS_APLL (1)
|
||||
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
|
||||
#define SOC_I2S_SUPPORTS_DMA_EQUAL (1)
|
||||
#define SOC_I2S_SUPPORTS_LCD_CAMERA (1)
|
||||
#define SOC_I2S_APLL_MIN_FREQ (250000000)
|
||||
|
@ -419,6 +419,10 @@ config SOC_I2S_SUPPORTS_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PLL_F160M
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PCM
|
||||
bool
|
||||
default y
|
||||
|
@ -185,6 +185,7 @@
|
||||
#define SOC_I2S_NUM (2)
|
||||
#define SOC_I2S_HW_VERSION_2 (1)
|
||||
#define SOC_I2S_SUPPORTS_XTAL (1)
|
||||
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
|
||||
#define SOC_I2S_SUPPORTS_PCM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM_TX (1)
|
||||
|
Loading…
Reference in New Issue
Block a user