Skip to content

Commit 5ba8f6a

Browse files
committed
refactor(rng): refactor to use hal/ll apis for S2
1 parent 333a2c0 commit 5ba8f6a

File tree

2 files changed

+144
-54
lines changed

2 files changed

+144
-54
lines changed

components/bootloader_support/src/bootloader_random_esp32s2.c

Lines changed: 54 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -16,6 +16,10 @@
1616
#include "esp_private/regi2c_ctrl.h"
1717
#include "hal/adc_ll.h"
1818

19+
#include "esp_rom_sys.h"
20+
#include "hal/clk_tree_ll.h"
21+
#include "hal/sar_ctrl_ll.h"
22+
1923
#ifndef BOOTLOADER_BUILD
2024
#include "esp_private/periph_ctrl.h"
2125
#endif
@@ -33,63 +37,63 @@ void bootloader_random_enable(void)
3337

3438
// Enable 8M clock source for RNG (this is actually enough to produce strong random results,
3539
// but enabling the SAR ADC as well adds some insurance.)
36-
REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN);
40+
clk_ll_rc_fast_digi_enable();
3741

3842
// Enable SAR ADC to read a disconnected input for additional entropy
39-
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN0_REG,DPORT_APB_SARADC_CLK_EN);
40-
41-
REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_SEL, 2);
42-
43-
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
44-
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
45-
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18));
46-
SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16));
47-
48-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 0x4);
49-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_DREF_ADDR, 0x4);
50-
51-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 1);
52-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 1);
53-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
54-
55-
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR1_PATT_LEN, 0);
56-
WRITE_PERI_REG(APB_SARADC_SAR1_PATT_TAB1_REG,0xafffffff); // set adc1 channel & bitwidth & atten
57-
58-
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR2_PATT_LEN, 0);
59-
WRITE_PERI_REG(APB_SARADC_SAR2_PATT_TAB1_REG,0xafffffff); //set adc2 channel & bitwidth & atten
60-
61-
SET_PERI_REG_MASK(SENS_SAR_MEAS1_MUX_REG,SENS_SAR1_DIG_FORCE);
62-
63-
REG_SET_FIELD(APB_SARADC_CTRL_REG,APB_SARADC_WORK_MODE, 1);
43+
_adc_ll_reset_register();
44+
_adc_ll_enable_bus_clock(true);
6445

65-
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_MEAS_NUM_LIMIT);
46+
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_APB);
47+
adc_ll_calibration_prepare(ADC_UNIT_1, false);
48+
adc_ll_calibration_prepare(ADC_UNIT_2, false);
49+
adc_ll_calibration_init(ADC_UNIT_1);
50+
adc_ll_calibration_init(ADC_UNIT_2);
6651

67-
REG_SET_FIELD(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 3);
68-
69-
SET_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_TIMER_SEL);
70-
71-
REG_SET_FIELD(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_TARGET, 100);
72-
73-
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL_REG,APB_SARADC_START_FORCE);
74-
75-
SET_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_TIMER_EN);
52+
#ifndef BOOTLOADER_BUILD
53+
regi2c_saradc_enable();
54+
#else
55+
regi2c_ctrl_ll_i2c_sar_periph_enable();
56+
#endif
57+
// enable analog i2c master clock for RNG runtime
58+
ANALOG_CLOCK_ENABLE();
59+
60+
adc_ll_regi2c_init();
61+
sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON);
62+
63+
adc_digi_pattern_config_t pattern_config = {};
64+
pattern_config.unit = ADC_UNIT_1;
65+
pattern_config.atten = ADC_ATTEN_DB_12;
66+
pattern_config.channel = ADC_CHANNEL_10; //Use reserved channel 10 to get internal voltage
67+
adc_ll_digi_set_pattern_table(ADC_UNIT_1, 0, pattern_config);
68+
pattern_config.unit = ADC_UNIT_2;
69+
pattern_config.atten = ADC_ATTEN_DB_12;
70+
pattern_config.channel = ADC_CHANNEL_10; //Use reserved channel 10 to get internal voltage
71+
adc_ll_digi_set_pattern_table(ADC_UNIT_2, 0, pattern_config);
72+
adc_ll_digi_set_pattern_table_len(ADC_UNIT_1, 1);
73+
adc_ll_digi_set_pattern_table_len(ADC_UNIT_2, 1);
74+
75+
adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_BOTH_UNIT);
76+
77+
adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_DIG);
78+
79+
adc_ll_digi_set_clk_div(4);
80+
adc_ll_digi_set_trigger_interval(100);
81+
adc_ll_digi_trigger_enable();
7682
}
7783

7884
void bootloader_random_disable(void)
7985
{
80-
/* Restore internal I2C bus state */
81-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 0x1);
82-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_DREF_ADDR, 0x1);
83-
84-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 0);
85-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0);
86-
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
87-
88-
/* Restore SARADC to default mode */
89-
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE);
90-
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN0_REG, DPORT_APB_SARADC_CLK_EN);
91-
SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S);
92-
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN);
86+
adc_ll_calibration_clear();
87+
_adc_ll_enable_bus_clock(false);
88+
adc_ll_digi_trigger_disable();
89+
adc_ll_digi_reset_pattern_table();
90+
91+
adc_ll_regi2c_adc_deinit();
92+
#ifndef BOOTLOADER_BUILD
93+
regi2c_saradc_disable();
94+
#endif
95+
96+
ANALOG_CLOCK_DISABLE();
9397

