esp_hal/efuse/esp32c2/
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}
14
15#[instability::unstable]
17pub fn flash_encryption() -> bool {
18 !super::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
19 .count_ones()
20 .is_multiple_of(2)
21}
22
23#[instability::unstable]
25pub fn rwdt_multiplier() -> u8 {
26 super::read_field_le::<u8>(WDT_DELAY_SEL)
27}
28
29#[instability::unstable]
33pub fn block_version() -> (u8, u8) {
34 (
37 super::read_field_le::<u8>(BLK_VERSION_MAJOR),
38 super::read_field_le::<u8>(BLK_VERSION_MINOR),
39 )
40}
41
42#[instability::unstable]
46pub fn rtc_calib_version() -> u8 {
47 let (major, _minor) = block_version();
48 if major == 0 { 1 } else { 0 }
49}
50
51#[instability::unstable]
55pub fn rtc_calib_init_code(_unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
56 let version = rtc_calib_version();
57
58 if version != 1 {
59 return None;
60 }
61
62 let diff_code0: u16 = super::read_field_le(ADC1_INIT_CODE_ATTEN0);
64 let code0 = if diff_code0 & (1 << 7) != 0 {
65 2160 - (diff_code0 & 0x7f)
66 } else {
67 2160 + diff_code0
68 };
69
70 if matches!(atten, Attenuation::_0dB) {
71 return Some(code0);
72 }
73
74 let diff_code11: u16 = super::read_field_le(ADC1_INIT_CODE_ATTEN3);
76 let code11 = code0 + diff_code11;
77
78 Some(code11)
79}
80
81#[instability::unstable]
85pub fn rtc_calib_cal_mv(_unit: AdcCalibUnit, atten: Attenuation) -> u16 {
86 match atten {
87 Attenuation::_0dB => 400,
88 Attenuation::_11dB => 1370,
89 _ => panic!("Unsupported attenuation"),
90 }
91}
92
93#[instability::unstable]
97pub fn rtc_calib_cal_code(_unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
98 let version = rtc_calib_version();
99
100 if version != 1 {
101 return None;
102 }
103
104 let diff_code0: u16 = super::read_field_le(ADC1_CAL_VOL_ATTEN0);
106 let code0 = if diff_code0 & (1 << 7) != 0 {
107 1540 - (diff_code0 & 0x7f)
108 } else {
109 1540 + diff_code0
110 };
111
112 if matches!(atten, Attenuation::_0dB) {
113 return Some(code0);
114 }
115
116 let diff_code11: u16 = super::read_field_le(ADC1_CAL_VOL_ATTEN3);
118 let code11 = if diff_code0 & (1 << 5) != 0 {
119 code0 - (diff_code11 & 0x1f)
120 } else {
121 code0 + diff_code11
122 } - 123;
123
124 Some(code11)
125}
126
127#[instability::unstable]
129pub fn major_chip_version() -> u8 {
130 super::read_field_le(WAFER_VERSION_MAJOR)
131}
132
133#[instability::unstable]
135pub fn minor_chip_version() -> u8 {
136 super::read_field_le(WAFER_VERSION_MINOR)
137}
138
139#[derive(Debug, Clone, Copy, strum::FromRepr)]
140#[repr(u32)]
141pub(crate) enum EfuseBlock {
142 Block0,
143 Block1,
144 Block2,
145 Block3,
146}
147
148impl EfuseBlock {
149 pub(crate) fn address(self) -> *const u32 {
150 let efuse = EFUSE::regs();
151 match self {
152 Self::Block0 => efuse.rd_wr_dis().as_ptr(),
153 Self::Block1 => efuse.rd_blk1_data0().as_ptr(),
154 Self::Block2 => efuse.rd_blk2_data0().as_ptr(),
155 Self::Block3 => efuse.rd_blk3_data0().as_ptr(),
156 }
157 }
158}