Reading of some eFuses

This commit is contained in:
bjoernQ 2022-06-17 16:02:21 +02:00 committed by Jesse Braham
parent 3841c09e5d
commit 8a3a0e7cb9
14 changed files with 442 additions and 3 deletions

View File

@ -1,6 +1,6 @@
{
"rust-analyzer.cargo.features": [
"esp32c3"
"esp32"
],
"rust-analyzer.cargo.allFeatures": false,
"editor.formatOnSave": true,
@ -10,12 +10,12 @@
"cargo",
"check",
"--features",
"esp32c3",
"esp32",
"--message-format=json",
"-Z",
"build-std=core",
"--target",
"riscv32imac-unknown-none-elf",
"xtensa-esp32-none-elf",
"--examples",
"--lib",
],

View File

@ -0,0 +1,123 @@
//! Reading of eFuses
//!
use fugit::{HertzU32, RateExtU32};
use crate::pac::EFUSE;
pub struct Efuse;
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum ChipType {
Esp32D0wdq6,
Esp32D0wdq5,
Esp32D2wdq5,
Esp32Picod2,
Esp32Picod4,
Unknown,
}
impl Efuse {
/// Reads chip's MAC address from the eFuse storage.
///
/// # Example
///
/// ```
/// let mac_address = Efuse::get_mac_address();
/// writeln!(
/// serial_tx,
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
/// mac_address[0],
/// mac_address[1],
/// mac_address[2],
/// mac_address[3],
/// mac_address[4],
/// mac_address[5]
/// );
/// ```
pub fn get_mac_address() -> [u8; 6] {
let efuse = unsafe { &*EFUSE::ptr() };
let mac_low: u32 = efuse.blk0_rdata1.read().rd_wifi_mac_crc_low().bits();
let mac_high: u32 = efuse.blk0_rdata2.read().rd_wifi_mac_crc_high().bits();
let mac_low_bytes = mac_low.to_be_bytes();
let mac_high_bytes = mac_high.to_be_bytes();
[
mac_high_bytes[2],
mac_high_bytes[3],
mac_low_bytes[0],
mac_low_bytes[1],
mac_low_bytes[2],
mac_low_bytes[3],
]
}
/// Returns the number of CPUs available on the chip.
///
/// While ESP32 chips usually come with two mostly equivalent CPUs (protocol
/// CPU and application CPU), the application CPU is unavailable on
/// some.
pub fn get_core_count() -> u32 {
let efuse = unsafe { &*EFUSE::ptr() };
let cpu_disabled = efuse.blk0_rdata3.read().rd_chip_ver_dis_app_cpu().bit();
if cpu_disabled {
1
} else {
2
}
}
/// Returns the maximum rated clock of the CPU in MHz.
///
/// Note that the actual clock may be lower, depending on the current power
/// configuration of the chip, clock source, and other settings.
pub fn get_max_cpu_fequency() -> HertzU32 {
let efuse = unsafe { &*EFUSE::ptr() };
let has_rating = efuse.blk0_rdata3.read().rd_chip_cpu_freq_rated().bit();
let has_low_rating = efuse.blk0_rdata3.read().rd_chip_cpu_freq_low().bit();
if has_rating && has_low_rating {
160u32.MHz()
} else {
240u32.MHz()
}
}
/// Returns the CHIP_VER_DIS_BT eFuse value.
pub fn is_bluetooth_enabled() -> bool {
let efuse = unsafe { &*EFUSE::ptr() };
!efuse.blk0_rdata3.read().rd_chip_ver_dis_bt().bit()
}
/// Returns the CHIP_VER_PKG eFuse value.
pub fn get_chip_type() -> ChipType {
let efuse = unsafe { &*EFUSE::ptr() };
match efuse.blk0_rdata3.read().rd_chip_ver_pkg().bits() {
0 => ChipType::Esp32D0wdq6,
1 => ChipType::Esp32D0wdq5,
2 => ChipType::Esp32D2wdq5,
4 => ChipType::Esp32Picod2,
5 => ChipType::Esp32Picod4,
_ => ChipType::Unknown,
}
}
/// Get status of SPI boot encryption.
pub fn get_flash_encryption() -> bool {
let efuse = unsafe { &*EFUSE::ptr() };
(efuse
.blk0_rdata0
.read()
.rd_flash_crypt_cnt()
.bits()
.count_ones()
% 2)
!= 0
}
}

View File

