Merge branch 'feature/c3_hw_sup_merge_master' into 'master'

esp_hw_support: merge C3 changes to master

See merge request espressif/esp-idf!11820
This commit is contained in:
Angus Gratton 2020-12-30 20:06:23 +08:00
commit 62cc864cbe
20 changed files with 375 additions and 364 deletions

View File

@ -261,10 +261,14 @@ static inline void bootloader_hardware_init(void)
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12);
}
/* There happend clock glitch reset for some chip when testing wifi[BIT0] and brownout reset when chip startup[BIT1].
* But super_watch_dog_reset function is ok, so open it[BIT2].
* Whether this api will deleted or not depends on analog design & test result when ECO chip come back.
*/
static inline void bootloader_glitch_reset_disable(void)
{
// TODO ESP32-C3 IDF-2453
REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, 0);
REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, BIT2);
}
esp_err_t bootloader_init(void)

View File

@ -10,7 +10,7 @@ set(srcs "cpu_util_esp32c3.c"
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
target_include_directories(${COMPONENT_LIB} PUBLIC . include)
target_include_directories(${COMPONENT_LIB} PUBLIC . private_include)
target_include_directories(${COMPONENT_LIB} PRIVATE ../hal)
if(NOT CMAKE_BUILD_EARLY_EXPANSION)

View File

@ -15,8 +15,7 @@
#pragma once
#include <stdint.h>
#include "i2c_apll.h"
#include "i2c_bbpll.h"
#include "regi2c_ctrl.h"
/* Analog function control register */
#define ANA_CONFIG_REG 0x6000E044

View File

@ -23,7 +23,7 @@
*/
#define I2C_BOD 0x61
#define I2C_BOD_HOSTID 1
#define I2C_BOD_HOSTID 0
#define I2C_BOD_THRESHOLD 0x5
#define I2C_BOD_THRESHOLD_MSB 2

View File

@ -41,3 +41,11 @@
#define I2C_ULP_IR_FORCE_XPD_IPH 0
#define I2C_ULP_IR_FORCE_XPD_IPH_MSB 4
#define I2C_ULP_IR_FORCE_XPD_IPH_LSB 4
#define I2C_ULP_IR_FORCE_XPD_CK 0
#define I2C_ULP_IR_FORCE_XPD_CK_MSB 2
#define I2C_ULP_IR_FORCE_XPD_CK_LSB 2
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK 0
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_MSB 6
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_LSB 6

View File

@ -24,7 +24,7 @@
*/
#define I2C_SAR_ADC 0X69
#define I2C_SAR_ADC_HOSTID 1
#define I2C_SAR_ADC_HOSTID 0
#define ADC_SAR1_ENCAL_GND_ADDR 0x7
#define ADC_SAR1_ENCAL_GND_ADDR_MSB 5

View File

@ -48,12 +48,6 @@ extern "C" {
/* Clear to enable BBPLL */
#define I2C_BBPLL_M (BIT(17))
#define SAR_I2C_FORCE_PD BIT(18)
#define SAR_I2C_FORCE_PU BIT(16)
#define ANA_CONFIG2_REG 0x6000E048
#define ANA_CONFIG2_M (BIT(18))
/* ROM functions which read/write internal control bus */
uint8_t rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add);
uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb);

View File

