Skip to main content

esp_hal/efuse/esp32c6/
mod.rs

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/// Selects which ADC we are interested in the efuse calibration data for
9#[instability::unstable]
10pub enum AdcCalibUnit {
11    /// Select efuse calibration data for ADC1
12    ADC1,
13    /// Select efuse calibration data for ADC2
14    ADC2,
15}
16
17/// Get status of SPI boot encryption.
18#[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/// Get the multiplier for the timeout value of the RWDT STAGE 0 register.
26#[instability::unstable]
27pub fn rwdt_multiplier() -> u8 {
28    super::read_field_le::<u8>(WDT_DELAY_SEL)
29}
30
31/// Get efuse block version
32///
33/// see <https://github.com/espressif/esp-idf/blob/dc016f5987/components/hal/efuse_hal.c#L27-L30>
34#[instability::unstable]
35pub fn block_version() -> (u8, u8) {
36    // see <https://github.com/espressif/esp-idf/blob/dc016f5987/components/hal/esp32c6/include/hal/efuse_ll.h#L65-L73>
37    // <https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c6/esp_efuse_table.csv#L156>
38    (
39        super::read_field_le::<u8>(BLK_VERSION_MAJOR),
40        super::read_field_le::<u8>(BLK_VERSION_MINOR),
41    )
42}
43
44/// Get version of RTC calibration block
45///
46/// see <https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c6/esp_efuse_rtc_calib.c#L20>
47#[instability::unstable]
48pub fn rtc_calib_version() -> u8 {
49    let (_major, minor) = block_version();
50    if minor >= 1 { 1 } else { 0 }
51}
52
53/// Get ADC initial code for specified attenuation from efuse
54///
55/// see <https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c6/esp_efuse_rtc_calib.c#L32>
56#[instability::unstable]
57pub fn rtc_calib_init_code(_unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
58    let version = rtc_calib_version();
59
60    if version != 1 {
61        return None;
62    }
63
64    // See <https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c6/esp_efuse_table.csv#L147-L152>
65    let init_code: u16 = super::read_field_le(match atten {
66        Attenuation::_0dB => ADC1_INIT_CODE_ATTEN0,
67        Attenuation::_2p5dB => ADC1_INIT_CODE_ATTEN1,
68        Attenuation::_6dB => ADC1_INIT_CODE_ATTEN2,
69        Attenuation::_11dB => ADC1_INIT_CODE_ATTEN3,
70    });
71
72    Some(init_code + 1600) // version 1 logic
73}
74
75/// Get ADC reference point voltage for specified attenuation in millivolts
76///
77/// see <https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c6/esp_efuse_rtc_calib.c#L42>
78#[instability::unstable]
79pub fn rtc_calib_cal_mv(_unit: AdcCalibUnit, atten: Attenuation) -> u16 {
80    match atten {
81        Attenuation::_0dB => 400,
82        Attenuation::_2p5dB => 550,
83        Attenuation::_6dB => 750,
84        Attenuation::_11dB => 1370,
85    }
86}
87
88/// Get ADC reference point digital code for specified attenuation
89///
90/// see <https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c6/esp_efuse_rtc_calib.c#L42>
91#[instability::unstable]
92pub fn rtc_calib_cal_code(_unit: AdcCalibUnit, atten: Attenuation) -> Option<u16> {
93    let version = rtc_calib_version();
94
95    if version != 1 {
96        return None;
97    }
98
99    // See <https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c6/esp_efuse_table.csv#L153-L156>
100    let cal_code: u16 = super::read_field_le(match atten {
101        Attenuation::_0dB => ADC1_CAL_VOL_ATTEN0,
102        Attenuation::_2p5dB => ADC1_CAL_VOL_ATTEN1,
103        Attenuation::_6dB => ADC1_CAL_VOL_ATTEN2,
104        Attenuation::_11dB => ADC1_CAL_VOL_ATTEN3,
105    });
106
107    let cal_code = if cal_code & (1 << 9) != 0 {
108        1500 - (cal_code & !(1 << 9))
109    } else {
110        1500 + cal_code
111    };
112
113    Some(cal_code)
114}
115
116/// Returns the major hardware revision
117#[instability::unstable]
118pub fn major_chip_version() -> u8 {
119    super::read_field_le(WAFER_VERSION_MAJOR)
120}
121
122/// Returns the minor hardware revision
123#[instability::unstable]
124pub fn minor_chip_version() -> u8 {
125    super::read_field_le(WAFER_VERSION_MINOR)
126}
127
128#[derive(Debug, Clone, Copy, strum::FromRepr)]
129#[repr(u32)]
130pub(crate) enum EfuseBlock {
131    Block0,
132    Block1,
133    Block2,
134    Block3,
135    Block4,
136    Block5,
137    Block6,
138    Block7,
139    Block8,
140    Block9,
141    Block10,
142}
143
144impl EfuseBlock {
145    pub(crate) fn address(self) -> *const u32 {
146        let efuse = EFUSE::regs();
147        match self {
148            Self::Block0 => efuse.rd_wr_dis().as_ptr(),
149            Self::Block1 => efuse.rd_mac_spi_sys_0().as_ptr(),
150            Self::Block2 => efuse.rd_sys_part1_data0().as_ptr(),
151            Self::Block3 => efuse.rd_usr_data0().as_ptr(),
152            Self::Block4 => efuse.rd_key0_data0().as_ptr(),
153            Self::Block5 => efuse.rd_key1_data0().as_ptr(),
154            Self::Block6 => efuse.rd_key2_data0().as_ptr(),
155            Self::Block7 => efuse.rd_key3_data0().as_ptr(),
156            Self::Block8 => efuse.rd_key4_data0().as_ptr(),
157            Self::Block9 => efuse.rd_key5_data0().as_ptr(),
158            Self::Block10 => efuse.rd_sys_part2_data0().as_ptr(),
159        }
160    }
161}