diff --git a/components/bootloader_support/src/bootloader_random_esp32c5.c b/components/bootloader_support/src/bootloader_random_esp32c5.c index 15c2314413..908e2f51d7 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c5.c +++ b/components/bootloader_support/src/bootloader_random_esp32c5.c @@ -11,7 +11,10 @@ #include "esp_private/regi2c_ctrl.h" #include "soc/lpperi_reg.h" -#define I2C_SAR_ADC_INIT_CODE_VAL 2150 +#define I2C_SAR_ADC_INIT_CODE_VAL 2150 +#define ADC_RNG_CLKM_DIV_NUM 0 +#define ADC_RNG_CLKM_DIV_B 0 +#define ADC_RNG_CLKM_DIV_A 0 void bootloader_random_enable(void) { @@ -19,7 +22,7 @@ void bootloader_random_enable(void) adc_ll_enable_bus_clock(true); adc_ll_enable_func_clock(true); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL); - adc_ll_digi_controller_clk_div(0, 0, 0); + adc_ll_digi_controller_clk_div(ADC_RNG_CLKM_DIV_NUM, ADC_RNG_CLKM_DIV_B, ADC_RNG_CLKM_DIV_A); // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU #ifndef BOOTLOADER_BUILD diff --git a/components/bootloader_support/src/bootloader_random_esp32c6.c b/components/bootloader_support/src/bootloader_random_esp32c6.c index de45f07c32..edaaef7723 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c6.c +++ b/components/bootloader_support/src/bootloader_random_esp32c6.c @@ -10,7 +10,10 @@ #include "hal/adc_types.h" #include "esp_private/regi2c_ctrl.h" -#define I2C_SAR_ADC_INIT_CODE_VAL 2150 +#define I2C_SAR_ADC_INIT_CODE_VAL 2150 +#define ADC_RNG_CLKM_DIV_NUM 0 +#define ADC_RNG_CLKM_DIV_B 0 +#define ADC_RNG_CLKM_DIV_A 0 void bootloader_random_enable(void) { @@ -18,7 +21,7 @@ void bootloader_random_enable(void) adc_ll_enable_bus_clock(true); adc_ll_enable_func_clock(true); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL); - adc_ll_digi_controller_clk_div(0, 0, 0); + adc_ll_digi_controller_clk_div(ADC_RNG_CLKM_DIV_NUM, ADC_RNG_CLKM_DIV_B, ADC_RNG_CLKM_DIV_A); // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU #ifndef BOOTLOADER_BUILD diff --git a/components/bootloader_support/src/bootloader_random_esp32c61.c b/components/bootloader_support/src/bootloader_random_esp32c61.c index 1f1e2ad9ff..b86fb0a965 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c61.c +++ b/components/bootloader_support/src/bootloader_random_esp32c61.c @@ -10,7 +10,10 @@ #include "hal/adc_types.h" #include "esp_private/regi2c_ctrl.h" -#define I2C_SAR_ADC_INIT_CODE_VAL 2150 +#define I2C_SAR_ADC_INIT_CODE_VAL 2150 +#define ADC_RNG_CLKM_DIV_NUM 0 +#define ADC_RNG_CLKM_DIV_B 0 +#define ADC_RNG_CLKM_DIV_A 0 void bootloader_random_enable(void) { @@ -18,7 +21,7 @@ void bootloader_random_enable(void) adc_ll_enable_bus_clock(true); adc_ll_enable_func_clock(true); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL); - adc_ll_digi_controller_clk_div(0, 0, 0); + adc_ll_digi_controller_clk_div(ADC_RNG_CLKM_DIV_NUM, ADC_RNG_CLKM_DIV_B, ADC_RNG_CLKM_DIV_A); // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU #ifndef BOOTLOADER_BUILD diff --git a/components/bootloader_support/src/bootloader_random_esp32h2.c b/components/bootloader_support/src/bootloader_random_esp32h2.c index 4c4f5155a7..f6576962ce 100644 --- a/components/bootloader_support/src/bootloader_random_esp32h2.c +++ b/components/bootloader_support/src/bootloader_random_esp32h2.c @@ -10,7 +10,10 @@ #include "hal/adc_types.h" #include "esp_private/regi2c_ctrl.h" -#define I2C_SAR_ADC_INIT_CODE_VAL 2150 +#define I2C_SAR_ADC_INIT_CODE_VAL 2150 +#define ADC_RNG_CLKM_DIV_NUM 0 +#define ADC_RNG_CLKM_DIV_B 0 +#define ADC_RNG_CLKM_DIV_A 0 void bootloader_random_enable(void) { @@ -18,7 +21,7 @@ void bootloader_random_enable(void) adc_ll_enable_bus_clock(true); adc_ll_enable_func_clock(true); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL); - adc_ll_digi_controller_clk_div(0, 0, 0); + adc_ll_digi_controller_clk_div(ADC_RNG_CLKM_DIV_NUM, ADC_RNG_CLKM_DIV_B, ADC_RNG_CLKM_DIV_A); // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU #ifndef BOOTLOADER_BUILD diff --git a/components/bootloader_support/src/bootloader_random_esp32p4.c b/components/bootloader_support/src/bootloader_random_esp32p4.c index baa1effa57..c3aa42d120 100644 --- a/components/bootloader_support/src/bootloader_random_esp32p4.c +++ b/components/bootloader_support/src/bootloader_random_esp32p4.c @@ -12,7 +12,10 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/adc_share_hw_ctrl.h" -#define I2C_SAR_ADC_INIT_CODE_VAL 2166 +#define I2C_SAR_ADC_INIT_CODE_VAL 2166 +#define ADC_RNG_CLKM_DIV_NUM 0 +#define ADC_RNG_CLKM_DIV_B 0 +#define ADC_RNG_CLKM_DIV_A 0 void bootloader_random_enable(void) { @@ -20,7 +23,7 @@ void bootloader_random_enable(void) _adc_ll_enable_bus_clock(true); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL); - adc_ll_digi_controller_clk_div(0, 0, 0); + adc_ll_digi_controller_clk_div(ADC_RNG_CLKM_DIV_NUM, ADC_RNG_CLKM_DIV_B, ADC_RNG_CLKM_DIV_A); // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU #ifndef BOOTLOADER_BUILD @@ -69,4 +72,6 @@ void bootloader_random_disable(void) ANALOG_CLOCK_DISABLE(); adc_ll_digi_controller_clk_div(4, 0, 0); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL); + + adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_ULP); } diff --git a/components/bootloader_support/src/bootloader_random_esp32s3.c b/components/bootloader_support/src/bootloader_random_esp32s3.c index 65eafa46ed..b948c4f3bc 100644 --- a/components/bootloader_support/src/bootloader_random_esp32s3.c +++ b/components/bootloader_support/src/bootloader_random_esp32s3.c @@ -1,18 +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/system_reg.h" #include "soc/syscon_reg.h" -#include "soc/apb_saradc_reg.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/sens_reg.h" -#include "hal/regi2c_ctrl.h" -#include "soc/regi2c_saradc.h" +#include "esp_private/regi2c_ctrl.h" +#include "hal/adc_ll.h" +#include "hal/adc_types.h" +#include "hal/regi2c_ctrl_ll.h" + +#define ADC_RNG_CLKM_DIV_NUM 3 +#define ADC_RNG_CLKM_DIV_B 0 +#define ADC_RNG_CLKM_DIV_A 0 void bootloader_random_enable(void) { @@ -22,81 +23,60 @@ void bootloader_random_enable(void) // but enabling the SAR ADC as well adds some insurance.) REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN); - /// Enable SAR ADC to read a disconnected input for additional entropy + _adc_ll_reset_register(); + _adc_ll_enable_bus_clock(true); + _adc_ll_enable_bus_clock(false); - // Reset ADC clock - SET_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN); - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN); + 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); - // Enable clock and select clock source for ADC digital controller - REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_SEL, 2); //APB clock - SET_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED); - SET_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN); +#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(); - // Read freq = apb_clk / (APB_SARADC_CLKM_DIV_NUM + 1) / TIMER_TARGET / 2 - // Internal ADC sample freq = apb_clk / (APB_SARADC_CLKM_DIV_NUM + 1) / (APB_SARADC_SAR_CLK_DIV + 1) - // Read frequency has to be at least 35 times lower than the sampling frequency + adc_ll_regi2c_init(); - REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLKM_DIV_NUM, 3); - REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_DIV, 3); // SAR clock divider has to be at least 2 - REG_SET_FIELD(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_TARGET, 70); + adc_digi_pattern_config_t pattern_config = {}; + pattern_config.unit = ADC_UNIT_1; + pattern_config.atten = ADC_ATTEN_DB_12; + pattern_config.channel = ADC_CHANNEL_10; //Use reserved channel to get internal voltage + adc_ll_digi_set_pattern_table(ADC_UNIT_1, 0, pattern_config); + pattern_config.unit = ADC_UNIT_2; + pattern_config.atten = ADC_ATTEN_DB_12; + pattern_config.channel = ADC_CHANNEL_10; //Use reserved ADC2 and reserved channel to get internal voltage + adc_ll_digi_set_pattern_table(ADC_UNIT_2, 1, pattern_config); + adc_ll_digi_set_pattern_table_len(ADC_UNIT_1, 1); + adc_ll_digi_set_pattern_table_len(ADC_UNIT_2, 1); - CLEAR_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_START_FORCE); - REG_SET_FIELD(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 3); - CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); - REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_WORK_MODE, 1); + adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_BOTH_UNIT); - REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR2_PATT_LEN, 0); - WRITE_PERI_REG(APB_SARADC_SAR2_PATT_TAB1_REG,0xafffff); // Test internal voltage if the channel info is 0xa. - REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR1_PATT_LEN, 0); - WRITE_PERI_REG(APB_SARADC_SAR1_PATT_TAB1_REG,0xafffff); // Test internal voltage if the channel info is 0xa. + adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_DIG); + adc_ll_disable_sleep_controller(); + adc_ll_set_arbiter_work_mode(ADC_ARB_MODE_LOOP); - // Enable adc1 digital controller - SET_PERI_REG_MASK(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); - - // Set SARADC2 arbiter - CLEAR_PERI_REG_MASK(SENS_SAR_MEAS2_MUX_REG, SENS_SAR2_RTC_FORCE); - CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_GRANT_FORCE); - CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_FIX_PRIORITY); - - // Disable ADC filter - REG_SET_FIELD(APB_SARADC_FILTER_CTRL0_REG, APB_SARADC_FILTER_CHANNEL0, 0xD); - REG_SET_FIELD(APB_SARADC_FILTER_CTRL0_REG, APB_SARADC_FILTER_CHANNEL1, 0xD); - - // Start ADC sample - SET_PERI_REG_MASK(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_SEL); - SET_PERI_REG_MASK(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); - - /*Choose the appropriate internal voltage to measure*/ - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 1); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 1); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + adc_ll_digi_set_clk_div(3); + adc_ll_digi_set_trigger_interval(70); + adc_ll_digi_trigger_enable(); } -//TODO: IDF-4714 void bootloader_random_disable(void) { - /* Restore internal I2C bus state */ - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + adc_ll_digi_trigger_disable(); + adc_ll_digi_reset_pattern_table(); - //Power off SAR ADC - REG_SET_FIELD(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 0); - //return to ADC RTC controller - CLEAR_PERI_REG_MASK(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); - //Invalidate ADC digital trigger timer - CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + adc_ll_regi2c_adc_deinit(); +#ifndef BOOTLOADER_BUILD + regi2c_saradc_disable(); +#endif - //Disable ADC digital part - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN); - //Hold reset bit for ADC digital part - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST); + // disable analog i2c master clock + ANALOG_CLOCK_DISABLE(); + adc_ll_digi_controller_clk_div(4, 0, 0); + adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_APB); - /* Note: the 8M CLK entropy source continues running even after this function is called, - but as mentioned above it's better to enable Wi-Fi or BT or call bootloader_random_enable() - in order to get a secondary entropy source. - */ + adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_ULP); } diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index a3b9960800..bb55c09b43 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -253,6 +253,17 @@ static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t } } +/** + * Rest pattern table to default value + */ +static inline void adc_ll_digi_reset_pattern_table(void) +{ + for(int i = 0; i < 4; i++) { + APB_SARADC.sar1_patt_tab[i].sar1_patt_tab = 0xffffff; + APB_SARADC.sar2_patt_tab[i].sar2_patt_tab = 0xffffff; + } +} + /** * Set pattern table for digital controller. * The pattern table that defines the conversion rules for each SAR ADC. Each table has 12 items, in which channel selection, @@ -619,20 +630,20 @@ 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.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 Reset ADC module */ -static inline void adc_ll_reset_register(void) +static inline void _adc_ll_reset_register(void) { SYSTEM.perip_rst_en0.apb_saradc_rst = 1; SYSTEM.perip_rst_en0.apb_saradc_rst = 0; @@ -640,7 +651,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) /** @@ -888,6 +899,66 @@ static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param } } +/** + * 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) +{ + (void)adc_n; + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_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); +} + /** * Output ADC internal reference voltage to channels, only available for ADC2 on ESP32. *