RTC regulator & voltage calibration fixes

This commit is contained in:
Chai Ji’e 2020-04-10 14:25:40 +08:00 committed by Wang Jia Lin
parent 2f0a57dece
commit dac17709ec
6 changed files with 102 additions and 1 deletions

View file

@ -79,6 +79,11 @@ static const char *TAG = "clk";
void esp_clk_init(void)
{
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);
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);

View 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

View file

@ -751,6 +751,7 @@ typedef struct {
uint32_t xtal_fpu : 1;
uint32_t bbpll_fpu : 1;
uint32_t cpu_waiti_clk_gate : 1;
uint32_t cali_ocode : 1; //!< Calibrate Ocode to make bangap voltage more precise.
} rtc_config_t;
/**
@ -768,7 +769,8 @@ typedef struct {
.rtc_dboost_fpd = 1, \
.xtal_fpu = 0, \
.bbpll_fpu = 0, \
.cpu_waiti_clk_gate = 1\
.cpu_waiti_clk_gate = 1, \
.cali_ocode = 0\
}
/**

View file

@ -16,6 +16,7 @@
#include "i2c_apll.h"
#include "i2c_bbpll.h"
#include "i2c_ulp.h"
#ifdef __cplusplus
extern "C" {

View file

@ -22,6 +22,9 @@
#include "soc/spi_mem_reg.h"
#include "soc/extmem_reg.h"
#include "i2c_rtc_clk.h"
#include "soc_log.h"
static const char *TAG = "rtc_init";
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_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)

View file

@ -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_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
} 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);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT);
}