From 85144da53ea844f1585aab5375fd066559429774 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Sun, 28 Sep 2025 14:34:30 +0800 Subject: [PATCH] refactor(rng): refactor to use hal/ll apis for C3 --- .../src/bootloader_random_esp32c3.c | 98 ++++++++++--------- components/hal/esp32c3/include/hal/adc_ll.h | 91 ++++++++++++++++- .../include/hal/temperature_sensor_ll.h | 4 +- 3 files changed, 143 insertions(+), 50 deletions(-) diff --git a/components/bootloader_support/src/bootloader_random_esp32c3.c b/components/bootloader_support/src/bootloader_random_esp32c3.c index a6ec0552807..2a70671e33a 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c3.c +++ b/components/bootloader_support/src/bootloader_random_esp32c3.c @@ -1,17 +1,19 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "sdkconfig.h" #include "bootloader_random.h" -#include "esp_log.h" -#include "soc/syscon_reg.h" #include "soc/rtc_cntl_reg.h" -#include "soc/apb_saradc_reg.h" -#include "soc/system_reg.h" #include "esp_private/regi2c_ctrl.h" -#include "soc/regi2c_saradc.h" +#include "hal/adc_ll.h" +#include "hal/temperature_sensor_ll.h" +#include "esp_private/sar_periph_ctrl.h" + +#define ADC_RNG_CLKM_DIV_NUM 15 +#define ADC_RNG_CLKM_DIV_B 0 +#define ADC_RNG_CLKM_DIV_A 0 void bootloader_random_enable(void) { @@ -19,49 +21,57 @@ void bootloader_random_enable(void) REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 0x3); SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M); - // Bridging sar2 internal reference voltage - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); +#ifndef BOOTLOADER_BUILD + sar_periph_ctrl_adc_reset(); +#else + tsens_ll_reg_values_t saved_tsens_regs = {}; + tsens_ll_backup_registers(&saved_tsens_regs); + _adc_ll_reset_register(); + // Restore temperature sensor related register values after ADC reset + _temperature_sensor_ll_reset_module(); + tsens_ll_restore_registers(&saved_tsens_regs); +#endif - // Enable SAR ADC2 internal channel to read adc2 ref voltage for additional entropy - SET_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN_M); - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST_M); - REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_SEL, 0x2); - SET_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); - SET_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED_M); - REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE, 0x3); - REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_DIV, 1); + _adc_ll_enable_bus_clock(true); + adc_ll_enable_func_clock(true); + adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_APB); + adc_ll_digi_controller_clk_div(ADC_RNG_CLKM_DIV_NUM, ADC_RNG_CLKM_DIV_B, ADC_RNG_CLKM_DIV_A); + adc_ll_digi_set_power_manage(ADC_LL_POWER_SW_ON); + adc_ll_digi_set_fsm_time(ADC_LL_FSM_RSTB_WAIT_DEFAULT, ADC_LL_FSM_START_WAIT_DEFAULT, + ADC_LL_FSM_STANDBY_WAIT_DEFAULT); - REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_RSTB_WAIT, 8); - REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_XPD_WAIT, 5); - REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_STANDBY_WAIT, 100); +#ifndef BOOTLOADER_BUILD + regi2c_saradc_enable(); +#else + regi2c_ctrl_ll_i2c_sar_periph_enable(); +#endif + // enable analog i2c master clock for RNG runtime + ANALOG_CLOCK_ENABLE(); + adc_ll_regi2c_init(); - SET_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); - CLEAR_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); - REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_LEN, 0); - REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1, 0x9cffff);// Set adc2 internal channel & atten - REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2, 0xffffff); - // Set ADC sampling frequency - REG_SET_FIELD(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_TARGET, 100); - REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLKM_DIV_NUM, 15); - CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_MEAS_NUM_LIMIT); - SET_PERI_REG_MASK(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); - SET_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_TIMER_EN); + adc_digi_pattern_config_t pattern_config = {}; + pattern_config.unit = ADC_UNIT_2; + pattern_config.atten = ADC_ATTEN_DB_12; + pattern_config.channel = ADC_CHANNEL_1; //Use reserved channel 10 to get internal voltage + adc_ll_digi_set_pattern_table(ADC_UNIT_2, 0, pattern_config); + adc_ll_digi_set_pattern_table_len(ADC_UNIT_2, 1); + + adc_ll_digi_dma_enable(); + + adc_ll_digi_set_clk_div(1); + adc_ll_digi_set_trigger_interval(100); + adc_ll_digi_trigger_enable(); } void bootloader_random_disable(void) { - /* Restore internal I2C bus state */ - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); - - /* Restore SARADC to default mode */ - CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_TIMER_EN); - CLEAR_PERI_REG_MASK(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); - REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1, 0xffffff); - REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2, 0xffffff); - CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); - REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE, 0); - REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 0); + _adc_ll_enable_bus_clock(false); + adc_ll_digi_trigger_disable(); + adc_ll_digi_reset_pattern_table(); + adc_ll_regi2c_adc_deinit(); +#ifndef BOOTLOADER_BUILD + regi2c_saradc_disable(); +#endif + // disable analog i2c master clock + ANALOG_CLOCK_DISABLE(); } diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index 063689f5e0d..0aa3c579184 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -240,6 +240,15 @@ static inline void adc_ll_digi_clear_pattern_table(adc_unit_t adc_n) APB_SARADC.ctrl.sar_patt_p_clear = 0; } +/** + * Reset pattern table to default value + */ +static inline void adc_ll_digi_reset_pattern_table(void) +{ + APB_SARADC.sar_patt_tab[0].sar_patt_tab1 = 0xffffff; + APB_SARADC.sar_patt_tab[1].sar_patt_tab1 = 0xffffff; +} + /** * Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize. * @@ -570,20 +579,30 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) * @brief Enable the ADC clock * @param enable true to enable, false to disable */ -static inline void adc_ll_enable_bus_clock(bool enable) +static inline void _adc_ll_enable_bus_clock(bool enable) { SYSTEM.perip_clk_en0.reg_apb_saradc_clk_en = enable; } // SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way #define adc_ll_enable_bus_clock(...) do { \ (void)__DECLARE_RCC_ATOMIC_ENV; \ - adc_ll_enable_bus_clock(__VA_ARGS__); \ + _adc_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the ADC function clock + * @param enable true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void adc_ll_enable_func_clock(bool enable) +{ + APB_SARADC.apb_adc_clkm_conf.clk_en = enable; +} + /** * @brief Reset ADC module */ -static inline void adc_ll_reset_register(void) +static inline void _adc_ll_reset_register(void) { SYSTEM.perip_rst_en0.reg_apb_saradc_rst = 1; SYSTEM.perip_rst_en0.reg_apb_saradc_rst = 0; @@ -591,7 +610,7 @@ static inline void adc_ll_reset_register(void) // SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way #define adc_ll_reset_register(...) do { \ (void)__DECLARE_RCC_ATOMIC_ENV; \ - adc_ll_reset_register(__VA_ARGS__); \ + _adc_ll_reset_register(__VA_ARGS__); \ } while(0) /** @@ -766,6 +785,70 @@ static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, lsb); } } + +/** + * Set the SAR DTEST param + * + * @param param DTEST value + */ +__attribute__((always_inline)) +static inline void adc_ll_set_dtest_param(uint32_t param) +{ + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, param); +} + +/** + * Set the SAR ENT param + * + * @param param ENT value + */ +__attribute__((always_inline)) +static inline void adc_ll_set_ent_param(uint32_t param) +{ + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, param); +} + +/** + * Enable/disable the calibration voltage reference for ADC unit. + * + * @param adc_n ADC index number. + * @param en true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void adc_ll_enable_calibration_ref(adc_unit_t adc_n, bool en) +{ + if (adc_n == ADC_UNIT_1) { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, en); + } else { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, en); + } +} + +/** + * Init regi2c SARADC registers + */ +__attribute__((always_inline)) +static inline void adc_ll_regi2c_init(void) +{ + adc_ll_set_dtest_param(0); + adc_ll_set_ent_param(1); + // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal voltage as sampling source + adc_ll_enable_calibration_ref(ADC_UNIT_1, true); + adc_ll_enable_calibration_ref(ADC_UNIT_2, true); +} + +/** + * Deinit regi2c SARADC registers + */ +__attribute__((always_inline)) +static inline void adc_ll_regi2c_adc_deinit(void) +{ + adc_ll_set_dtest_param(0); + adc_ll_set_ent_param(0); + adc_ll_enable_calibration_ref(ADC_UNIT_1, false); + adc_ll_enable_calibration_ref(ADC_UNIT_2, false); +} + /* Temp code end. */ /** diff --git a/components/hal/esp32c3/include/hal/temperature_sensor_ll.h b/components/hal/esp32c3/include/hal/temperature_sensor_ll.h index 15acca6ed70..081f89e2181 100644 --- a/components/hal/esp32c3/include/hal/temperature_sensor_ll.h +++ b/components/hal/esp32c3/include/hal/temperature_sensor_ll.h @@ -66,7 +66,7 @@ static inline void temperature_sensor_ll_bus_clk_enable(bool enable) /** * @brief Reset the Temperature sensor module */ -static inline void temperature_sensor_ll_reset_module(void) +static inline void _temperature_sensor_ll_reset_module(void) { SYSTEM.perip_rst_en1.reg_tsens_rst = 1; SYSTEM.perip_rst_en1.reg_tsens_rst = 0; @@ -74,7 +74,7 @@ static inline void temperature_sensor_ll_reset_module(void) /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define temperature_sensor_ll_reset_module(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; temperature_sensor_ll_reset_module(__VA_ARGS__);} while(0) +#define temperature_sensor_ll_reset_module(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _temperature_sensor_ll_reset_module(__VA_ARGS__);} while(0) /** * @brief Select the clock source for temperature sensor. On ESP32-C3, temperautre sensor