Merge branch 'feat/c5_ocode_support' into 'master'

ocode: c5 support

See merge request espressif/esp-idf!36004
This commit is contained in:
Armando (Dou Yiwen) 2025-01-02 12:29:53 +08:00
commit fa66ebec27
7 changed files with 158 additions and 1 deletions

View File

@ -5,6 +5,7 @@ set(srcs "rtc_clk_init.c"
"pmu_init.c"
"pmu_sleep.c"
"chip_info.c"
"ocode_init.c"
)
if(NOT BOOTLOADER_BUILD)

View File

@ -0,0 +1,92 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "soc/rtc.h"
#include "esp_attr.h"
#include "soc/regi2c_dig_reg.h"
#include "soc/regi2c_lp_bias.h"
#include "hal/efuse_hal.h"
#include "hal/efuse_ll.h"
#include "hal/clk_tree_ll.h"
#include "esp_private/regi2c_ctrl.h"
#include "esp_hw_log.h"
static const char *TAG = "ocode_init";
static void set_ocode_by_efuse(int ocode_scheme_ver)
{
assert(ocode_scheme_ver == 1);
unsigned int ocode = efuse_ll_get_ocode();
//set ext_ocode
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_EXT_CODE, ocode);
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1);
}
static void IRAM_ATTR calibrate_ocode(void)
{
/*
Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off 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.
*/
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_32K_OSC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
cal_clk = RTC_CAL_32K_XTAL;
}
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();
ANALOG_CLOCK_ENABLE();
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) {
ESP_HW_LOGW(TAG, "o_code calibration fail\n");
break;
}
}
ANALOG_CLOCK_DISABLE();
rtc_clk_cpu_freq_set_config(&old_config);
}
void esp_ocode_calib_init(void)
{
uint32_t blk_ver = efuse_hal_blk_version();
if ((blk_ver >= 1) && (blk_ver < 100)) {
set_ocode_by_efuse(1);
ESP_HW_LOGD(TAG, "efuse ocode");
} else {
calibrate_ocode();
ESP_HW_LOGD(TAG, "calib ocode");
}
}

View File

@ -31,6 +31,7 @@
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk.h"
#include "esp_private/esp_pmu.h"
#include "esp_private/ocode_init.h"
#include "esp_rom_uart.h"
#include "esp_rom_sys.h"
@ -50,6 +51,9 @@ void esp_rtc_init(void)
{
#if !CONFIG_IDF_ENV_FPGA
pmu_init();
if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) {
esp_ocode_calib_init();
}
#endif
}

View File

@ -45,9 +45,9 @@
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk.h"
#include "esp_private/esp_pmu.h"
#include "esp_private/ocode_init.h"
#include "esp_rom_uart.h"
#include "esp_rom_sys.h"
#include "ocode_init.h"
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
* Larger values increase startup delay. Smaller values may cause false positive

View File

@ -98,6 +98,11 @@ __attribute__((always_inline)) static inline void efuse_ll_set_ecdsa_key_blk(int
EFUSE.conf.cfg_ecdsa_blk = efuse_blk;
}
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_ocode(void)
{
return EFUSE.rd_sys_part1_data4.ocode;
}
/******************* eFuse control functions *************************/
__attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void)

View File

@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_lp_bias.h
* @brief Register definitions for analog to calibrate o_code for getting a more precise voltage.
*
* This file lists register fields of low power dbais, located on an internal configuration
* bus. These definitions are used via macros defined in regi2c_ctrl.h, by
* rtc_init function in rtc_init.c.
*/
#define I2C_ULP 0x61
#define I2C_ULP_HOSTID 0
#define I2C_ULP_IR_RESETB 0
#define I2C_ULP_IR_RESETB_MSB 0
#define I2C_ULP_IR_RESETB_LSB 0
#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_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_DISABLE_WATCHDOG_CK 0
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_MSB 6
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_LSB 6
#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
#define I2C_ULP_OCODE 4
#define I2C_ULP_OCODE_MSB 7
#define I2C_ULP_OCODE_LSB 0
#define I2C_ULP_IR_FORCE_CODE 5
#define I2C_ULP_IR_FORCE_CODE_MSB 6
#define I2C_ULP_IR_FORCE_CODE_LSB 6
#define I2C_ULP_EXT_CODE 6
#define I2C_ULP_EXT_CODE_MSB 7
#define I2C_ULP_EXT_CODE_LSB 0