9498
/* Note: the 8M CLK entropy source continues running even after this function is called,
9599
but as mentioned above it's better to enable Wi-Fi or BT or call bootloader_random_enable()

components/hal/esp32s2/include/hal/adc_ll.h

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,17 @@ static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t
247247
}
248248
}
249249

250+
/**
251+
* Rest pattern table to default value
252+
*/
253+
static inline void adc_ll_digi_reset_pattern_table(void)
254+
{
255+
for(int i = 0; i < 4; i++) {
256+
APB_SARADC.sar1_patt_tab[i] = 0xffffff;
257+
APB_SARADC.sar2_patt_tab[i] = 0xffffff;
258+
}
259+
}
260+
250261
/**
251262
* Set pattern table for digital controller.
252263
* The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
@@ -928,7 +939,7 @@ static inline void adc_oneshot_ll_disable_all_unit(void)
928939
* @brief Enable the ADC clock
929940
* @param enable true to enable, false to disable
930941
*/
931-
static inline void adc_ll_enable_bus_clock(bool enable)
942+
static inline void _adc_ll_enable_bus_clock(bool enable)
932943
{
933944
uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG);
934945
reg_val = reg_val & (~DPORT_APB_SARADC_CLK_EN);
@@ -938,21 +949,21 @@ static inline void adc_ll_enable_bus_clock(bool enable)
938949
// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way
939950
#define adc_ll_enable_bus_clock(...) do { \
940951
(void)__DECLARE_RCC_ATOMIC_ENV; \
941-
adc_ll_enable_bus_clock(__VA_ARGS__); \
952+
_adc_ll_enable_bus_clock(__VA_ARGS__); \
942953
} while(0)
943954

944955
/**
945956
* @brief Reset ADC module
946957
*/
947-
static inline void adc_ll_reset_register(void)
958+
static inline void _adc_ll_reset_register(void)
948959
{
949960
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_APB_SARADC_RST);
950961
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_APB_SARADC_RST);
951962
}
952963
// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way
953964
#define adc_ll_reset_register(...) do { \
954965
(void)__DECLARE_RCC_ATOMIC_ENV; \
955-
adc_ll_reset_register(__VA_ARGS__); \
966+
_adc_ll_reset_register(__VA_ARGS__); \
956967
} while(0)
957968

958969
/**
@@ -1170,6 +1181,19 @@ static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gn
11701181
}
11711182
}
11721183

1184+
/**
1185+
* Clear calibration prepare settings
1186+
* This function reverses the operations done by adc_ll_calibration_prepare
1187+
*/
1188+
static inline void adc_ll_calibration_clear(void)
1189+
{
1190+
/* Reverse the operations done in adc_ll_calibration_prepare */
1191+
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
1192+
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
1193+
SET_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M);
1194+
CLEAR_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M);
1195+
}
1196+
11731197
/**
11741198
* Resume register status after calibration.
11751199
*
@@ -1209,6 +1233,68 @@ static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param
12091233
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, lsb);
12101234
}
12111235
}
1236+
1237+
/**
1238+
* Set the SAR DTEST param
1239+
*
1240+
* @param param DTEST value
1241+
*/
1242+
__attribute__((always_inline))
1243+
static inline void adc_ll_set_dtest_param(uint32_t param)
1244+
{
1245+
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, param);
1246+
}
1247+
1248+
/**
1249+
* Set the SAR ENT param
1250+
*
1251+
* @param param ENT value
1252+
*/
1253+
__attribute__((always_inline))
1254+
static inline void adc_ll_set_ent_param(uint32_t param)
1255+
{
1256+
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, param);
1257+
}
1258+
1259+
/**
1260+
* Enable/disable the calibration voltage reference for ADC unit.
1261+
*
1262+
* @param adc_n ADC index number.
1263+
* @param en true to enable, false to disable
1264+
*/
1265+
__attribute__((always_inline))
1266+
static inline void adc_ll_enable_calibration_ref(adc_unit_t adc_n, bool en)
1267+
{
1268+
(void)adc_n;
1269+
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, en);
1270+
}
1271+
1272+
/**
1273+
* Init regi2c SARADC registers
1274+
*/
1275+
__attribute__((always_inline))
1276+
static inline void adc_ll_regi2c_init(void)
1277+
{
1278+
adc_ll_set_dtest_param(0);
1279+
adc_ll_set_ent_param(1);
1280+
// Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal voltage as sampling source
1281+
adc_ll_enable_calibration_ref(ADC_UNIT_1, true);
1282+
adc_ll_enable_calibration_ref(ADC_UNIT_2, true);
1283+
}
1284+
1285+
/**
1286+
* Deinit regi2c SARADC registers
1287+
*/
1288+
__attribute__((always_inline))
1289+
static inline void adc_ll_regi2c_adc_deinit(void)
1290+
{
1291+
adc_ll_set_dtest_param(0);
1292+
adc_ll_set_ent_param(0);
1293+
adc_ll_enable_calibration_ref(ADC_UNIT_1, false);
1294+
adc_ll_enable_calibration_ref(ADC_UNIT_2, false);
1295+
}
1296+
1297+
12121298
/* Temp code end. */
12131299

12141300
/**

0 commit comments

Comments
 (0)