@ -28,7 +28,7 @@
#include "soc/efuse_reg.h"
#include "soc/syscon_reg.h"
#include "soc/system_reg.h"
#include "i2c_rtc_clk.h"
#include "regi2c_ctrl.h"
#include "soc_log.h"
#include "rtc_clk_common.h"
#include "esp_rom_sys.h"
@ -55,17 +55,27 @@ void rtc_clk_32k_enable_internal(x32k_config_t cfg)
void rtc_clk_32k_enable(bool enable)
{
abort(); // TODO ESP32-C3 IDF-2408
if (enable) {
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
rtc_clk_32k_enable_internal(cfg);
} else {
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
}
}
void rtc_clk_32k_enable_external(void)
{
abort(); // TODO ESP32-C3 IDF-2408
/* TODO ESP32-C3 IDF-2408: external 32k source may need different settings */
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
rtc_clk_32k_enable_internal(cfg);
}
void rtc_clk_32k_bootstrap(uint32_t cycle)
{
/* No special bootstrapping needed. Just enable the XTAL here. */
/* No special bootstrapping needed for ESP32-C3, 'cycle' argument is to keep the signature
* same as for the ESP32. Just enable the XTAL here.
*/
(void) cycle;
rtc_clk_32k_enable(true);
}
@ -112,32 +122,6 @@ bool rtc_clk_8md256_enabled(void)
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
}
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div)
{
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1);
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0);
if (enable) {
I2C_WRITEREG_MASK_RTC(I2C_APLL, I2C_APLL_DSDM2, sdm2);
I2C_WRITEREG_MASK_RTC(I2C_APLL, I2C_APLL_DSDM0, sdm0);
I2C_WRITEREG_MASK_RTC(I2C_APLL, I2C_APLL_DSDM1, sdm1);
I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_1);
I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_2_REV1);
I2C_WRITEREG_MASK_RTC(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
/* calibration */
I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_1);
I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_2);
I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_3);
/* wait for calibration end */
while (!(I2C_READREG_MASK_RTC(I2C_APLL, I2C_APLL_OR_CAL_END))) {
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
esp_rom_delay_us(1);
}
}
}
void rtc_clk_set_xtal_wait(void)
{
/*
@ -145,12 +129,10 @@ void rtc_clk_set_xtal_wait(void)
and `RTC_CNTL_XTL_BUF_WAIT` depend on it.
*/
rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
if (slow_clk_freq == (rtc_slow_freq_x32k)) {
if (slow_clk_freq == RTC_SLOW_FREQ_32K_XTAL) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_freq == rtc_slow_freq_8MD256) {
} else if (slow_clk_freq == RTC_SLOW_FREQ_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 2000);
@ -161,6 +143,18 @@ void rtc_clk_set_xtal_wait(void)
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, xtal_wait_1ms);
}
static void wait_dig_dbias_valid(uint64_t rtc_cycles)
{
rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
if (slow_clk_freq == RTC_SLOW_FREQ_32K_XTAL) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_freq == RTC_SLOW_FREQ_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
rtc_clk_cal(cal_clk, rtc_cycles);
}
void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
{
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
@ -226,55 +220,87 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
uint8_t dr3;
uint8_t dchgp;
uint8_t dcur;
assert(xtal_freq == RTC_XTAL_FREQ_40M);
uint8_t dbias;
if (pll_freq == RTC_PLL_FREQ_480M) {
/* Clear this register to let the digital part know 480M PLL is used */
/* Set this register to let the digital part know 480M PLL is used */
SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
/* Configure 480M PLL */
switch (xtal_freq) {
case RTC_XTAL_FREQ_40M:
div_ref = 0;
div7_0 = 8;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 4;
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
dcur = 3;
dbias = 2;
break;
case RTC_XTAL_FREQ_32M:
div_ref = 1;
div7_0 = 26;
dr1 = 1;
dr3 = 1;
dchgp = 4;
dcur = 0;
dbias = 2;
break;
default:
div_ref = 0;
div7_0 = 8;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
}
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
} else {
/* Clear this register to let the digital part know 320M PLL is used */
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
/* Configure 320M PLL */
switch (xtal_freq) {
case RTC_XTAL_FREQ_40M:
div_ref = 0;
div7_0 = 4;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 5;
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
dcur = 3;
dbias = 2;
break;
case RTC_XTAL_FREQ_32M:
div_ref = 1;
div7_0 = 6;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
default:
div_ref = 0;
div7_0 = 4;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
}
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
}
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_bbpll_div_7_0 = div7_0;
uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_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);
// Enable calibration by software
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_IR_CAL_ENX_CAP, 1);
for (int ext_cap = 0; ext_cap < 16; ext_cap++) {
uint8_t cal_result;
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, ext_cap);
cal_result = I2C_READREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OR_CAL_CAP);
if (cal_result == 0) {
break;
}
if (ext_cap == 15) {
SOC_LOGE(TAG, "BBPLL SOFTWARE CAL FAIL");
abort();
}
}
s_cur_pll_freq = pll_freq;
}
@ -285,19 +311,26 @@ 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)
{
//int dbias = DIG_DBIAS_80M_160M;
int origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
int origin_cpuperiod_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
int dbias = DIG_DBIAS_80M;
int per_conf = DPORT_CPUPERIOD_SEL_80;
if (cpu_freq_mhz == 80) {
/* nothing to do */
} else if (cpu_freq_mhz == 160) {
dbias = DIG_DBIAS_160M;
per_conf = DPORT_CPUPERIOD_SEL_160;
} else {
SOC_LOGE(TAG, "invalid frequency");
abort();
}
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias);
if ((origin_soc_clk == DPORT_SOC_CLK_SEL_XTAL) || (origin_soc_clk == DPORT_SOC_CLK_SEL_8M)
|| (((origin_soc_clk == DPORT_SOC_CLK_SEL_PLL) && (0 == origin_cpuperiod_sel)))) {
wait_dig_dbias_valid(2);
}
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, per_conf);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
//REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_PLL);
rtc_clk_apb_freq_update(80 * MHZ);
ets_update_cpu_frequency(cpu_freq_mhz);
@ -346,24 +379,23 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
{
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
if (soc_clk_sel != DPORT_SOC_CLK_SEL_XTAL) {
rtc_clk_cpu_freq_to_xtal(xtal_freq, 1);
}
if (config->source == RTC_CPU_FREQ_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
rtc_clk_bbpll_disable();
}
if (config->source == RTC_CPU_FREQ_SRC_XTAL) {
if (config->div > 1) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
}
} else if (config->source == RTC_CPU_FREQ_SRC_PLL) {
if (soc_clk_sel != DPORT_SOC_CLK_SEL_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 == RTC_CPU_FREQ_SRC_8M) {
rtc_clk_cpu_freq_to_8m();
if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
rtc_clk_bbpll_disable();
}
}
}
@ -406,7 +438,6 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
div = 1;
freq_mhz = source_freq_mhz;
break;
case DPORT_SOC_CLK_SEL_APLL:
default:
SOC_LOGE(TAG, "unsupported frequency configuration");
abort();
@ -419,53 +450,6 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
};
}
void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq)
{
rtc_xtal_freq_t xtal_freq = RTC_XTAL_FREQ_40M;
/* Switch CPU to XTAL frequency first */
//REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
//REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, APB_CTRL_SOC_CLK_SEL_XTL);
//REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 1);
//ets_update_cpu_frequency(xtal_freq);
/* Frequency switch is synchronized to SLOW_CLK cycle. Wait until the switch
* is complete before disabling the PLL.
*/
rtc_clk_wait_for_slow_cycle();
REG_SET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
//REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 0);
// SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
// RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD |
// RTC_CNTL_BBPLL_I2C_FORCE_PD);
s_cur_pll_freq = 0;
rtc_clk_apb_freq_update(xtal_freq * MHZ);
if (cpu_freq == RTC_CPU_FREQ_XTAL) {
/* already at XTAL, nothing to do */
} else if (cpu_freq == RTC_CPU_FREQ_2M) {
/* set up divider to produce 2MHz from XTAL */
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, (xtal_freq / 2) - 1);
ets_update_cpu_frequency(2);
rtc_clk_apb_freq_update(2 * MHZ);
} else {
/* use PLL as clock source */
if (cpu_freq == RTC_CPU_FREQ_80M) {
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 0);
ets_update_cpu_frequency(80);
s_cur_pll_freq = RTC_PLL_FREQ_480M;
} else if (cpu_freq == RTC_CPU_FREQ_160M) {
//REG_CLR_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 1);
ets_update_cpu_frequency(160);
s_cur_pll_freq = RTC_PLL_FREQ_480M;
}
#define APB_CTRL_SOC_CLK_SEL_PLL 1
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, APB_CTRL_SOC_CLK_SEL_PLL);
rtc_clk_wait_for_slow_cycle();
rtc_clk_apb_freq_update(80 * MHZ);
}
s_cur_pll_freq = cpu_freq;
}
void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
{
if (config->source == RTC_CPU_FREQ_SRC_XTAL) {
@ -492,7 +476,18 @@ void rtc_clk_cpu_freq_set_xtal(void)
*/
void rtc_clk_cpu_freq_to_xtal(int freq, int div)
{
int origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
int origin_div_cnt = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT);
ets_update_cpu_frequency(freq);
/* lower the voltage */
if (freq <= 2) {
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_2M);
} else {
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
}
if ((DPORT_SOC_CLK_SEL_XTAL == origin_soc_clk) && (origin_div_cnt > 0)) {
wait_dig_dbias_valid(2);
}
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, div - 1);
@ -500,18 +495,17 @@ void rtc_clk_cpu_freq_to_xtal(int freq, int div)
/* switch clock source */
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
rtc_clk_apb_freq_update(freq * MHZ);
/* lower the voltage */
if (freq <= 2) {
//REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_2M);
} else {
//REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
}
}
static void rtc_clk_cpu_freq_to_8m(void)
{
int origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
int origin_div_cnt = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT);
ets_update_cpu_frequency(8);
//REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
if ((DPORT_SOC_CLK_SEL_XTAL == origin_soc_clk) && (origin_div_cnt > 4)) {
wait_dig_dbias_valid(2);
}
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_8M);
rtc_clk_apb_freq_update(RTC_FAST_CLK_FREQ_8M);

