forked from espressif/esp-idf
RTC regulator & voltage calibration fixes
This commit is contained in:
@@ -79,6 +79,11 @@ static const char *TAG = "clk";
|
|||||||
void esp_clk_init(void)
|
void esp_clk_init(void)
|
||||||
{
|
{
|
||||||
rtc_config_t cfg = RTC_CONFIG_DEFAULT();
|
rtc_config_t cfg = RTC_CONFIG_DEFAULT();
|
||||||
|
RESET_REASON rst_reas;
|
||||||
|
rst_reas = rtc_get_reset_reason(0);
|
||||||
|
if (rst_reas == POWERON_RESET) {
|
||||||
|
cfg.cali_ocode = 1;
|
||||||
|
}
|
||||||
rtc_init(cfg);
|
rtc_init(cfg);
|
||||||
|
|
||||||
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
|
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
|
||||||
|
39
components/soc/soc/esp32s2/i2c_ulp.h
Normal file
39
components/soc/soc/esp32s2/i2c_ulp.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2015-2017 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_ulp.h
|
||||||
|
* @brief Register definitions for analog to calibrate o_code for getting a more precise voltage.
|
||||||
|
*
|
||||||
|
* This file lists register fields of ULP, located on an internal configuration
|
||||||
|
* bus. These definitions are used via macros defined in i2c_rtc_clk.h, by
|
||||||
|
* rtc_init function in rtc_init.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define I2C_ULP 0x61
|
||||||
|
#define I2C_ULP_HOSTID 1
|
||||||
|
|
||||||
|
#define I2C_ULP_IR_RESETB 0
|
||||||
|
#define I2C_ULP_IR_RESETB_MSB 0
|
||||||
|
#define I2C_ULP_IR_RESETB_LSB 0
|
||||||
|
|
||||||
|
#define I2C_ULP_O_DONE_FLAG 3
|
||||||
|
#define I2C_ULP_O_DONE_FLAG_MSB 0
|
||||||
|
#define I2C_ULP_O_DONE_FLAG_LSB 0
|
||||||
|
|
||||||
|
#define I2C_ULP_BG_O_DONE_FLAG 3
|
||||||
|
#define I2C_ULP_BG_O_DONE_FLAG_MSB 3
|
||||||
|
#define I2C_ULP_BG_O_DONE_FLAG_LSB 3
|
@@ -751,6 +751,7 @@ typedef struct {
|
|||||||
uint32_t xtal_fpu : 1;
|
uint32_t xtal_fpu : 1;
|
||||||
uint32_t bbpll_fpu : 1;
|
uint32_t bbpll_fpu : 1;
|
||||||
uint32_t cpu_waiti_clk_gate : 1;
|
uint32_t cpu_waiti_clk_gate : 1;
|
||||||
|
uint32_t cali_ocode : 1; //!< Calibrate Ocode to make bangap voltage more precise.
|
||||||
} rtc_config_t;
|
} rtc_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -768,7 +769,8 @@ typedef struct {
|
|||||||
.rtc_dboost_fpd = 1, \
|
.rtc_dboost_fpd = 1, \
|
||||||
.xtal_fpu = 0, \
|
.xtal_fpu = 0, \
|
||||||
.bbpll_fpu = 0, \
|
.bbpll_fpu = 0, \
|
||||||
.cpu_waiti_clk_gate = 1\
|
.cpu_waiti_clk_gate = 1, \
|
||||||
|
.cali_ocode = 0\
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "i2c_apll.h"
|
#include "i2c_apll.h"
|
||||||
#include "i2c_bbpll.h"
|
#include "i2c_bbpll.h"
|
||||||
|
#include "i2c_ulp.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
#include "soc/spi_mem_reg.h"
|
#include "soc/spi_mem_reg.h"
|
||||||
#include "soc/extmem_reg.h"
|
#include "soc/extmem_reg.h"
|
||||||
#include "i2c_rtc_clk.h"
|
#include "i2c_rtc_clk.h"
|
||||||
|
#include "soc_log.h"
|
||||||
|
|
||||||
|
static const char *TAG = "rtc_init";
|
||||||
|
|
||||||
void rtc_init(rtc_config_t cfg)
|
void rtc_init(rtc_config_t cfg)
|
||||||
{
|
{
|
||||||
@@ -143,6 +146,56 @@ 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_UNHOLD);
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
|
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
|
||||||
}
|
}
|
||||||
|
if (cfg.cali_ocode)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Bangap 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
I2C_WRITEREG_MASK_RTC(I2C_ULP, I2C_ULP_IR_RESETB, 0);
|
||||||
|
I2C_WRITEREG_MASK_RTC(I2C_ULP, I2C_ULP_IR_RESETB, 1);
|
||||||
|
bool odone_flag = 0;
|
||||||
|
bool bg_odone_flag = 0;
|
||||||
|
while(1) {
|
||||||
|
odone_flag = I2C_READREG_MASK_RTC(I2C_ULP, I2C_ULP_O_DONE_FLAG);
|
||||||
|
bg_odone_flag = I2C_READREG_MASK_RTC(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");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rtc_clk_cpu_freq_set_config(&old_config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_vddsdio_config_t rtc_vddsdio_get_config(void)
|
rtc_vddsdio_config_t rtc_vddsdio_get_config(void)
|
||||||
|
@@ -107,6 +107,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
|
|||||||
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
|
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
|
||||||
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
|
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
|
||||||
} else {
|
} else {
|
||||||
|
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);
|
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);
|
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user