Merge branch 'bugfix/fix_esp32s2_soc_bug' into 'master'
RTC regulator & voltage calibration fixes See merge request espressif/esp-idf!8137
This commit is contained in:
commit
b3d8b6a250
6 changed files with 102 additions and 1 deletions
|
@ -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);
|
||||
|
|
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 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\
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "i2c_apll.h"
|
||||
#include "i2c_bbpll.h"
|
||||
#include "i2c_ulp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue