esp_hal/efuse/esp32c6/
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
44fn get_signed_val(data: u32, sign_bit: u32) -> i32 {
48 let sign_mask = 1u32 << sign_bit;
49 if data & sign_mask != 0 {
50 -((data & !sign_mask) as i32)
51 } else {
52 data as i32
53 }
54}
55
56#[instability::unstable]
60pub fn rtc_calib_version() -> u8 {
61 let (_major, minor) = block_version();
62 if minor == 1 {
63 1
64 } else if minor >= 2 {
65 2
66 } else {
67 0
68 }
69}
70
71#[instability::unstable]
75pub fn rtc_calib_init_code(_unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
76 let version = rtc_calib_version();
77
78 if !(1..=2).contains(&version) {
79 return None;
80 }
81
82 let init_code: u16 = super::read_field_le(match atten {
84 Attenuation::_0dB => ADC1_INIT_CODE_ATTEN0,
85 Attenuation::_2p5dB => ADC1_INIT_CODE_ATTEN1,
86 Attenuation::_6dB => ADC1_INIT_CODE_ATTEN2,
87 Attenuation::_11dB => ADC1_INIT_CODE_ATTEN3,
88 });
89
90 Some(init_code + 1600)
91}
92
93#[instability::unstable]
97pub fn rtc_calib_get_chan_compens(
98 _unit: AdcCalibUnit,
99 channel: u8,
100 atten: Attenuation,
101) -> Option<i32> {
102 let chan_diff: u32 = super::read_field_le(match channel {
103 0 => ADC1_INIT_CODE_ATTEN0_CH0,
104 1 => ADC1_INIT_CODE_ATTEN0_CH1,
105 2 => ADC1_INIT_CODE_ATTEN0_CH2,
106 3 => ADC1_INIT_CODE_ATTEN0_CH3,
107 4 => ADC1_INIT_CODE_ATTEN0_CH4,
108 5 => ADC1_INIT_CODE_ATTEN0_CH5,
109 _ => ADC1_INIT_CODE_ATTEN0_CH6,
110 });
111
112 Some(get_signed_val(chan_diff, 3) * (4 - atten as i32))
113}
114
115#[instability::unstable]
119pub fn rtc_calib_cal_mv(_unit: AdcCalibUnit, atten: Attenuation) -> u16 {
120 let version = rtc_calib_version();
121 let input_vout_mv = match version {
122 2 => [750, 1000, 1500, 2800],
123 _ => [400, 550, 750, 1370],
124 };
125
126 input_vout_mv[atten as usize]
127}
128
129#[instability::unstable]
133pub fn rtc_calib_cal_code(_unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
134 let version = rtc_calib_version();
135
136 if !(1..=2).contains(&version) {
137 return None;
138 }
139
140 let cal_vol: u16 = super::read_field_le(match atten {
142 Attenuation::_0dB => ADC1_CAL_VOL_ATTEN0,
143 Attenuation::_2p5dB => ADC1_CAL_VOL_ATTEN1,
144 Attenuation::_6dB => ADC1_CAL_VOL_ATTEN2,
145 Attenuation::_11dB => ADC1_CAL_VOL_ATTEN3,
146 });
147
148 let chk_offset = if version == 1 {
149 1500
150 } else if atten == Attenuation::_6dB {
151 2900
152 } else {
153 2850
154 };
155
156 Some((chk_offset + get_signed_val(cal_vol as u32, 9)) as u16)
157}
158
159#[instability::unstable]
161pub fn major_chip_version() -> u8 {
162 super::read_field_le(WAFER_VERSION_MAJOR)
163}
164
165#[instability::unstable]
167pub fn minor_chip_version() -> u8 {
168 super::read_field_le(WAFER_VERSION_MINOR)
169}
170
171#[derive(Debug, Clone, Copy, strum::FromRepr)]
172#[repr(u32)]
173pub(crate) enum EfuseBlock {
174 Block0,
175 Block1,
176 Block2,
177 Block3,
178 Block4,
179 Block5,
180 Block6,
181 Block7,
182 Block8,
183 Block9,
184 Block10,
185}
186
187impl EfuseBlock {
188 pub(crate) fn address(self) -> *const u32 {
189 let efuse = EFUSE::regs();
190 match self {
191 Self::Block0 => efuse.rd_wr_dis().as_ptr(),
192 Self::Block1 => efuse.rd_mac_spi_sys_0().as_ptr(),
193 Self::Block2 => efuse.rd_sys_part1_data0().as_ptr(),
194 Self::Block3 => efuse.rd_usr_data0().as_ptr(),
195 Self::Block4 => efuse.rd_key0_data0().as_ptr(),
196 Self::Block5 => efuse.rd_key1_data0().as_ptr(),
197 Self::Block6 => efuse.rd_key2_data0().as_ptr(),
198 Self::Block7 => efuse.rd_key3_data0().as_ptr(),
199 Self::Block8 => efuse.rd_key4_data0().as_ptr(),
200 Self::Block9 => efuse.rd_key5_data0().as_ptr(),
201 Self::Block10 => efuse.rd_sys_part2_data0().as_ptr(),
202 }
203 }
204}