1 /*
2 * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "sdkconfig.h"
7 #include "bootloader_random.h"
8 #include "soc/soc.h"
9 #include "soc/pcr_reg.h"
10 #include "soc/apb_saradc_reg.h"
11 #include "soc/pmu_reg.h"
12 #include "hal/regi2c_ctrl.h"
13 #include "soc/regi2c_saradc.h"
14 #include "esp_log.h"
15
16 static const uint32_t SAR2_CHANNEL = 9;
17 static const uint32_t PATTERN_BIT_WIDTH = 6;
18 static const uint32_t SAR1_ATTEN = 1;
19 static const uint32_t SAR2_ATTEN = 1;
20
bootloader_random_enable(void)21 void bootloader_random_enable(void)
22 {
23 // pull SAR ADC out of reset
24 REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN);
25 REG_CLR_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN);
26
27 // enable SAR ADC APB clock
28 REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_REG_CLK_EN);
29
30 // enable ADC_CTRL_CLK (SAR ADC function clock)
31 REG_SET_BIT(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_EN);
32
33 // select XTAL clock (40 MHz) source for ADC_CTRL_CLK
34 REG_SET_FIELD(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_SEL, 0);
35
36 // set the clock divider for ADC_CTRL_CLK to default value (in case it has been changed)
37 REG_SET_FIELD(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_DIV_NUM, 0);
38
39 // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU
40 SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB);
41 SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
42
43 // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal voltage as sampling source
44 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR , 2);
45 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR , 1);
46 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 1);
47 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1);
48
49 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, 0x08);
50 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, 0x66);
51 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0x08);
52 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0x66);
53
54 // create patterns and set them in pattern table
55 uint32_t pattern_one = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation
56 uint32_t pattern_two = (SAR2_CHANNEL << 2) | SAR1_ATTEN; // we want channel 9 with max attenuation
57 uint32_t pattern_table = 0 | (pattern_two << 3 * PATTERN_BIT_WIDTH) | pattern_one << 2 * PATTERN_BIT_WIDTH;
58 REG_WRITE(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table);
59
60 // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0)
61 REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SARADC_SAR_PATT_LEN, 1);
62
63 // Same as in C3
64 REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SARADC_SAR_CLK_DIV, 15);
65
66 // set timer expiry (timer is ADC_CTRL_CLK)
67 REG_SET_FIELD(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_TARGET, 200);
68
69 // enable timer
70 REG_SET_BIT(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN);
71 }
72
bootloader_random_disable(void)73 void bootloader_random_disable(void)
74 {
75 // disable timer
76 REG_CLR_BIT(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN);
77
78 // Write reset value of this register
79 REG_WRITE(APB_SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF);
80
81 // Revert ADC I2C configuration and initial voltage source setting
82 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, 0x60);
83 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, 0x0);
84 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0x60);
85 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0x0);
86 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
87 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
88 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 0);
89 REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0);
90
91 // disable ADC_CTRL_CLK (SAR ADC function clock)
92 REG_WRITE(PCR_SARADC_CLKM_CONF_REG, 0x00404000);
93
94 // Set PCR_SARADC_CONF_REG to initial state
95 REG_WRITE(PCR_SARADC_CONF_REG, 0x5);
96 }
97