Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
adc_cal: c2: Add efuse functions for reading calibration
  • Loading branch information
katyo committed Jul 4, 2023
commit 69208ecc86ff922bfccd0e6651c6e63ba71fe854
98 changes: 97 additions & 1 deletion esp-hal-common/src/soc/esp32c2/efuse.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Reading of eFuses

use crate::peripherals::EFUSE;
pub use crate::soc::efuse_field::*;
use crate::{adc::Attenuation, peripherals::EFUSE};

pub struct Efuse;

Expand Down Expand Up @@ -36,6 +36,102 @@ impl Efuse {
pub fn get_rwdt_multiplier() -> u8 {
Self::read_field_le::<u8>(WDT_DELAY_SEL)
}

/// Get efuse block version
///
/// see https://github.com/espressif/esp-idf/blob/dc016f5987/components/hal/efuse_hal.c#L27-L30
pub fn get_block_version() -> (u8, u8) {
// see https://github.com/espressif/esp-idf/blob/dc016f5987/components/hal/esp32c2/include/hal/efuse_ll.h#L65-L73
// https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_table.csv#L90-L91
(
Self::read_field_le::<u8>(BLK_VERSION_MAJOR),
Self::read_field_le::<u8>(BLK_VERSION_MINOR),
)
}

/// Get version of RTC calibration block
///
/// see https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_rtc_calib.c#L14
pub fn get_rtc_calib_version() -> u8 {
let (major, _minor) = Self::get_block_version();
if major == 0 {
1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 1 needs to be a named constant IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like avoid introduce new constants.
Ok, I'll think about it.

} else {
0
}
}

/// Get ADC initial code for specified attenuation from efuse
///
/// see https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_rtc_calib.c#L27
pub fn get_rtc_calib_init_code(_unit: u8, atten: Attenuation) -> Option<u16> {
let version = Self::get_rtc_calib_version();

if version != 1 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 1 needs to be the same constant as above, I think.

return None;
}

// see https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_table.csv#L94
let diff_code0: u16 = Self::read_field_le(ADC1_INIT_CODE_ATTEN0);
let code0 = if diff_code0 & (1 << 7) != 0 {
2160 - (diff_code0 & 0x7f)
} else {
2160 + diff_code0
};

if matches!(atten, Attenuation::Attenuation0dB) {
return Some(code0);
}

// see https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_table.csv#L95
let diff_code11: u16 = Self::read_field_le(ADC1_INIT_CODE_ATTEN3);
let code11 = code0 + diff_code11;

Some(code11)
}

/// Get ADC reference point voltage for specified attenuation in millivolts
///
/// see https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_rtc_calib.c#L65
pub fn get_rtc_calib_cal_mv(_unit: u8, atten: Attenuation) -> u16 {
match atten {
Attenuation::Attenuation0dB => 400,
Attenuation::Attenuation11dB => 1370,
}
}

/// Get ADC reference point digital code for specified attenuation
///
/// see https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_rtc_calib.c#L65
pub fn get_rtc_calib_cal_code(_unit: u8, atten: Attenuation) -> Option<u16> {
let version = Self::get_rtc_calib_version();

if version != 1 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version here should also be replaced by a const

return None;
}

// see https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_table.csv#L96
let diff_code0: u16 = Self::read_field_le(ADC1_CAL_VOL_ATTEN0);
let code0 = if diff_code0 & (1 << 7) != 0 {
1540 - (diff_code0 & 0x7f)
} else {
1540 + diff_code0
};

if matches!(atten, Attenuation::Attenuation0dB) {
return Some(code0);
}

// see https://github.com/espressif/esp-idf/blob/903af13e8/components/efuse/esp32c2/esp_efuse_table.csv#L97
let diff_code11: u16 = Self::read_field_le(ADC1_CAL_VOL_ATTEN3);
let code11 = if diff_code0 & (1 << 5) != 0 {
code0 - (diff_code11 & 0x1f)
} else {
code0 + diff_code11
} - 123;

Some(code11)
}
}

#[derive(Copy, Clone)]
Expand Down