From d598c9db7c5fb539e902946d3bc7aeab6df3d2a6 Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 17 Feb 2025 15:38:23 +0800 Subject: [PATCH] refactor(rng): refactor to use hal/ll apis for c61 --- .../src/bootloader_random_esp32c61.c | 117 +++++------------- .../src/bootloader_random_esp32h2.c | 9 +- components/hal/esp32c61/include/hal/adc_ll.h | 102 ++++++++++++++- .../hal/esp32c61/include/hal/regi2c_ctrl_ll.h | 35 +++++- components/hal/esp32h2/include/hal/adc_ll.h | 22 ++++ .../soc/esp32c61/include/soc/regi2c_saradc.h | 44 +++---- 6 files changed, 215 insertions(+), 114 deletions(-) diff --git a/components/bootloader_support/src/bootloader_random_esp32c61.c b/components/bootloader_support/src/bootloader_random_esp32c61.c index a4b1da5070..94a63e294a 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c61.c +++ b/components/bootloader_support/src/bootloader_random_esp32c61.c @@ -1,107 +1,58 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "sdkconfig.h" #include "bootloader_random.h" -#include "soc/soc.h" -#include "soc/pcr_reg.h" -#include "soc/apb_saradc_reg.h" -#include "soc/pmu_reg.h" -#include "hal/regi2c_ctrl.h" -#include "soc/regi2c_saradc.h" -#include "esp_log.h" - -static const uint32_t SAR2_CHANNEL = 9; -static const uint32_t SAR1_CHANNEL = 7; -static const uint32_t PATTERN_BIT_WIDTH = 6; -static const uint32_t SAR1_ATTEN = 3; -static const uint32_t SAR2_ATTEN = 3; +#include "hal/regi2c_ctrl_ll.h" +#include "hal/adc_ll.h" +#include "hal/adc_types.h" void bootloader_random_enable(void) { - // pull SAR ADC out of reset - REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); - REG_CLR_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); - - // enable SAR ADC APB clock - REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_REG_CLK_EN); - - // pull APB register out of reset - REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_REG_RST_EN); - REG_CLR_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_REG_RST_EN); - - // enable ADC_CTRL_CLK (SAR ADC function clock) - REG_SET_BIT(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_EN); - - // select XTAL clock (40 MHz) source for ADC_CTRL_CLK - REG_SET_FIELD(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_SEL, 0); - - // set the clock divider for ADC_CTRL_CLK to default value (in case it has been changed) - REG_SET_FIELD(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_DIV_NUM, 0); + adc_ll_reset_register(); + 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); // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); - + regi2c_ctrl_ll_i2c_reset_set(); + regi2c_ctrl_ll_i2c_periph_enable(); // enable analog i2c master clock for RNG runtime ANALOG_CLOCK_ENABLE(); - // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal voltage as sampling source - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR , 0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR , 1); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 1); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); + adc_ll_regi2c_adc_prepare(); + adc_ll_set_calibration_param(ADC_UNIT_1, 0x866); + adc_ll_set_calibration_param(ADC_UNIT_2, 0x866); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, 0x08); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, 0x66); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0x08); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0x66); + 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_7; + 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_1; + adc_ll_digi_set_pattern_table(ADC_UNIT_2, 1, pattern_config); + adc_ll_digi_set_pattern_table_len(ADC_UNIT_1, 2); - // create patterns and set them in pattern table - uint32_t pattern_one = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation - uint32_t pattern_two = (SAR1_CHANNEL << 2) | SAR1_ATTEN; // we want channel 7 with max attenuation - uint32_t pattern_table = 0 | (pattern_two << 3 * PATTERN_BIT_WIDTH) | pattern_one << 2 * PATTERN_BIT_WIDTH; - REG_WRITE(SARADC_SAR_PATT_TAB1_REG, pattern_table); - - // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0) - REG_SET_FIELD(SARADC_CTRL_REG, SARADC_SAR_PATT_LEN, 1); - - // Same as in C3 - REG_SET_FIELD(SARADC_CTRL_REG, SARADC_SAR_CLK_DIV, 15); - - // set timer expiry (timer is ADC_CTRL_CLK) - REG_SET_FIELD(SARADC_CTRL2_REG, SARADC_TIMER_TARGET, 200); - - // enable timer - REG_SET_BIT(SARADC_CTRL2_REG, SARADC_TIMER_EN); + adc_ll_digi_set_clk_div(15); + adc_ll_digi_set_trigger_interval(200); + adc_ll_digi_trigger_enable(); } void bootloader_random_disable(void) { - // disable timer - REG_CLR_BIT(SARADC_CTRL2_REG, SARADC_TIMER_EN); - - // Write reset value of this register - REG_WRITE(SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); - - // Revert ADC I2C configuration and initial voltage source setting - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, 0x60); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, 0x0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0x60); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0x0); - 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_SARADC1_ENCAL_REF_ADDR, 0); - REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); + adc_ll_digi_trigger_disable(); + adc_ll_digi_reset_pattern_table(); + adc_ll_set_calibration_param(ADC_UNIT_1, 0x0); + adc_ll_set_calibration_param(ADC_UNIT_2, 0x0); + adc_ll_regi2c_adc_reset(); // disable analog i2c master clock ANALOG_CLOCK_DISABLE(); - - // disable ADC_CTRL_CLK (SAR ADC function clock) - REG_WRITE(PCR_SARADC_CLKM_CONF_REG, 0x00404000); - - // Set PCR_SARADC_CONF_REG to initial state - REG_WRITE(PCR_SARADC_CONF_REG, 0x5); + adc_ll_digi_controller_clk_div(4, 0, 0); + adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL); } diff --git a/components/bootloader_support/src/bootloader_random_esp32h2.c b/components/bootloader_support/src/bootloader_random_esp32h2.c index a5b11b0340..4e2a2db6a4 100644 --- a/components/bootloader_support/src/bootloader_random_esp32h2.c +++ b/components/bootloader_support/src/bootloader_random_esp32h2.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "sdkconfig.h" -#include "esp_log.h" #include "bootloader_random.h" #include "hal/regi2c_ctrl_ll.h" #include "hal/adc_ll.h" @@ -23,9 +22,7 @@ void bootloader_random_enable(void) // enable analog i2c master clock for RNG runtime ANALOG_CLOCK_ENABLE(); - adc_ll_set_dtest_param(0); - adc_ll_set_ent_param(1); - adc_ll_enable_tout_bus(ADC_UNIT_1, true); + adc_ll_regi2c_adc_prepare(void); adc_ll_set_calibration_param(ADC_UNIT_1, 0x866); adc_ll_set_calibration_param(ADC_UNIT_2, 0x866); @@ -49,9 +46,7 @@ void bootloader_random_disable(void) adc_ll_digi_reset_pattern_table(); adc_ll_set_calibration_param(ADC_UNIT_1, 0x0); adc_ll_set_calibration_param(ADC_UNIT_2, 0x0); - adc_ll_set_dtest_param(0); - adc_ll_set_ent_param(0); - adc_ll_enable_tout_bus(ADC_UNIT_1, false); + adc_ll_regi2c_adc_reset(); // disable analog i2c master clock ANALOG_CLOCK_DISABLE(); diff --git a/components/hal/esp32c61/include/hal/adc_ll.h b/components/hal/esp32c61/include/hal/adc_ll.h index f1b266d4a1..ba99f25813 100644 --- a/components/hal/esp32c61/include/hal/adc_ll.h +++ b/components/hal/esp32c61/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -224,6 +224,15 @@ static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t patt } } +/** + * Rest pattern table to default value + */ +static inline void adc_ll_digi_reset_pattern_table(void) +{ + ADC.saradc_sar_patt_tab1.saradc_sar_patt_tab1 = 0xffffff; + ADC.saradc_sar_patt_tab2.saradc_sar_patt_tab2 = 0xffffff; +} + /** * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. * @@ -616,6 +625,97 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c //Not used on ESP32C61 } +/*--------------------------------------------------------------- + Calibration +---------------------------------------------------------------*/ +/** + * Set the calibration result to ADC. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param param calibration param + */ +__attribute__((always_inline)) +static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param) +{ + uint8_t msb = param >> 8; + uint8_t lsb = param & 0xFF; + + if (adc_n == ADC_UNIT_1) { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb); + } else { + //C61 doesn't support ADC2, here is for backward compatibility for RNG + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, msb); + 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, I2C_SARADC_DTEST , 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, I2C_SARADC_ENT_SAR, param); +} + +/** + * Enable the SAR TOUT bus + * + * @param adc_n ADC index number. + * @param en true for enable + */ +__attribute__((always_inline)) +static inline void adc_ll_enable_encal_ref(adc_unit_t adc_n, bool en) +{ + //C61 doesn't support ADC2, here is for backward compatibility for RNG + if (adc_n == ADC_UNIT_1) { + REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC1_ENCAL_REF, en); + } else { + REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC2_ENCAL_REF, en); + } +} + +__attribute__((always_inline)) +/** + * Prepare regi2c SARADC registers + */ +static inline void adc_ll_regi2c_adc_prepare(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_encal_ref(ADC_UNIT_1, true); + adc_ll_enable_encal_ref(ADC_UNIT_2, true); +} + +/** + * Reset regi2c SARADC registers + */ +__attribute__((always_inline)) +static inline void adc_ll_regi2c_adc_reset(void) +{ + adc_ll_set_dtest_param(0); + adc_ll_set_ent_param(0); + adc_ll_enable_encal_ref(ADC_UNIT_1, false); + adc_ll_enable_encal_ref(ADC_UNIT_2, false); +} + /*--------------------------------------------------------------- Oneshot Read ---------------------------------------------------------------*/ diff --git a/components/hal/esp32c61/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32c61/include/hal/regi2c_ctrl_ll.h index 1c17305864..772854d00e 100644 --- a/components/hal/esp32c61/include/hal/regi2c_ctrl_ll.h +++ b/components/hal/esp32c61/include/hal/regi2c_ctrl_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ #include #include "soc/soc.h" #include "soc/regi2c_defs.h" +#include "soc/pmu_reg.h" #include "modem/modem_lpcon_struct.h" #include "modem/modem_syscon_struct.h" #include "soc/i2c_ana_mst_reg.h" @@ -111,6 +112,38 @@ static inline void regi2c_ctrl_ll_i2c_saradc_disable(void) // TODO: IDF-9322 } +/** + * @brief Enable regi2c controlled periph registers + */ +static inline void regi2c_ctrl_ll_i2c_periph_enable(void) +{ + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); +} + +/** + * @brief Disable regi2c controlled periph registers + */ +static inline void regi2c_ctrl_ll_i2c_periph_disable(void) +{ + CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); +} + +/** + * @brief Set regi2c reset + */ +static inline void regi2c_ctrl_ll_i2c_reset_set(void) +{ + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); +} + +/** + * @brief Clear regi2c reset + */ +static inline void regi2c_ctrl_ll_i2c_reset_clear(void) +{ + CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index 3ebbf04909..a55c037d71 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -723,6 +723,28 @@ static inline void adc_ll_enable_tout_bus(adc_unit_t adc_n, bool en) REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_EN_TOUT_SAR1_BUS, en); } +/** + * Prepare regi2c SARADC registers + */ +__attribute__((always_inline)) +static inline void adc_ll_regi2c_adc_prepare(void) +{ + adc_ll_set_dtest_param(0); + adc_ll_set_ent_param(1); + adc_ll_enable_tout_bus(ADC_UNIT_1, true); +} + +/** + * Reset regi2c SARADC registers + */ +__attribute__((always_inline)) +static inline void adc_ll_regi2c_adc_reset(void) +{ + adc_ll_set_dtest_param(0); + adc_ll_set_ent_param(0); + adc_ll_enable_tout_bus(ADC_UNIT_1, false); +} + /*--------------------------------------------------------------- Oneshot Read ---------------------------------------------------------------*/ diff --git a/components/soc/esp32c61/include/soc/regi2c_saradc.h b/components/soc/esp32c61/include/soc/regi2c_saradc.h index a49ca32d8f..12f53d4a0d 100644 --- a/components/soc/esp32c61/include/soc/regi2c_saradc.h +++ b/components/soc/esp32c61/include/soc/regi2c_saradc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -50,33 +50,33 @@ #define I2C_SARADC_TSENS_DAC_MSB 3 #define I2C_SARADC_TSENS_DAC_LSB 0 -#define ADC_SARADC_DTEST_RTC_ADDR 0x7 -#define ADC_SARADC_DTEST_RTC_ADDR_MSB 1 -#define ADC_SARADC_DTEST_RTC_ADDR_LSB 0 +#define I2C_SARADC_DTEST 0x7 +#define I2C_SARADC_DTEST_MSB 1 +#define I2C_SARADC_DTEST_LSB 0 -#define ADC_SARADC_ENT_TSENS_ADDR 0x7 -#define ADC_SARADC_ENT_TSENS_ADDR_MSB 2 -#define ADC_SARADC_ENT_TSENS_ADDR_LSB 2 +#define I2C_SARADC_ENT_TSENS 0x7 +#define I2C_SARADC_ENT_TSENS_MSB 2 +#define I2C_SARADC_ENT_TSENS_LSB 2 -#define ADC_SARADC_ENT_RTC_ADDR 0x7 -#define ADC_SARADC_ENT_RTC_ADDR_MSB 3 -#define ADC_SARADC_ENT_RTC_ADDR_LSB 3 +#define I2C_SARADC_ENT_SAR 0x7 +#define I2C_SARADC_ENT_SAR_MSB 3 +#define I2C_SARADC_ENT_SAR_LSB 3 -#define ADC_SARADC1_ENCAL_REF_ADDR 0x7 -#define ADC_SARADC1_ENCAL_REF_ADDR_MSB 4 -#define ADC_SARADC1_ENCAL_REF_ADDR_LSB 4 +#define I2C_SARADC1_ENCAL_REF 0x7 +#define I2C_SARADC1_ENCAL_REF_MSB 4 +#define I2C_SARADC1_ENCAL_REF_LSB 4 -#define ADC_SAR1_ENCAL_GND_ADDR 0x7 -#define ADC_SAR1_ENCAL_GND_ADDR_MSB 5 -#define ADC_SAR1_ENCAL_GND_ADDR_LSB 5 +#define I2C_SAR1_ENCAL_GND 0x7 +#define I2C_SAR1_ENCAL_GND_MSB 5 +#define I2C_SAR1_ENCAL_GND_LSB 5 -#define ADC_SARADC2_ENCAL_REF_ADDR 0x7 -#define ADC_SARADC2_ENCAL_REF_ADDR_MSB 6 -#define ADC_SARADC2_ENCAL_REF_ADDR_LSB 6 +#define I2C_SARADC2_ENCAL_REF 0x7 +#define I2C_SARADC2_ENCAL_REF_MSB 6 +#define I2C_SARADC2_ENCAL_REF_LSB 6 -#define ADC_SAR2_ENCAL_GND_ADDR 0x7 -#define ADC_SAR2_ENCAL_GND_ADDR_MSB 7 -#define ADC_SAR2_ENCAL_GND_ADDR_LSB 7 +#define I2C_SAR2_ENCAL_GND 0x7 +#define I2C_SAR2_ENCAL_GND_MSB 7 +#define I2C_SAR2_ENCAL_GND_LSB 7 #define POWER_GLITCH_DREF_VDET_PERIF 11 #define POWER_GLITCH_DREF_VDET_PERIF_MSB 2