esp_hal/soc/esp32c2/
trng.rs

1const I2C_SAR_ADC: u8 = 0x69;
2const I2C_SAR_ADC_HOSTID: u8 = 0;
3const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7;
4const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 6;
5const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 6;
6const ADC_SARADC_DTEST_RTC_ADDR: u8 = 0x7;
7const ADC_SARADC_DTEST_RTC_ADDR_MSB: u8 = 1;
8const ADC_SARADC_DTEST_RTC_ADDR_LSB: u8 = 0;
9const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x7;
10const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 3;
11const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 3;
12const ADC_SARADC_ENT_TSENS_ADDR: u8 = 0x07;
13const ADC_SARADC_ENT_TSENS_ADDR_MSB: u8 = 2;
14const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2;
15
16use crate::{
17    peripherals::{APB_SARADC, LPWR, SYSTEM},
18    rom::regi2c_write_mask,
19};
20
21/// Enable true randomness by enabling the entropy source.
22/// Blocks `ADC` usage.
23pub(crate) fn ensure_randomness() {
24    let rtc_cntl = LPWR::regs();
25    let system = SYSTEM::regs();
26    let apb_saradc = APB_SARADC::regs();
27
28    unsafe {
29        // RNG module is always clock enabled
30        rtc_cntl
31            .cntl_sensor_ctrl()
32            .modify(|_, w| w.force_xpd_sar().bits(3));
33
34        rtc_cntl.ana_conf().modify(|_, w| w.sar_i2c_pu().set_bit());
35
36        // Bridging sar2 internal reference voltage
37        // Cannot replace with PAC-based functions
38        regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1);
39
40        regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
41
42        regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
43
44        regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0);
45
46        // Enable SAR ADC2 internal channel to read adc2 ref voltage for additional
47        // entropy
48        system
49            .perip_clk_en0()
50            .modify(|_, w| w.apb_saradc_clk_en().set_bit());
51
52        system
53            .perip_rst_en0()
54            .modify(|_, w| w.apb_saradc_rst().clear_bit());
55
56        apb_saradc.clkm_conf().modify(|_, w| w.clk_sel().bits(2));
57
58        apb_saradc.clkm_conf().modify(|_, w| w.clk_en().set_bit());
59
60        apb_saradc.ctrl().modify(|_, w| w.sar_clk_gated().set_bit());
61
62        apb_saradc.ctrl().modify(|_, w| w.xpd_sar_force().bits(3));
63
64        apb_saradc.ctrl().modify(|_, w| w.sar_clk_div().bits(1));
65
66        apb_saradc.fsm_wait().modify(|_, w| w.rstb_wait().bits(8));
67
68        apb_saradc.fsm_wait().modify(|_, w| w.xpd_wait().bits(5));
69
70        apb_saradc
71            .fsm_wait()
72            .modify(|_, w| w.standby_wait().bits(100));
73
74        apb_saradc
75            .ctrl()
76            .modify(|_, w| w.sar_patt_p_clear().set_bit());
77
78        apb_saradc
79            .ctrl()
80            .modify(|_, w| w.sar_patt_p_clear().clear_bit());
81
82        apb_saradc.ctrl().modify(|_, w| w.sar_patt_len().bits(0));
83
84        apb_saradc
85            .sar_patt_tab1()
86            .modify(|_, w| w.sar_patt_tab1().bits(0x9cffff));
87
88        apb_saradc
89            .sar_patt_tab2()
90            .modify(|_, w| w.sar_patt_tab2().bits(0x9cffff));
91
92        apb_saradc.ctrl2().modify(|_, w| w.timer_target().bits(100));
93
94        apb_saradc
95            .clkm_conf()
96            .modify(|_, w| w.clkm_div_num().bits(15));
97
98        apb_saradc
99            .ctrl2()
100            .modify(|_, w| w.meas_num_limit().clear_bit());
101
102        apb_saradc.dma_conf().modify(|_, w| w.adc_trans().set_bit());
103
104        apb_saradc.ctrl2().modify(|_, w| w.timer_en().set_bit());
105    }
106}
107
108/// Disable true randomness. Unlocks `ADC` peripheral.
109pub(crate) fn revert_trng() {
110    let apb_saradc = APB_SARADC::regs();
111    let rtc_cntl = LPWR::regs();
112
113    unsafe {
114        regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0);
115
116        apb_saradc.ctrl2().modify(|_, w| w.timer_en().clear_bit());
117
118        apb_saradc
119            .dma_conf()
120            .modify(|_, w| w.adc_trans().clear_bit());
121
122        apb_saradc
123            .sar_patt_tab1()
124            .modify(|_, w| w.sar_patt_tab1().bits(0xffffff));
125
126        apb_saradc
127            .sar_patt_tab2()
128            .modify(|_, w| w.sar_patt_tab2().bits(0xffffff));
129
130        apb_saradc.clkm_conf().modify(|_, w| w.clk_en().clear_bit());
131
132        apb_saradc.ctrl().modify(|_, w| w.xpd_sar_force().bits(0));
133
134        rtc_cntl
135            .cntl_sensor_ctrl()
136            .modify(|_, w| w.force_xpd_sar().bits(0));
137    }
138}