@ -0,0 +1,57 @@
//! Reading of eFuses
//!
use crate::pac::EFUSE;
pub struct Efuse;
impl Efuse {
/// Reads chip's MAC address from the eFuse storage.
///
/// # Example
///
/// ```
/// let mac_address = Efuse::get_mac_address();
/// writeln!(
/// serial_tx,
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
/// mac_address[0],
/// mac_address[1],
/// mac_address[2],
/// mac_address[3],
/// mac_address[4],
/// mac_address[5]
/// );
/// ```
pub fn get_mac_address() -> [u8; 6] {
let efuse = unsafe { &*EFUSE::ptr() };
let mac_low: u32 = efuse.rd_mac_spi_sys_0.read().mac_0().bits();
let mac_high: u32 = efuse.rd_mac_spi_sys_1.read().mac_1().bits() as u32;
let mac_low_bytes = mac_low.to_be_bytes();
let mac_high_bytes = mac_high.to_be_bytes();
[
mac_high_bytes[2],
mac_high_bytes[3],
mac_low_bytes[0],
mac_low_bytes[1],
mac_low_bytes[2],
mac_low_bytes[3],
]
}
/// Get status of SPI boot encryption.
pub fn get_flash_encryption() -> bool {
let efuse = unsafe { &*EFUSE::ptr() };
(efuse
.rd_repeat_data1
.read()
.spi_boot_crypt_cnt()
.bits()
.count_ones()
% 2)
!= 0
}
}

View File

@ -0,0 +1,57 @@
//! Reading of eFuses
//!
use crate::pac::EFUSE;
pub struct Efuse;
impl Efuse {
/// Reads chip's MAC address from the eFuse storage.
///
/// # Example
///
/// ```
/// let mac_address = Efuse::get_mac_address();
/// writeln!(
/// serial_tx,
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
/// mac_address[0],
/// mac_address[1],
/// mac_address[2],
/// mac_address[3],
/// mac_address[4],
/// mac_address[5]
/// );
/// ```
pub fn get_mac_address() -> [u8; 6] {
let efuse = unsafe { &*EFUSE::ptr() };
let mac_low: u32 = efuse.rd_mac_spi_sys_0.read().mac_0().bits();
let mac_high: u32 = efuse.rd_mac_spi_sys_1.read().mac_1().bits() as u32;
let mac_low_bytes = mac_low.to_be_bytes();
let mac_high_bytes = mac_high.to_be_bytes();
[
mac_high_bytes[2],
mac_high_bytes[3],
mac_low_bytes[0],
mac_low_bytes[1],
mac_low_bytes[2],
mac_low_bytes[3],
]
}
/// Get status of SPI boot encryption.
pub fn get_flash_encryption() -> bool {
let efuse = unsafe { &*EFUSE::ptr() };
(efuse
.rd_repeat_data1
.read()
.spi_boot_crypt_cnt()
.bits()
.count_ones()
% 2)
!= 0
}
}

View File

@ -0,0 +1,57 @@
//! Reading of eFuses
//!
use crate::pac::EFUSE;
pub struct Efuse;
impl Efuse {
/// Reads chip's MAC address from the eFuse storage.
///
/// # Example
///
/// ```
/// let mac_address = Efuse::get_mac_address();
/// writeln!(
/// serial_tx,
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
/// mac_address[0],
/// mac_address[1],
/// mac_address[2],
/// mac_address[3],
/// mac_address[4],
/// mac_address[5]
/// );
/// ```
pub fn get_mac_address() -> [u8; 6] {
let efuse = unsafe { &*EFUSE::ptr() };
let mac_low: u32 = efuse.rd_mac_spi_sys_0.read().mac_0().bits();
let mac_high: u32 = efuse.rd_mac_spi_sys_1.read().mac_1().bits() as u32;
let mac_low_bytes = mac_low.to_be_bytes();
let mac_high_bytes = mac_high.to_be_bytes();
[
mac_high_bytes[2],
mac_high_bytes[3],
mac_low_bytes[0],
mac_low_bytes[1],
mac_low_bytes[2],
mac_low_bytes[3],
]
}
/// Get status of SPI boot encryption.
pub fn get_flash_encryption() -> bool {
let efuse = unsafe { &*EFUSE::ptr() };
(efuse
.rd_repeat_data1
.read()
.spi_boot_crypt_cnt()
.bits()
.count_ones()
% 2)
!= 0
}
}

View File