View File

@ -18,12 +18,10 @@
#define DPORT_CPUPERIOD_SEL_80 0
#define DPORT_CPUPERIOD_SEL_160 1
#define DPORT_CPUPERIOD_SEL_240 2
#define DPORT_SOC_CLK_SEL_XTAL 0
#define DPORT_SOC_CLK_SEL_PLL 1
#define DPORT_SOC_CLK_SEL_8M 2
#define DPORT_SOC_CLK_SEL_APLL 3
#define RTC_FAST_CLK_FREQ_8M 8500000

View File

@ -24,7 +24,7 @@
#include "soc/sens_periph.h"
#include "soc/efuse_periph.h"
#include "soc/apb_ctrl_reg.h"
#include "i2c_rtc_clk.h"
#include "regi2c_ctrl.h"
#include "soc_log.h"
#include "sdkconfig.h"
#include "rtc_clk_common.h"

View File

@ -22,52 +22,42 @@
#include "soc/spi_mem_reg.h"
#include "soc/extmem_reg.h"
#include "soc/system_reg.h"
#include "i2c_rtc_clk.h"
#include "regi2c_ctrl.h"
#include "soc_log.h"
static const char *TAG = "rtc_init";
void rtc_init(rtc_config_t cfg)
{
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU);
rtc_clk_set_xtal_wait();
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, cfg.pll_wait);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, cfg.ck8m_wait);
REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
/* Moved from rtc sleep to rtc init to save sleep function running time */
// set shortest possible sleep time limit
//REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
/* This power domian removed
* set rom&ram timer
* REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_ROM_RAM_POWERUP_TIMER, ROM_RAM_POWERUP_CYCLES);
* REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_ROM_RAM_WAIT_TIMER, ROM_RAM_WAIT_CYCLES);
*/
// set wifi timer
// set default powerup & wait time
rtc_init_config_t rtc_init_cfg = RTC_INIT_CONFIG_DEFAULT();
REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_WIFI_POWERUP_TIMER, rtc_init_cfg.wifi_powerup_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_WIFI_WAIT_TIMER, rtc_init_cfg.wifi_wait_cycles);
// set rtc peri timer
//REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_POWERUP_TIMER, rtc_init_cfg.rtc_powerup_cycles);
//REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_WAIT_TIMER, rtc_init_cfg.rtc_wait_cycles);
// set digital wrap timer
REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_BT_POWERUP_TIMER, rtc_init_cfg.bt_powerup_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_BT_WAIT_TIMER, rtc_init_cfg.bt_wait_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_CPU_TOP_POWERUP_TIMER, rtc_init_cfg.cpu_top_powerup_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_CPU_TOP_WAIT_TIMER, rtc_init_cfg.cpu_top_wait_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_DG_WRAP_POWERUP_TIMER, rtc_init_cfg.dg_wrap_powerup_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_DG_WRAP_WAIT_TIMER, rtc_init_cfg.dg_wrap_wait_cycles);
// set rtc memory timer
//REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_RTCMEM_POWERUP_TIMER, rtc_init_cfg.rtc_mem_powerup_cycles);
//REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_RTCMEM_WAIT_TIMER, rtc_init_cfg.rtc_mem_wait_cycles);
//SET_PERI_REG_MASK(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_INC_HEARTBEAT_PERIOD);
REG_SET_FIELD(RTC_CNTL_TIMER6_REG, RTC_CNTL_DG_PERI_POWERUP_TIMER, rtc_init_cfg.dg_peri_powerup_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER6_REG, RTC_CNTL_DG_PERI_WAIT_TIMER, rtc_init_cfg.dg_peri_wait_cycles);
/* Reset RTC bias to default value (needed if waking up from deep sleep) */
//REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_1V10);
//REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_SLP, RTC_CNTL_DBIAS_1V10);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, RTC_CNTL_DBIAS_1V10);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, RTC_CNTL_DBIAS_1V10);
if (cfg.clkctl_init) {
//clear CMMU clock force on
CLEAR_PERI_REG_MASK(EXTMEM_CACHE_MMU_POWER_CTRL_REG, EXTMEM_CACHE_MMU_MEM_FORCE_ON);
//clear rom clock force on
//REG_SET_FIELD(SYSTEM_ROM_CTRL_0_REG, SYSTEM_ROM_IRAM0_CLKGATE_FORCE_ON, 0);
//clear sram clock force on
//REG_SET_FIELD(SYSTEM_SRAM_CTRL_0_REG, SYSTEM_SRAM_CLKGATE_FORCE_ON, 0);
//clear tag clock force on
CLEAR_PERI_REG_MASK(EXTMEM_ICACHE_TAG_POWER_CTRL_REG, EXTMEM_ICACHE_TAG_MEM_FORCE_ON);
//clear register clock force on
@ -84,10 +74,13 @@ void rtc_init(rtc_config_t cfg)
} else {
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU);
}
// CLEAR APLL close
// force pd APLL
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU);
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
//open sar_i2c protect function to avoid sar_i2c reset when rtc_ldo is low.
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_I2C_RESET_POR_FORCE_PD);
//cancel bbpll force pu if setting no force power up
if (!cfg.bbpll_fpu) {
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_FORCE_PU);
@ -98,44 +91,39 @@ void rtc_init(rtc_config_t cfg)
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_I2C_FORCE_PU);
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
}
//cancel RTC REG force PU
//CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PU);
//combine two rtc memory options
//CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_PU);
//CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_NOISO);
if (cfg.rtc_dboost_fpd) {
SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PD);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PD);
}
//cancel sar i2c pd force
//CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD);
//cancel digital pu force
//CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_PU);
//cannel i2c_reset_protect pd force
//clear i2c_reset_protect pd force, need tested in low temperature.
//CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,RTC_CNTL_I2C_RESET_POR_FORCE_PD);
/* If this mask is enabled, all soc memories cannot enter power down mode */
/* We should control soc memory power down mode from RTC, so we will not touch this register any more */
//CLEAR_PERI_REG_MASK(SYSTEM_MEM_PD_MASK_REG, SYSTEM_LSLP_MEM_PD_MASK);
CLEAR_PERI_REG_MASK(SYSTEM_MEM_PD_MASK_REG, SYSTEM_LSLP_MEM_PD_MASK);
/* If this pd_cfg is set to 1, all memory won't enter low power mode during light sleep */
/* If this pd_cfg is set to 0, all memory will enter low power mode during light sleep */
rtc_sleep_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(0);
rtc_sleep_pd(pd_cfg);
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(0);
rtc_sleep_pu(pu_cfg);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU);
// ROM_RAM power domain is removed
// CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_ROM_RAM_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_WRAP_FORCE_NOISO);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO);
// CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CPU_ROM_RAM_FORCE_NOISO);
//CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FORCE_NOISO);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_NOISO);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CPU_TOP_FORCE_NOISO);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PERI_FORCE_NOISO);
//cancel digital PADS force no iso
if (cfg.cpu_waiti_clk_gate) {
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON);
@ -146,9 +134,59 @@ void rtc_init(rtc_config_t cfg)
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
}
if (cfg.cali_ocode) {
/*
Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration(must close PLL).
Method:
1. read current cpu config, save in old_config;
2. switch cpu to xtal because PLL will be closed when o-code calibration;
3. begin o-code calibration;
4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
5. set cpu to old-config.
*/
rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
if (slow_clk_freq == (rtc_slow_freq_x32k)) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_freq == rtc_slow_freq_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
rtc_vddsdio_config_t rtc_vddsdio_get_config()
uint64_t max_delay_time_us = 10000;
uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
uint64_t cycle0 = rtc_time_get();
uint64_t timeout_cycle = cycle0 + max_delay_cycle;
uint64_t cycle1 = 0;
rtc_cpu_freq_config_t old_config;
rtc_clk_cpu_freq_get_config(&old_config);
rtc_clk_cpu_freq_set_xtal();
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0);
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1);
bool odone_flag = 0;
bool bg_odone_flag = 0;
while (1) {
odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG);
bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
cycle1 = rtc_time_get();
if (odone_flag && bg_odone_flag) {
break;
}
if (cycle1 >= timeout_cycle) {
SOC_LOGW(TAG, "o_code calibration fail\n");
break;
}
}
rtc_clk_cpu_freq_set_config(&old_config);
}
}
rtc_vddsdio_config_t rtc_vddsdio_get_config(void)
{
rtc_vddsdio_config_t result;
uint32_t sdio_conf_reg = REG_READ(RTC_CNTL_SDIO_CONF_REG);

View File

@ -19,22 +19,118 @@
#include "soc/apb_ctrl_reg.h"
#include "soc/rtc.h"
#include "soc/i2s_reg.h"
#include "soc/bb_reg.h"
#include "soc/nrx_reg.h"
#include "soc/fe_reg.h"
#include "soc/timer_group_reg.h"
#include "soc/rtc.h"
#include "esp32c3/rom/ets_sys.h"
#include "regi2c_ctrl.h"
/**
* Configure whether certain peripherals are powered down in deep sleep
* @param cfg power down flags as rtc_sleep_pd_config_t structure
* @param cfg power down flags as rtc_sleep_pu_config_t structure
*/
void rtc_sleep_pd(rtc_sleep_pd_config_t cfg)
void rtc_sleep_pu(rtc_sleep_pu_config_t cfg)
{
abort(); // TODO ESP32-C3 IDF-2106
REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_DC_MEM_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_AGC_MEM_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
if (cfg.sram_fpu) {
REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_SRAM_POWER_UP, APB_CTRL_SRAM_POWER_UP);
} else {
REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_SRAM_POWER_UP, 0);
}
if (cfg.rom_ram_fpu) {
REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_ROM_POWER_UP, APB_CTRL_ROM_POWER_UP);
} else {
REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_ROM_POWER_UP, 0);
}
}
void rtc_sleep_init(rtc_sleep_config_t cfg)
{
abort(); // TODO ESP32-C3 IDF-2106
if (cfg.lslp_mem_inf_fpu) {
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
rtc_sleep_pu(pu_cfg);
}
if (cfg.wifi_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
}
if (cfg.bt_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
}
if (cfg.cpu_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
}
if (cfg.dig_peri_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
}
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, RTC_CNTL_BIASSLP_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, RTC_CNTL_BIASSLP_SLEEP_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, RTC_CNTL_PD_CUR_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, RTC_CNTL_PD_CUR_SLEEP_DEFAULT);
if (cfg.deep_slp) {
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
/* It's only a temporary configuration to set dbg 0 to make deepsleep run successfully when in high temperature.
we will restore it to RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT when ECO chip come back.
TODO ESP32-C3 IDF-2568
*/
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, 0);
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
} else {
SET_PERI_REG_MASK(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP_EN);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP, RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT);
SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT);
}
/* enable VDDSDIO control by state machine */
REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, cfg.rtc_dbias_slp);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, cfg.rtc_dbias_wak);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP, cfg.dig_dbias_slp);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, cfg.dig_dbias_wak);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
/* gating XTAL clock */
REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING);
}
void rtc_sleep_low_init(uint32_t slowclk_period)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
void rtc_sleep_set_wakeup_time(uint64_t t)
@ -62,8 +158,8 @@ uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
/* restore config if it is a light sleep */
if (lslp_mem_inf_fpu) {
rtc_sleep_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(0);
rtc_sleep_pd(pd_cfg);
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
rtc_sleep_pu(pu_cfg);
}
return reject;
}

