esp_hal/efuse/esp32s3/
mod.rs1use crate::{analog::adc::Attenuation, peripherals::EFUSE};
2
3#[cfg_attr(not(feature = "unstable"), allow(dead_code))]
4mod fields;
5#[instability::unstable]
6pub use fields::*;
7
8#[instability::unstable]
10pub enum AdcCalibUnit {
11 ADC1,
13 ADC2,
15}
16
17#[instability::unstable]
19pub fn flash_encryption() -> bool {
20 !super::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
21 .count_ones()
22 .is_multiple_of(2)
23}
24
25#[instability::unstable]
27pub fn rwdt_multiplier() -> u8 {
28 super::read_field_le::<u8>(WDT_DELAY_SEL)
29}
30
31#[instability::unstable]
35pub fn block_version() -> (u8, u8) {
36 (
39 super::read_field_le::<u8>(BLK_VERSION_MAJOR),
40 super::read_field_le::<u8>(BLK_VERSION_MINOR),
41 )
42}
43
44#[instability::unstable]
48pub fn rtc_calib_version() -> u8 {
49 let (major, _minor) = block_version();
50
51 if major == 1 { 1 } else { 0 }
52}
53
54#[instability::unstable]
58pub fn rtc_calib_init_code(unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
59 let version = rtc_calib_version();
60
61 if version != 1 {
62 return None;
63 }
64
65 let adc_icode_diff: [u16; 4] = match unit {
66 AdcCalibUnit::ADC1 => [
67 super::read_field_le(ADC1_INIT_CODE_ATTEN0),
68 super::read_field_le(ADC1_INIT_CODE_ATTEN1),
69 super::read_field_le(ADC1_INIT_CODE_ATTEN2),
70 super::read_field_le(ADC1_INIT_CODE_ATTEN3),
71 ],
72 AdcCalibUnit::ADC2 => [
73 super::read_field_le(ADC2_INIT_CODE_ATTEN0),
74 super::read_field_le(ADC2_INIT_CODE_ATTEN1),
75 super::read_field_le(ADC2_INIT_CODE_ATTEN2),
76 super::read_field_le(ADC2_INIT_CODE_ATTEN3),
77 ],
78 };
79
80 let mut adc_icode = [0; 4];
83 match unit {
84 AdcCalibUnit::ADC1 => {
85 adc_icode[0] = adc_icode_diff[0] + 1850;
86 adc_icode[1] = adc_icode_diff[1] + adc_icode[0] + 90;
87 adc_icode[2] = adc_icode_diff[2] + adc_icode[1];
88 adc_icode[3] = adc_icode_diff[3] + adc_icode[2] + 70;
89 }
90 AdcCalibUnit::ADC2 => {
91 adc_icode[0] = adc_icode_diff[0] + 2020;
92 adc_icode[1] = adc_icode_diff[1] + adc_icode[0];
93 adc_icode[2] = adc_icode_diff[2] + adc_icode[1];
94 adc_icode[3] = adc_icode_diff[3] + adc_icode[2];
95 }
96 }
97
98 Some(
99 adc_icode[match atten {
100 Attenuation::_0dB => 0,
101 Attenuation::_2p5dB => 1,
102 Attenuation::_6dB => 2,
103 Attenuation::_11dB => 3,
104 }],
105 )
106}
107
108#[instability::unstable]
112pub fn rtc_calib_cal_mv(_unit: AdcCalibUnit, _atten: Attenuation) -> u16 {
113 850
114}
115
116#[instability::unstable]
120pub fn rtc_calib_cal_code(unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
121 let version = rtc_calib_version();
122
123 if version != 1 {
124 return None;
125 }
126
127 let adc_vol_diff: [u16; 8] = [
128 super::read_field_le(ADC1_CAL_VOL_ATTEN0),
129 super::read_field_le(ADC1_CAL_VOL_ATTEN1),
130 super::read_field_le(ADC1_CAL_VOL_ATTEN2),
131 super::read_field_le(ADC1_CAL_VOL_ATTEN3),
132 super::read_field_le(ADC2_CAL_VOL_ATTEN0),
133 super::read_field_le(ADC2_CAL_VOL_ATTEN1),
134 super::read_field_le(ADC2_CAL_VOL_ATTEN2),
135 super::read_field_le(ADC2_CAL_VOL_ATTEN3),
136 ];
137
138 let mut adc1_vol = [0; 4];
139 let mut adc2_vol = [0; 4];
140 adc1_vol[3] = adc_vol_diff[3] + 900;
141 adc1_vol[2] = adc_vol_diff[2] + adc1_vol[3] + 800;
142 adc1_vol[1] = adc_vol_diff[1] + adc1_vol[2] + 700;
143 adc1_vol[0] = adc_vol_diff[0] + adc1_vol[1] + 800;
144 adc2_vol[3] = adc1_vol[3] - adc_vol_diff[7] + 15;
145 adc2_vol[2] = adc1_vol[2] - adc_vol_diff[6] + 20;
146 adc2_vol[1] = adc1_vol[1] - adc_vol_diff[5] + 10;
147 adc2_vol[0] = adc1_vol[0] - adc_vol_diff[4] + 40;
148
149 let atten = match atten {
150 Attenuation::_0dB => 0,
151 Attenuation::_2p5dB => 1,
152 Attenuation::_6dB => 2,
153 Attenuation::_11dB => 3,
154 };
155
156 Some(match unit {
157 AdcCalibUnit::ADC1 => adc1_vol[atten],
158 AdcCalibUnit::ADC2 => adc2_vol[atten],
159 })
160}
161
162#[instability::unstable]
164pub fn major_chip_version() -> u8 {
165 super::read_field_le(WAFER_VERSION_MAJOR)
166}
167
168#[instability::unstable]
170pub fn minor_chip_version() -> u8 {
171 super::read_field_le::<u8>(WAFER_VERSION_MINOR_HI) << 3
172 | super::read_field_le::<u8>(WAFER_VERSION_MINOR_LO)
173}
174
175#[derive(Debug, Clone, Copy, strum::FromRepr)]
176#[repr(u32)]
177pub(crate) enum EfuseBlock {
178 Block0,
179 Block1,
180 Block2,
181 Block3,
182 Block4,
183 Block5,
184 Block6,
185 Block7,
186 Block8,
187 Block9,
188 Block10,
189}
190
191impl EfuseBlock {
192 pub(crate) fn address(self) -> *const u32 {
193 let efuse = EFUSE::regs();
194 match self {
195 Self::Block0 => efuse.rd_wr_dis().as_ptr(),
196 Self::Block1 => efuse.rd_mac_spi_sys_0().as_ptr(),
197 Self::Block2 => efuse.rd_sys_part1_data0().as_ptr(),
198 Self::Block3 => efuse.rd_usr_data0().as_ptr(),
199 Self::Block4 => efuse.rd_key0_data0().as_ptr(),
200 Self::Block5 => efuse.rd_key1_data0().as_ptr(),
201 Self::Block6 => efuse.rd_key2_data0().as_ptr(),
202 Self::Block7 => efuse.rd_key3_data0().as_ptr(),
203 Self::Block8 => efuse.rd_key4_data0().as_ptr(),
204 Self::Block9 => efuse.rd_key5_data0().as_ptr(),
205 Self::Block10 => efuse.rd_sys_part2_data0().as_ptr(),
206 }
207 }
208}