@ -28,6 +28,13 @@ pub use esp32s2_pac as pac;
pub use esp32s3_pac as pac;
pub mod delay;
#[cfg_attr(feature = "esp32", path = "efuse/esp32.rs")]
#[cfg_attr(feature = "esp32c3", path = "efuse/esp32c3.rs")]
#[cfg_attr(feature = "esp32s2", path = "efuse/esp32s2.rs")]
#[cfg_attr(feature = "esp32s3", path = "efuse/esp32s3.rs")]
pub mod efuse;
pub mod gpio;
pub mod i2c;
#[cfg_attr(feature = "risc_v", path = "interrupt/riscv.rs")]

View File

@ -0,0 +1,40 @@
#![no_std]
#![no_main]
use core::fmt::Write;
use esp32_hal::{efuse::Efuse, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer};
use panic_halt as _;
use xtensa_lx_rt::entry;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();
let mut timer0 = Timer::new(peripherals.TIMG0);
let mut serial0 = Serial::new(peripherals.UART0).unwrap();
let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
timer0.disable();
rtc_cntl.set_wdt_global_enable(false);
writeln!(serial0, "MAC address {:02x?}", Efuse::get_mac_address()).unwrap();
writeln!(serial0, "Core Count {}", Efuse::get_core_count()).unwrap();
writeln!(
serial0,
"Bluetooth enabled {}",
Efuse::is_bluetooth_enabled()
)
.unwrap();
writeln!(serial0, "Chip type {:?}", Efuse::get_chip_type()).unwrap();
writeln!(serial0, "Max CPU clock {:?}", Efuse::get_max_cpu_fequency()).unwrap();
writeln!(
serial0,
"Flash Encryption {:?}",
Efuse::get_flash_encryption()
)
.unwrap();
loop {}
}

View File

@ -3,6 +3,7 @@
pub use embedded_hal as ehal;
pub use esp_hal_common::{
clock,
efuse,
gpio as gpio_types,
i2c,
interrupt,

View File

@ -0,0 +1,34 @@
#![no_std]
#![no_main]
use core::fmt::Write;
use esp32c3_hal::{efuse::Efuse, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer};
use panic_halt as _;
use riscv_rt::entry;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();
let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
let mut serial0 = Serial::new(peripherals.UART0).unwrap();
let mut timer0 = Timer::new(peripherals.TIMG0);
let mut timer1 = Timer::new(peripherals.TIMG1);
// Disable watchdog timers
rtc_cntl.set_super_wdt_enable(false);
rtc_cntl.set_wdt_enable(false);
timer0.disable();
timer1.disable();
writeln!(serial0, "MAC address {:02x?}", Efuse::get_mac_address()).unwrap();
writeln!(
serial0,
"Flash Encryption {:?}",
Efuse::get_flash_encryption()
)
.unwrap();
loop {}
}

View File

@ -5,6 +5,7 @@ use core::arch::global_asm;
pub use embedded_hal as ehal;
pub use esp_hal_common::{
clock,
efuse,
gpio as gpio_types,
i2c,
interrupt,

View File

@ -0,0 +1,30 @@
#![no_std]
#![no_main]
use core::fmt::Write;
use esp32s2_hal::{efuse::Efuse, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer};
use panic_halt as _;
use xtensa_lx_rt::entry;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();
let mut timer0 = Timer::new(peripherals.TIMG0);
let mut serial0 = Serial::new(peripherals.UART0).unwrap();
let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
timer0.disable();
rtc_cntl.set_wdt_global_enable(false);
writeln!(serial0, "MAC address {:02x?}", Efuse::get_mac_address()).unwrap();
writeln!(
serial0,
"Flash Encryption {:?}",
Efuse::get_flash_encryption()
)
.unwrap();
loop {}
}

View File

@ -3,6 +3,7 @@
pub use embedded_hal as ehal;
pub use esp_hal_common::{
clock,
efuse,
gpio as gpio_types,
i2c::{self, I2C},
interrupt,

View File

@ -0,0 +1,30 @@
#![no_std]
#![no_main]
use core::fmt::Write;
use esp32s3_hal::{efuse::Efuse, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer};
use panic_halt as _;
use xtensa_lx_rt::entry;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();
let mut timer0 = Timer::new(peripherals.TIMG0);
let mut serial0 = Serial::new(peripherals.UART0).unwrap();
let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
timer0.disable();
rtc_cntl.set_wdt_global_enable(false);
writeln!(serial0, "MAC address {:02x?}", Efuse::get_mac_address()).unwrap();
writeln!(
serial0,
"Flash Encryption {:?}",
Efuse::get_flash_encryption()
)
.unwrap();
loop {}
}

View File

@ -3,6 +3,7 @@
pub use embedded_hal as ehal;
pub use esp_hal_common::{
clock,
efuse,
gpio as gpio_types,
i2c,
interrupt,