forked from espressif/esp-idf
Merge branch 'feat/c5_ocode_support' into 'master'
ocode: c5 support See merge request espressif/esp-idf!36004
This commit is contained in:
@@ -5,6 +5,7 @@ set(srcs "rtc_clk_init.c"
|
|||||||
"pmu_init.c"
|
"pmu_init.c"
|
||||||
"pmu_sleep.c"
|
"pmu_sleep.c"
|
||||||
"chip_info.c"
|
"chip_info.c"
|
||||||
|
"ocode_init.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT BOOTLOADER_BUILD)
|
if(NOT BOOTLOADER_BUILD)
|
||||||
|
92
components/esp_hw_support/port/esp32c5/ocode_init.c
Normal file
92
components/esp_hw_support/port/esp32c5/ocode_init.c
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
@@ -31,6 +31,7 @@
|
|||||||
#include "esp_private/periph_ctrl.h"
|
#include "esp_private/periph_ctrl.h"
|
||||||
#include "esp_private/esp_clk.h"
|
#include "esp_private/esp_clk.h"
|
||||||
#include "esp_private/esp_pmu.h"
|
#include "esp_private/esp_pmu.h"
|
||||||
|
#include "esp_private/ocode_init.h"
|
||||||
#include "esp_rom_uart.h"
|
#include "esp_rom_uart.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
@@ -50,6 +51,9 @@ void esp_rtc_init(void)
|
|||||||
{
|
{
|
||||||
#if !CONFIG_IDF_ENV_FPGA
|
#if !CONFIG_IDF_ENV_FPGA
|
||||||
pmu_init();
|
pmu_init();
|
||||||
|
if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) {
|
||||||
|
esp_ocode_calib_init();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,9 +45,9 @@
|
|||||||
#include "esp_private/periph_ctrl.h"
|
#include "esp_private/periph_ctrl.h"
|
||||||
#include "esp_private/esp_clk.h"
|
#include "esp_private/esp_clk.h"
|
||||||
#include "esp_private/esp_pmu.h"
|
#include "esp_private/esp_pmu.h"
|
||||||
|
#include "esp_private/ocode_init.h"
|
||||||
#include "esp_rom_uart.h"
|
#include "esp_rom_uart.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "ocode_init.h"
|
|
||||||
|
|
||||||
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
|
/* 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
|
* Larger values increase startup delay. Smaller values may cause false positive
|
||||||
|
@@ -98,6 +98,11 @@ __attribute__((always_inline)) static inline void efuse_ll_set_ecdsa_key_blk(int
|
|||||||
EFUSE.conf.cfg_ecdsa_blk = efuse_blk;
|
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 *************************/
|
/******************* eFuse control functions *************************/
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void)
|
__attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void)
|
||||||
|
55
components/soc/esp32c5/include/soc/regi2c_lp_bias.h
Normal file
55
components/soc/esp32c5/include/soc/regi2c_lp_bias.h
Normal 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
|
Reference in New Issue
Block a user