1use 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
17impl AdcCalibUnit {
18 fn index(self) -> u8 {
19 match self {
20 Self::ADC1 => 0,
21 Self::ADC2 => 1,
22 }
23 }
24}
25
26#[derive(Clone, Copy)]
28#[instability::unstable]
29pub enum RtcCalibParam {
30 Vlow,
32 Vhigh,
34 Vinit,
36}
37
38struct RtcCalibEntry {
39 begin_bit: u16,
40 length: u8,
41 multiplier: i16,
42 base: i16,
43 depends: u8,
44}
45
46const RTC_CALIB_MAP: [RtcCalibEntry; 33] = [
48 RtcCalibEntry {
49 begin_bit: 0,
50 length: 0,
51 multiplier: 0,
52 base: 0,
53 depends: 0,
54 },
55 RtcCalibEntry {
57 begin_bit: 208,
58 length: 6,
59 multiplier: 4,
60 base: 2231,
61 depends: 0,
62 },
63 RtcCalibEntry {
64 begin_bit: 214,
65 length: 6,
66 multiplier: 4,
67 base: 1643,
68 depends: 0,
69 },
70 RtcCalibEntry {
71 begin_bit: 220,
72 length: 6,
73 multiplier: 4,
74 base: 1290,
75 depends: 0,
76 },
77 RtcCalibEntry {
78 begin_bit: 226,
79 length: 6,
80 multiplier: 4,
81 base: 701,
82 depends: 0,
83 },
84 RtcCalibEntry {
85 begin_bit: 232,
86 length: 6,
87 multiplier: 4,
88 base: 2305,
89 depends: 0,
90 },
91 RtcCalibEntry {
92 begin_bit: 238,
93 length: 6,
94 multiplier: 4,
95 base: 1693,
96 depends: 0,
97 },
98 RtcCalibEntry {
99 begin_bit: 244,
100 length: 6,
101 multiplier: 4,
102 base: 1343,
103 depends: 0,
104 },
105 RtcCalibEntry {
106 begin_bit: 250,
107 length: 6,
108 multiplier: 4,
109 base: 723,
110 depends: 0,
111 },
112 RtcCalibEntry {
114 begin_bit: 144,
115 length: 8,
116 multiplier: 4,
117 base: 5775,
118 depends: 0,
119 },
120 RtcCalibEntry {
121 begin_bit: 152,
122 length: 8,
123 multiplier: 4,
124 base: 5693,
125 depends: 0,
126 },
127 RtcCalibEntry {
128 begin_bit: 160,
129 length: 8,
130 multiplier: 4,
131 base: 5723,
132 depends: 0,
133 },
134 RtcCalibEntry {
135 begin_bit: 168,
136 length: 8,
137 multiplier: 4,
138 base: 6209,
139 depends: 0,
140 },
141 RtcCalibEntry {
142 begin_bit: 176,
143 length: 8,
144 multiplier: 4,
145 base: 5817,
146 depends: 0,
147 },
148 RtcCalibEntry {
149 begin_bit: 184,
150 length: 8,
151 multiplier: 4,
152 base: 5703,
153 depends: 0,
154 },
155 RtcCalibEntry {
156 begin_bit: 192,
157 length: 8,
158 multiplier: 4,
159 base: 5731,
160 depends: 0,
161 },
162 RtcCalibEntry {
163 begin_bit: 200,
164 length: 8,
165 multiplier: 4,
166 base: 6157,
167 depends: 0,
168 },
169 RtcCalibEntry {
171 begin_bit: 197,
172 length: 6,
173 multiplier: 2,
174 base: 169,
175 depends: 19,
176 },
177 RtcCalibEntry {
178 begin_bit: 203,
179 length: 6,
180 multiplier: 2,
181 base: -26,
182 depends: 19,
183 },
184 RtcCalibEntry {
185 begin_bit: 209,
186 length: 9,
187 multiplier: 2,
188 base: 126,
189 depends: 22,
190 },
191 RtcCalibEntry {
192 begin_bit: 218,
193 length: 7,
194 multiplier: 2,
195 base: 387,
196 depends: 19,
197 },
198 RtcCalibEntry {
199 begin_bit: 225,
200 length: 7,
201 multiplier: 2,
202 base: 177,
203 depends: 22,
204 },
205 RtcCalibEntry {
206 begin_bit: 232,
207 length: 10,
208 multiplier: 2,
209 base: 5815,
210 depends: 0,
211 },
212 RtcCalibEntry {
213 begin_bit: 242,
214 length: 7,
215 multiplier: 2,
216 base: 27,
217 depends: 22,
218 },
219 RtcCalibEntry {
220 begin_bit: 249,
221 length: 7,
222 multiplier: 2,
223 base: 410,
224 depends: 22,
225 },
226 RtcCalibEntry {
228 begin_bit: 147,
229 length: 8,
230 multiplier: 2,
231 base: 1519,
232 depends: 0,
233 },
234 RtcCalibEntry {
235 begin_bit: 155,
236 length: 6,
237 multiplier: 2,
238 base: 88,
239 depends: 25,
240 },
241 RtcCalibEntry {
242 begin_bit: 161,
243 length: 5,
244 multiplier: 2,
245 base: 8,
246 depends: 26,
247 },
248 RtcCalibEntry {
249 begin_bit: 166,
250 length: 6,
251 multiplier: 2,
252 base: 70,
253 depends: 27,
254 },
255 RtcCalibEntry {
256 begin_bit: 172,
257 length: 8,
258 multiplier: 2,
259 base: 1677,
260 depends: 0,
261 },
262 RtcCalibEntry {
263 begin_bit: 180,
264 length: 6,
265 multiplier: 2,
266 base: 23,
267 depends: 29,
268 },
269 RtcCalibEntry {
270 begin_bit: 186,
271 length: 5,
272 multiplier: 2,
273 base: 6,
274 depends: 30,
275 },
276 RtcCalibEntry {
277 begin_bit: 191,
278 length: 6,
279 multiplier: 2,
280 base: 13,
281 depends: 31,
282 },
283];
284
285fn signed_bit_to_int(number: u32, len: u32) -> i32 {
286 if number >> (len - 1) != 0 {
287 -((number ^ (1 << (len - 1))) as i32)
288 } else {
289 number as i32
290 }
291}
292
293fn rtc_calib_tag(version: u8, unit: u8, atten: Attenuation, param: RtcCalibParam) -> Option<u8> {
294 let atten = atten as u8;
295 let offset = match (version, param) {
296 (1, RtcCalibParam::Vlow) => 1,
297 (1, RtcCalibParam::Vhigh) => 9,
298 (2, RtcCalibParam::Vhigh) => 17,
299 (2, RtcCalibParam::Vinit) => 25,
300 _ => return None,
301 };
302 Some(offset + unit * 4 + atten)
303}
304
305fn rtc_calib_parsed(tag: u8, skip_efuse: bool) -> i32 {
306 if tag == 0 {
307 return 0;
308 }
309 let entry = &RTC_CALIB_MAP[tag as usize];
310 let raw = if skip_efuse {
311 0
312 } else {
313 let field = crate::efuse::EfuseField::new(
314 2,
315 (entry.begin_bit as u32) / 32,
316 entry.begin_bit as u32,
317 entry.length as u32,
318 );
319 let bits = super::read_field_le::<u32>(field);
320 signed_bit_to_int(bits, entry.length as u32) * i32::from(entry.multiplier)
321 };
322 raw + i32::from(entry.base) + rtc_calib_parsed(entry.depends, skip_efuse)
323}
324
325#[instability::unstable]
329pub fn rtc_calib_reading(version: u8, unit: u8, atten: Attenuation, param: RtcCalibParam) -> i32 {
330 rtc_calib_reading_inner(version, unit, atten, param, false)
331}
332
333pub(crate) fn rtc_calib_reading_inner(
334 version: u8,
335 unit: u8,
336 atten: Attenuation,
337 param: RtcCalibParam,
338 skip_efuse: bool,
339) -> i32 {
340 rtc_calib_tag(version, unit, atten, param)
341 .map(|tag| rtc_calib_parsed(tag, skip_efuse))
342 .unwrap_or(0)
343}
344
345#[instability::unstable]
349pub fn rtc_calib_version() -> u8 {
350 super::read_field_le::<u8>(BLK_VERSION_MINOR)
351}
352
353#[instability::unstable]
355pub fn rtc_calib_init_code(unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
356 if rtc_calib_version() != 2 {
357 return None;
358 }
359 Some(rtc_calib_reading(2, unit.index(), atten, RtcCalibParam::Vinit) as u16)
360}
361
362#[instability::unstable]
364pub fn rtc_calib_cal_mv(_unit: AdcCalibUnit, atten: Attenuation) -> u16 {
365 match atten {
366 Attenuation::_0dB => 600,
367 Attenuation::_2p5dB => 800,
368 Attenuation::_6dB => 1000,
369 Attenuation::_11dB => 2000,
370 }
371}
372
373#[instability::unstable]
375pub fn rtc_calib_cal_code(unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
376 if rtc_calib_version() != 2 {
377 return None;
378 }
379 Some(rtc_calib_reading(2, unit.index(), atten, RtcCalibParam::Vhigh) as u16)
380}
381
382#[instability::unstable]
384pub fn flash_encryption() -> bool {
385 !super::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
386 .count_ones()
387 .is_multiple_of(2)
388}
389
390#[instability::unstable]
392pub fn rwdt_multiplier() -> u8 {
393 super::read_field_le::<u8>(WDT_DELAY_SEL)
394}
395
396#[instability::unstable]
398pub fn major_chip_version() -> u8 {
399 super::read_field_le(WAFER_VERSION_MAJOR)
400}
401
402#[instability::unstable]
404pub fn minor_chip_version() -> u8 {
405 super::read_field_le::<u8>(WAFER_VERSION_MINOR_HI) << 3
406 | super::read_field_le::<u8>(WAFER_VERSION_MINOR_LO)
407}
408
409#[derive(Debug, Clone, Copy, strum::FromRepr)]
410#[repr(u32)]
411pub(crate) enum EfuseBlock {
412 Block0,
413 Block1,
414 Block2,
415 Block3,
416 Block4,
417 Block5,
418 Block6,
419 Block7,
420 Block8,
421 Block9,
422 Block10,
423}
424
425impl EfuseBlock {
426 pub(crate) fn address(self) -> *const u32 {
427 let efuse = EFUSE::regs();
428 match self {
429 Self::Block0 => efuse.rd_wr_dis().as_ptr(),
430 Self::Block1 => efuse.rd_mac_spi_sys_0().as_ptr(),
431 Self::Block2 => efuse.rd_sys_data_part1_(0).as_ptr(),
432 Self::Block3 => efuse.rd_usr_data(0).as_ptr(),
433 Self::Block4 => efuse.rd_key0_data(0).as_ptr(),
434 Self::Block5 => efuse.rd_key1_data(0).as_ptr(),
435 Self::Block6 => efuse.rd_key2_data(0).as_ptr(),
436 Self::Block7 => efuse.rd_key3_data(0).as_ptr(),
437 Self::Block8 => efuse.rd_key4_data(0).as_ptr(),
438 Self::Block9 => efuse.rd_key5_data(0).as_ptr(),
439 Self::Block10 => efuse.rd_sys_data_part2_(0).as_ptr(),
440 }
441 }
442}