View File

@ -150,6 +150,12 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
uint64_t rtc_time_get(void)
{
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
#if 0 // TODO ESP32-C3 IDF-2569: Re-enable it in the future
while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
esp_rom_delay_us(1); // might take 1 RTC slowclk period, don't flood RTC bus
}
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
#endif
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
return t;

View File

@ -17,7 +17,7 @@
extern void rtc_clk_select_rtc_slow_clk(void);
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
#include "esp32/clk.h"

View File

@ -893,6 +893,7 @@ static uint32_t get_power_down_flags(void)
// RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup.
// If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH.
if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) {
#if SOC_TOUCH_PAD_WAKE_SUPPORTED
uint32_t wakeup_source = RTC_TOUCH_TRIG_EN;
#if SOC_ULP_SUPPORTED
wakeup_source |= RTC_ULP_TRIG_EN;
@ -904,6 +905,13 @@ static uint32_t get_power_down_flags(void)
// prevents ULP timer and touch FSMs from working correctly.
s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF;
}
#else
if (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN) {
s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON;
} else {
s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF;
}
#endif // SOC_TOUCH_PAD_WAKE_SUPPORTED
}
if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] == ESP_PD_OPTION_AUTO) {

View File

@ -210,6 +210,7 @@
#define SOC_TOUCH_PAD_MEASURE_WAIT_MAX (0xFF) /*!<The timer frequency is 8Mhz, the max value is 0xff */
#define SOC_TOUCH_PAD_THRESHOLD_MAX (0) /*!<If set touch threshold max value, The touch sensor can't be in touched status */
#define SOC_TOUCH_PAD_WAKE_SUPPORTED (1) /*!<Supports waking up from touch pad trigger */
/*-------------------------- TWAI CAPS ---------------------------------------*/
#define SOC_TWAI_BRP_MIN 2

View File

@ -1,135 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
/**
* @file i2c_apll.h
* @brief Register definitions for audio PLL (APLL)
*
* This file lists register fields of APLL, located on an internal configuration
* bus. These definitions are used via macros defined in i2c_rtc_clk.h, by
* rtc_clk_apll_enable function in rtc_clk.c.
*/
#define I2C_APLL 0X6D
#define I2C_APLL_HOSTID 3
#define I2C_APLL_IR_CAL_DELAY 0
#define I2C_APLL_IR_CAL_DELAY_MSB 3
#define I2C_APLL_IR_CAL_DELAY_LSB 0
#define I2C_APLL_IR_CAL_RSTB 0
#define I2C_APLL_IR_CAL_RSTB_MSB 4
#define I2C_APLL_IR_CAL_RSTB_LSB 4
#define I2C_APLL_IR_CAL_START 0
#define I2C_APLL_IR_CAL_START_MSB 5
#define I2C_APLL_IR_CAL_START_LSB 5
#define I2C_APLL_IR_CAL_UNSTOP 0
#define I2C_APLL_IR_CAL_UNSTOP_MSB 6
#define I2C_APLL_IR_CAL_UNSTOP_LSB 6
#define I2C_APLL_OC_ENB_FCAL 0
#define I2C_APLL_OC_ENB_FCAL_MSB 7
#define I2C_APLL_OC_ENB_FCAL_LSB 7
#define I2C_APLL_IR_CAL_EXT_CAP 1
#define I2C_APLL_IR_CAL_EXT_CAP_MSB 4
#define I2C_APLL_IR_CAL_EXT_CAP_LSB 0
#define I2C_APLL_IR_CAL_ENX_CAP 1
#define I2C_APLL_IR_CAL_ENX_CAP_MSB 5
#define I2C_APLL_IR_CAL_ENX_CAP_LSB 5
#define I2C_APLL_OC_LBW 1
#define I2C_APLL_OC_LBW_MSB 6
#define I2C_APLL_OC_LBW_LSB 6
#define I2C_APLL_IR_CAL_CK_DIV 2
#define I2C_APLL_IR_CAL_CK_DIV_MSB 3
#define I2C_APLL_IR_CAL_CK_DIV_LSB 0
#define I2C_APLL_OC_DCHGP 2
#define I2C_APLL_OC_DCHGP_MSB 6
#define I2C_APLL_OC_DCHGP_LSB 4
#define I2C_APLL_OC_ENB_VCON 2
#define I2C_APLL_OC_ENB_VCON_MSB 7
#define I2C_APLL_OC_ENB_VCON_LSB 7
#define I2C_APLL_OR_CAL_CAP 3
#define I2C_APLL_OR_CAL_CAP_MSB 4
#define I2C_APLL_OR_CAL_CAP_LSB 0
#define I2C_APLL_OR_CAL_UDF 3
#define I2C_APLL_OR_CAL_UDF_MSB 5
#define I2C_APLL_OR_CAL_UDF_LSB 5
#define I2C_APLL_OR_CAL_OVF 3
#define I2C_APLL_OR_CAL_OVF_MSB 6
#define I2C_APLL_OR_CAL_OVF_LSB 6
#define I2C_APLL_OR_CAL_END 3
#define I2C_APLL_OR_CAL_END_MSB 7
#define I2C_APLL_OR_CAL_END_LSB 7
#define I2C_APLL_OR_OUTPUT_DIV 4
#define I2C_APLL_OR_OUTPUT_DIV_MSB 4
#define I2C_APLL_OR_OUTPUT_DIV_LSB 0
#define I2C_APLL_OC_TSCHGP 4
#define I2C_APLL_OC_TSCHGP_MSB 6
#define I2C_APLL_OC_TSCHGP_LSB 6
#define I2C_APLL_EN_FAST_CAL 4
#define I2C_APLL_EN_FAST_CAL_MSB 7
#define I2C_APLL_EN_FAST_CAL_LSB 7
#define I2C_APLL_OC_DHREF_SEL 5
#define I2C_APLL_OC_DHREF_SEL_MSB 1
#define I2C_APLL_OC_DHREF_SEL_LSB 0
#define I2C_APLL_OC_DLREF_SEL 5
#define I2C_APLL_OC_DLREF_SEL_MSB 3
#define I2C_APLL_OC_DLREF_SEL_LSB 2
#define I2C_APLL_SDM_DITHER 5
#define I2C_APLL_SDM_DITHER_MSB 4
#define I2C_APLL_SDM_DITHER_LSB 4
#define I2C_APLL_SDM_STOP 5
#define I2C_APLL_SDM_STOP_MSB 5
#define I2C_APLL_SDM_STOP_LSB 5
#define I2C_APLL_SDM_RSTB 5
#define I2C_APLL_SDM_RSTB_MSB 6
#define I2C_APLL_SDM_RSTB_LSB 6
#define I2C_APLL_OC_DVDD 6
#define I2C_APLL_OC_DVDD_MSB 4
#define I2C_APLL_OC_DVDD_LSB 0
#define I2C_APLL_DSDM2 7
#define I2C_APLL_DSDM2_MSB 5
#define I2C_APLL_DSDM2_LSB 0
#define I2C_APLL_DSDM1 8
#define I2C_APLL_DSDM1_MSB 7
#define I2C_APLL_DSDM1_LSB 0
#define I2C_APLL_DSDM0 9
#define I2C_APLL_DSDM0_MSB 7
#define I2C_APLL_DSDM0_LSB 0

View File

@ -88,7 +88,9 @@ extern "C" {
*/
#define XTAL_FREQ_EST_CYCLES 10
#define DIG_DBIAS_80M_160M RTC_CNTL_DBIAS_1V10
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V10
#define DIG_DBIAS_160M RTC_CNTL_DBIAS_1V20
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
@ -110,13 +112,14 @@ extern "C" {
/*
set sleep_init default param
*/
#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 5
#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 3
#define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15
#define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0
#define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0
#define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1
#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0
#define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1
#define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254
/**
* @brief Possible main XTAL frequency values.
@ -232,9 +235,9 @@ typedef struct {
} x32k_config_t;
#define X32K_CONFIG_DEFAULT() { \
.dac = 1, \
.dac = 3, \
.dres = 3, \
.dgm = 0, \
.dgm = 3, \
.dbuf = 1, \
}
@ -717,20 +720,15 @@ void rtc_sleep_low_init(uint32_t slowclk_period);
*/
void rtc_sleep_set_wakeup_time(uint64_t t);
#define RTC_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup
#define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup (light sleep only)
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup
#define RTC_SDIO_TRIG_EN BIT(4) //!< SDIO wakeup (light sleep only)
#define RTC_MAC_TRIG_EN BIT(5) //!< MAC wakeup (light sleep only)
#define RTC_UART0_TRIG_EN BIT(6) //!< UART0 wakeup (light sleep only)
#define RTC_UART1_TRIG_EN BIT(7) //!< UART1 wakeup (light sleep only)
#define RTC_BT_TRIG_EN BIT(10) //!< BT wakeup (light sleep only)
#define RTC_COCPU_TRIG_EN BIT(11)
#define RTC_XTAL32K_DEAD_TRIG_EN BIT(12)
#define RTC_COCPU_TRAP_TRIG_EN BIT(13)
#define RTC_USB_TRIG_EN BIT(14)
#define RTC_BROWNOUT_DET_TRIG_EN BIT(16)
/**
* @brief Enter deep or light sleep mode

View File

@ -222,6 +222,7 @@
#define SOC_TOUCH_PAD_THRESHOLD_MAX (0x1FFFFF) /*!<If set touch threshold max value, The touch sensor can't be in touched status */
#define SOC_TOUCH_PAD_MEASURE_WAIT_MAX (0xFF) /*!<The timer frequency is 8Mhz, the max value is 0xff */
#define SOC_TOUCH_PAD_WAKE_SUPPORTED (1) /*!<Supports waking up from touch pad trigger */
/*-------------------------- TWAI CAPS ---------------------------------------*/
#define SOC_TWAI_BRP_MIN 2

View File

@ -26,6 +26,7 @@ extern "C" {
#define SOC_TOUCH_SHIELD_CHANNEL (14)
#define SOC_TOUCH_DENOISE_CHANNEL (0)
#define SOC_TOUCH_PROXIMITY_CHANNEL_NUM (3)
#define SOC_TOUCH_PAD_WAKE_SUPPORTED (1) /*!<Supports waking up from touch pad trigger */
#ifdef __cplusplus
}