mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-30 05:40:39 +00:00
Reorganize efuse code (#3868)
This commit is contained in:
parent
b2c31a1dac
commit
82100314c5
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#![allow(clippy::empty_docs)]
|
#![allow(clippy::empty_docs)]
|
||||||
|
|
||||||
use super::EfuseField;
|
use crate::efuse::EfuseField;
|
||||||
|
|
||||||
/// Efuse write disable mask
|
/// Efuse write disable mask
|
||||||
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 16);
|
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 16);
|
@ -1,59 +1,7 @@
|
|||||||
#![cfg_attr(docsrs, procmacros::doc_replace)]
|
use crate::{peripherals::EFUSE, time::Rate};
|
||||||
//! # Reading of eFuses (ESP32)
|
|
||||||
//!
|
|
||||||
//! ## Overview
|
|
||||||
//!
|
|
||||||
//! The `efuse` module provides functionality for reading eFuse data
|
|
||||||
//! from the `ESP32` chip, allowing access to various chip-specific information
|
|
||||||
//! such as:
|
|
||||||
//!
|
|
||||||
//! * MAC address
|
|
||||||
//! * Chip type, revision
|
|
||||||
//! * Core count
|
|
||||||
//! * Max CPU frequency
|
|
||||||
//!
|
|
||||||
//! and more. It is useful for retrieving chip-specific configuration and
|
|
||||||
//! identification data during runtime.
|
|
||||||
//!
|
|
||||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
|
||||||
//! reading various eFuse fields and values.
|
|
||||||
//!
|
|
||||||
//! ## Examples
|
|
||||||
//!
|
|
||||||
//! ### Read data from the eFuse storage.
|
|
||||||
//!
|
|
||||||
//! ```rust, no_run
|
|
||||||
//! # {before_snippet}
|
|
||||||
//! # use esp_hal::efuse::Efuse;
|
|
||||||
//!
|
|
||||||
//! let mac_address = Efuse::read_base_mac_address();
|
|
||||||
//!
|
|
||||||
//! println!(
|
|
||||||
//! "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]
|
|
||||||
//! );
|
|
||||||
//!
|
|
||||||
//! println!("MAC address {:02x?}", Efuse::mac_address());
|
|
||||||
//! println!("Flash Encryption {:?}", Efuse::flash_encryption());
|
|
||||||
//! println!("Core Count {}", Efuse::core_count());
|
|
||||||
//! println!("Bluetooth enabled {}", Efuse::is_bluetooth_enabled());
|
|
||||||
//! println!("Chip type {:?}", Efuse::chip_type());
|
|
||||||
//! println!("Max CPU clock {:?}", Efuse::max_cpu_frequency());
|
|
||||||
//! # {after_snippet}
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
pub use self::fields::*;
|
|
||||||
use crate::{peripherals::EFUSE, soc::efuse_field::EfuseField, time::Rate};
|
|
||||||
|
|
||||||
mod fields;
|
mod fields;
|
||||||
|
pub use fields::*;
|
||||||
/// A struct representing the eFuse functionality of the chip.
|
|
||||||
pub struct Efuse;
|
|
||||||
|
|
||||||
/// Representing different types of ESP32 chips.
|
/// Representing different types of ESP32 chips.
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
@ -74,7 +22,7 @@ pub enum ChipType {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Efuse {
|
impl super::Efuse {
|
||||||
/// Returns the number of CPUs available on the chip.
|
/// Returns the number of CPUs available on the chip.
|
||||||
///
|
///
|
||||||
/// While ESP32 chips usually come with two mostly equivalent CPUs (protocol
|
/// While ESP32 chips usually come with two mostly equivalent CPUs (protocol
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#![allow(clippy::empty_docs)]
|
#![allow(clippy::empty_docs)]
|
||||||
|
|
||||||
use super::EfuseField;
|
use crate::efuse::EfuseField;
|
||||||
|
|
||||||
/// Disable programming of individual eFuses
|
/// Disable programming of individual eFuses
|
||||||
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 8);
|
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 8);
|
@ -1,54 +1,9 @@
|
|||||||
#![cfg_attr(docsrs, procmacros::doc_replace)]
|
use crate::{analog::adc::Attenuation, peripherals::EFUSE};
|
||||||
//! # Reading of eFuses (ESP32-C2)
|
|
||||||
//!
|
|
||||||
//! ## Overview
|
|
||||||
//! The `efuse` module provides functionality for reading eFuse data
|
|
||||||
//! from the `ESP32-C2` chip, allowing access to various chip-specific
|
|
||||||
//! information such as:
|
|
||||||
//!
|
|
||||||
//! * MAC address
|
|
||||||
//! * ADC calibration information
|
|
||||||
//!
|
|
||||||
//! and more. It is useful for retrieving chip-specific configuration and
|
|
||||||
//! identification data during runtime.
|
|
||||||
//!
|
|
||||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
|
||||||
//! reading various eFuse fields and values.
|
|
||||||
//!
|
|
||||||
//! ## Examples
|
|
||||||
//!
|
|
||||||
//! ### Read data from the eFuse storage.
|
|
||||||
//!
|
|
||||||
//! ```rust, no_run
|
|
||||||
//! # {before_snippet}
|
|
||||||
//! # use esp_hal::efuse::Efuse;
|
|
||||||
//!
|
|
||||||
//! let mac_address = Efuse::read_base_mac_address();
|
|
||||||
//!
|
|
||||||
//! println!(
|
|
||||||
//! "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]
|
|
||||||
//! );
|
|
||||||
//!
|
|
||||||
//! println!("MAC address {:02x?}", Efuse::mac_address());
|
|
||||||
//! println!("Flash Encryption {:?}", Efuse::flash_encryption());
|
|
||||||
//! # {after_snippet}
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
pub use self::fields::*;
|
|
||||||
use crate::{analog::adc::Attenuation, peripherals::EFUSE, soc::efuse_field::EfuseField};
|
|
||||||
|
|
||||||
mod fields;
|
mod fields;
|
||||||
|
pub use fields::*;
|
||||||
|
|
||||||
/// A struct representing the eFuse functionality of the chip.
|
impl super::Efuse {
|
||||||
pub struct Efuse;
|
|
||||||
|
|
||||||
impl Efuse {
|
|
||||||
/// Get status of SPI boot encryption.
|
/// Get status of SPI boot encryption.
|
||||||
pub fn flash_encryption() -> bool {
|
pub fn flash_encryption() -> bool {
|
||||||
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#![allow(clippy::empty_docs)]
|
#![allow(clippy::empty_docs)]
|
||||||
|
|
||||||
use super::EfuseField;
|
use crate::efuse::EfuseField;
|
||||||
|
|
||||||
/// Disable programming of individual eFuses
|
/// Disable programming of individual eFuses
|
||||||
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
@ -1,55 +1,9 @@
|
|||||||
#![cfg_attr(docsrs, procmacros::doc_replace)]
|
use crate::{analog::adc::Attenuation, peripherals::EFUSE};
|
||||||
//! # Reading of eFuses (ESP32-C3)
|
|
||||||
//!
|
|
||||||
//! ## Overview
|
|
||||||
//!
|
|
||||||
//! The `efuse` module provides functionality for reading eFuse data
|
|
||||||
//! from the `ESP32-C3` chip, allowing access to various chip-specific
|
|
||||||
//! information such as:
|
|
||||||
//!
|
|
||||||
//! * MAC address
|
|
||||||
//! * ADC calibration data
|
|
||||||
//!
|
|
||||||
//! and more. It is useful for retrieving chip-specific configuration and
|
|
||||||
//! identification data during runtime.
|
|
||||||
//!
|
|
||||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
|
||||||
//! reading various eFuse fields and values.
|
|
||||||
//!
|
|
||||||
//! ## Examples
|
|
||||||
//!
|
|
||||||
//! ### Read data from the eFuse storage.
|
|
||||||
//!
|
|
||||||
//! ```rust, no_run
|
|
||||||
//! # {before_snippet}
|
|
||||||
//! # use esp_hal::efuse::Efuse;
|
|
||||||
//!
|
|
||||||
//! let mac_address = Efuse::read_base_mac_address();
|
|
||||||
//!
|
|
||||||
//! println!(
|
|
||||||
//! "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]
|
|
||||||
//! );
|
|
||||||
//!
|
|
||||||
//! println!("MAC address {:02x?}", Efuse::mac_address());
|
|
||||||
//! println!("Flash Encryption {:?}", Efuse::flash_encryption());
|
|
||||||
//! # {after_snippet}
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
pub use self::fields::*;
|
|
||||||
use crate::{analog::adc::Attenuation, peripherals::EFUSE, soc::efuse_field::EfuseField};
|
|
||||||
|
|
||||||
mod fields;
|
mod fields;
|
||||||
|
pub use fields::*;
|
||||||
|
|
||||||
/// A struct representing the eFuse functionality of the chip.
|
impl super::Efuse {
|
||||||
pub struct Efuse;
|
|
||||||
|
|
||||||
impl Efuse {
|
|
||||||
/// Get status of SPI boot encryption.
|
/// Get status of SPI boot encryption.
|
||||||
pub fn flash_encryption() -> bool {
|
pub fn flash_encryption() -> bool {
|
||||||
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#![allow(clippy::empty_docs)]
|
#![allow(clippy::empty_docs)]
|
||||||
|
|
||||||
use super::EfuseField;
|
use crate::efuse::EfuseField;
|
||||||
|
|
||||||
/// Disable programming of individual eFuses
|
/// Disable programming of individual eFuses
|
||||||
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
@ -1,55 +1,9 @@
|
|||||||
#![cfg_attr(docsrs, procmacros::doc_replace)]
|
use crate::{analog::adc::Attenuation, peripherals::EFUSE};
|
||||||
//! # Reading of eFuses (ESP32-C6)
|
|
||||||
//!
|
|
||||||
//! ## Overview
|
|
||||||
//! The `efuse` module provides functionality for reading eFuse data
|
|
||||||
//! from the `ESP32-C6` chip, allowing access to various chip-specific
|
|
||||||
//! information such as:
|
|
||||||
//!
|
|
||||||
//! * MAC address
|
|
||||||
//! * ADC calibration data
|
|
||||||
//! * Chip version
|
|
||||||
//!
|
|
||||||
//! and more. It is useful for retrieving chip-specific configuration and
|
|
||||||
//! identification data during runtime.
|
|
||||||
//!
|
|
||||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
|
||||||
//! reading various eFuse fields and values.
|
|
||||||
//!
|
|
||||||
//! ## Examples
|
|
||||||
//!
|
|
||||||
//! ### Read data from the eFuse storage.
|
|
||||||
//!
|
|
||||||
//! ```rust, no_run
|
|
||||||
//! # {before_snippet}
|
|
||||||
//! # use esp_hal::efuse::Efuse;
|
|
||||||
//!
|
|
||||||
//! let mac_address = Efuse::read_base_mac_address();
|
|
||||||
//!
|
|
||||||
//! println!(
|
|
||||||
//! "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]
|
|
||||||
//! );
|
|
||||||
//!
|
|
||||||
//! println!("MAC address {:02x?}", Efuse::mac_address());
|
|
||||||
//! println!("Flash Encryption {:?}", Efuse::flash_encryption());
|
|
||||||
//! # {after_snippet}
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
pub use self::fields::*;
|
|
||||||
use crate::{analog::adc::Attenuation, peripherals::EFUSE, soc::efuse_field::EfuseField};
|
|
||||||
|
|
||||||
mod fields;
|
mod fields;
|
||||||
|
pub use fields::*;
|
||||||
|
|
||||||
/// A struct representing the eFuse functionality of the chip.
|
impl super::Efuse {
|
||||||
pub struct Efuse;
|
|
||||||
|
|
||||||
impl Efuse {
|
|
||||||
/// Get status of SPI boot encryption.
|
/// Get status of SPI boot encryption.
|
||||||
pub fn flash_encryption() -> bool {
|
pub fn flash_encryption() -> bool {
|
||||||
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#![allow(clippy::empty_docs)]
|
#![allow(clippy::empty_docs)]
|
||||||
|
|
||||||
use super::EfuseField;
|
use crate::efuse::EfuseField;
|
||||||
|
|
||||||
/// Disable programming of individual eFuses
|
/// Disable programming of individual eFuses
|
||||||
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
@ -1,55 +1,9 @@
|
|||||||
#![cfg_attr(docsrs, procmacros::doc_replace)]
|
use crate::{analog::adc::Attenuation, peripherals::EFUSE};
|
||||||
//! # Reading of eFuses (ESP32-H2)
|
|
||||||
//!
|
|
||||||
//! ## Overview
|
|
||||||
//!
|
|
||||||
//! The `efuse` module provides functionality for reading eFuse data
|
|
||||||
//! from the `ESP32-H2` chip, allowing access to various chip-specific
|
|
||||||
//! information such as:
|
|
||||||
//!
|
|
||||||
//! * MAC address
|
|
||||||
//! * ADC calibration data
|
|
||||||
//!
|
|
||||||
//! and more. It is useful for retrieving chip-specific configuration and
|
|
||||||
//! identification data during runtime.
|
|
||||||
//!
|
|
||||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
|
||||||
//! reading various eFuse fields and values.
|
|
||||||
//!
|
|
||||||
//! ## Examples
|
|
||||||
//!
|
|
||||||
//! ### Read data from the eFuse storage.
|
|
||||||
//!
|
|
||||||
//! ```rust, no_run
|
|
||||||
//! # {before_snippet}
|
|
||||||
//! # use esp_hal::efuse::Efuse;
|
|
||||||
//!
|
|
||||||
//! let mac_address = Efuse::read_base_mac_address();
|
|
||||||
//!
|
|
||||||
//! println!(
|
|
||||||
//! "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]
|
|
||||||
//! );
|
|
||||||
//!
|
|
||||||
//! println!("MAC address {:02x?}", Efuse::mac_address());
|
|
||||||
//! println!("Flash Encryption {:?}", Efuse::flash_encryption());
|
|
||||||
//! # {after_snippet}
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
pub use self::fields::*;
|
|
||||||
use crate::{analog::adc::Attenuation, peripherals::EFUSE, soc::efuse_field::EfuseField};
|
|
||||||
|
|
||||||
mod fields;
|
mod fields;
|
||||||
|
pub use fields::*;
|
||||||
|
|
||||||
/// A struct representing the eFuse functionality of the chip.
|
impl super::Efuse {
|
||||||
pub struct Efuse;
|
|
||||||
|
|
||||||
impl Efuse {
|
|
||||||
/// Get status of SPI boot encryption.
|
/// Get status of SPI boot encryption.
|
||||||
pub fn flash_encryption() -> bool {
|
pub fn flash_encryption() -> bool {
|
||||||
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#![allow(clippy::empty_docs)]
|
#![allow(clippy::empty_docs)]
|
||||||
|
|
||||||
use super::EfuseField;
|
use crate::efuse::EfuseField;
|
||||||
|
|
||||||
/// Disable programming of individual eFuses
|
/// Disable programming of individual eFuses
|
||||||
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
@ -1,57 +1,9 @@
|
|||||||
#![cfg_attr(docsrs, procmacros::doc_replace)]
|
use crate::peripherals::EFUSE;
|
||||||
//! # Reading of eFuses (ESP32-S2)
|
|
||||||
//!
|
|
||||||
//! ## Overview
|
|
||||||
//!
|
|
||||||
//! The `efuse` module provides functionality for reading eFuse data
|
|
||||||
//! from the `ESP32-S2` chip, allowing access to various chip-specific
|
|
||||||
//! information such as:
|
|
||||||
//!
|
|
||||||
//! * MAC address
|
|
||||||
//! * core count
|
|
||||||
//! * CPU frequency
|
|
||||||
//! * chip type
|
|
||||||
//!
|
|
||||||
//! and more. It is useful for retrieving chip-specific configuration and
|
|
||||||
//! identification data during runtime.
|
|
||||||
//!
|
|
||||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
|
||||||
//! reading various eFuse fields and values.
|
|
||||||
//!
|
|
||||||
//! ## Examples
|
|
||||||
//!
|
|
||||||
//! ### Read data from the eFuse storage.
|
|
||||||
//!
|
|
||||||
//! ```rust, no_run
|
|
||||||
//! # {before_snippet}
|
|
||||||
//! # use esp_hal::efuse::Efuse;
|
|
||||||
//!
|
|
||||||
//! let mac_address = Efuse::read_base_mac_address();
|
|
||||||
//!
|
|
||||||
//! println!(
|
|
||||||
//! "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]
|
|
||||||
//! );
|
|
||||||
//!
|
|
||||||
//! println!("MAC address {:02x?}", Efuse::mac_address());
|
|
||||||
//! println!("Flash Encryption {:?}", Efuse::flash_encryption());
|
|
||||||
//! # {after_snippet}
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
pub use self::fields::*;
|
|
||||||
use crate::{peripherals::EFUSE, soc::efuse_field::EfuseField};
|
|
||||||
|
|
||||||
mod fields;
|
mod fields;
|
||||||
|
pub use fields::*;
|
||||||
|
|
||||||
/// A struct representing the eFuse functionality of the chip.
|
impl super::Efuse {
|
||||||
pub struct Efuse;
|
|
||||||
|
|
||||||
impl Efuse {
|
|
||||||
/// Get status of SPI boot encryption.
|
/// Get status of SPI boot encryption.
|
||||||
pub fn flash_encryption() -> bool {
|
pub fn flash_encryption() -> bool {
|
||||||
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#![allow(clippy::empty_docs)]
|
#![allow(clippy::empty_docs)]
|
||||||
|
|
||||||
use super::EfuseField;
|
use crate::efuse::EfuseField;
|
||||||
|
|
||||||
/// Disable programming of individual eFuses
|
/// Disable programming of individual eFuses
|
||||||
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
pub const WR_DIS: EfuseField = EfuseField::new(0, 0, 0, 32);
|
@ -1,55 +1,9 @@
|
|||||||
#![cfg_attr(docsrs, procmacros::doc_replace)]
|
use crate::{analog::adc::Attenuation, peripherals::EFUSE};
|
||||||
//! # Reading of eFuses (ESP32-S3)
|
|
||||||
//!
|
|
||||||
//! ## Overview
|
|
||||||
//!
|
|
||||||
//! The `efuse` module provides functionality for reading eFuse data
|
|
||||||
//! from the `ESP32-S3` chip, allowing access to various chip-specific
|
|
||||||
//! information such as:
|
|
||||||
//!
|
|
||||||
//! * MAC address
|
|
||||||
//! * Chip revision
|
|
||||||
//!
|
|
||||||
//! and more. It is useful for retrieving chip-specific configuration and
|
|
||||||
//! identification data during runtime.
|
|
||||||
//!
|
|
||||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
|
||||||
//! reading various eFuse fields and values.
|
|
||||||
//!
|
|
||||||
//! ## Examples
|
|
||||||
//!
|
|
||||||
//! ### Read data from the eFuse storage.
|
|
||||||
//!
|
|
||||||
//! ```rust, no_run
|
|
||||||
//! # {before_snippet}
|
|
||||||
//! # use esp_hal::efuse::Efuse;
|
|
||||||
//!
|
|
||||||
//! let mac_address = Efuse::read_base_mac_address();
|
|
||||||
//!
|
|
||||||
//! println!(
|
|
||||||
//! "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]
|
|
||||||
//! );
|
|
||||||
//!
|
|
||||||
//! println!("MAC address {:02x?}", Efuse::mac_address());
|
|
||||||
//! println!("Flash Encryption {:?}", Efuse::flash_encryption());
|
|
||||||
//! # {after_snippet}
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
pub use self::fields::*;
|
|
||||||
use crate::{analog::adc::Attenuation, peripherals::EFUSE, soc::efuse_field::EfuseField};
|
|
||||||
|
|
||||||
mod fields;
|
mod fields;
|
||||||
|
pub use fields::*;
|
||||||
|
|
||||||
/// A struct representing the eFuse functionality of the chip.
|
impl super::Efuse {
|
||||||
pub struct Efuse;
|
|
||||||
|
|
||||||
impl Efuse {
|
|
||||||
/// Get status of SPI boot encryption.
|
/// Get status of SPI boot encryption.
|
||||||
pub fn flash_encryption() -> bool {
|
pub fn flash_encryption() -> bool {
|
||||||
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
!Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT)
|
253
esp-hal/src/efuse/mod.rs
Normal file
253
esp-hal/src/efuse/mod.rs
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
#![cfg_attr(docsrs, procmacros::doc_replace)]
|
||||||
|
//! # eFuse (one-time programmable configuration)
|
||||||
|
//!
|
||||||
|
//! ## Overview
|
||||||
|
//!
|
||||||
|
//! The `efuse` module provides functionality for reading eFuse data
|
||||||
|
//! from the chip, allowing access to various chip-specific
|
||||||
|
//! information such as:
|
||||||
|
//!
|
||||||
|
//! * MAC address
|
||||||
|
//! * Chip revision
|
||||||
|
//!
|
||||||
|
//! and more. It is useful for retrieving chip-specific configuration and
|
||||||
|
//! identification data during runtime.
|
||||||
|
//!
|
||||||
|
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
||||||
|
//! reading various eFuse fields and values.
|
||||||
|
//!
|
||||||
|
//! ## Examples
|
||||||
|
//!
|
||||||
|
//! ### Read data from the eFuse storage.
|
||||||
|
//!
|
||||||
|
//! ```rust, no_run
|
||||||
|
//! # {before_snippet}
|
||||||
|
//! use esp_hal::efuse::{Efuse, SECURE_VERSION};
|
||||||
|
//!
|
||||||
|
//! let mac_address = Efuse::read_base_mac_address();
|
||||||
|
//!
|
||||||
|
//! println!(
|
||||||
|
//! "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]
|
||||||
|
//! );
|
||||||
|
//!
|
||||||
|
//! println!("MAC address {:02x?}", Efuse::mac_address());
|
||||||
|
//! println!("Flash Encryption {:?}", Efuse::flash_encryption());
|
||||||
|
//!
|
||||||
|
//! // Besides the helper methods, various eFuse field constants can also be read with a lower-level API:
|
||||||
|
//!
|
||||||
|
//! println!(
|
||||||
|
//! "Secure version {:?}",
|
||||||
|
//! Efuse::read_field_le::<u16>(SECURE_VERSION)
|
||||||
|
//! );
|
||||||
|
//! # {after_snippet}
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use core::{cmp, mem, slice, sync::atomic::Ordering};
|
||||||
|
|
||||||
|
use bytemuck::AnyBitPattern;
|
||||||
|
use portable_atomic::AtomicU8;
|
||||||
|
|
||||||
|
#[cfg_attr(esp32, path = "esp32/mod.rs")]
|
||||||
|
#[cfg_attr(esp32c2, path = "esp32c2/mod.rs")]
|
||||||
|
#[cfg_attr(esp32c3, path = "esp32c3/mod.rs")]
|
||||||
|
#[cfg_attr(esp32c6, path = "esp32c6/mod.rs")]
|
||||||
|
#[cfg_attr(esp32h2, path = "esp32h2/mod.rs")]
|
||||||
|
#[cfg_attr(esp32s2, path = "esp32s2/mod.rs")]
|
||||||
|
#[cfg_attr(esp32s3, path = "esp32s3/mod.rs")]
|
||||||
|
pub(crate) mod implem;
|
||||||
|
|
||||||
|
pub use implem::*;
|
||||||
|
|
||||||
|
/// The bit field for get access to efuse data
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[instability::unstable]
|
||||||
|
pub struct EfuseField {
|
||||||
|
/// The block
|
||||||
|
pub(crate) block: EfuseBlock,
|
||||||
|
/// Word number - this is just informational
|
||||||
|
pub(crate) _word: u32,
|
||||||
|
/// Starting bit in the efuse block
|
||||||
|
pub(crate) bit_start: u32,
|
||||||
|
/// Number of bits
|
||||||
|
pub(crate) bit_count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EfuseField {
|
||||||
|
pub(crate) const fn new(block: u32, word: u32, bit_start: u32, bit_count: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
block: EfuseBlock::from_repr(block).unwrap(),
|
||||||
|
_word: word,
|
||||||
|
bit_start,
|
||||||
|
bit_count,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A struct representing the eFuse functionality of the chip.
|
||||||
|
#[instability::unstable]
|
||||||
|
pub struct Efuse;
|
||||||
|
|
||||||
|
impl Efuse {
|
||||||
|
/// Reads chip's MAC address from the eFuse storage.
|
||||||
|
#[instability::unstable]
|
||||||
|
pub fn read_base_mac_address() -> [u8; 6] {
|
||||||
|
let mut mac_addr = [0u8; 6];
|
||||||
|
|
||||||
|
let mac0 = Self::read_field_le::<[u8; 4]>(crate::efuse::MAC0);
|
||||||
|
let mac1 = Self::read_field_le::<[u8; 2]>(crate::efuse::MAC1);
|
||||||
|
|
||||||
|
// MAC address is stored in big endian, so load the bytes in reverse:
|
||||||
|
mac_addr[0] = mac1[1];
|
||||||
|
mac_addr[1] = mac1[0];
|
||||||
|
mac_addr[2] = mac0[3];
|
||||||
|
mac_addr[3] = mac0[2];
|
||||||
|
mac_addr[4] = mac0[1];
|
||||||
|
mac_addr[5] = mac0[0];
|
||||||
|
|
||||||
|
mac_addr
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read field value in a little-endian order
|
||||||
|
#[inline(always)]
|
||||||
|
#[instability::unstable]
|
||||||
|
pub fn read_field_le<T: AnyBitPattern>(field: EfuseField) -> T {
|
||||||
|
let EfuseField {
|
||||||
|
block,
|
||||||
|
bit_start,
|
||||||
|
bit_count,
|
||||||
|
..
|
||||||
|
} = field;
|
||||||
|
|
||||||
|
// Represent output value as a bytes slice:
|
||||||
|
let mut output = mem::MaybeUninit::<T>::uninit();
|
||||||
|
let mut bytes = unsafe {
|
||||||
|
slice::from_raw_parts_mut(output.as_mut_ptr() as *mut u8, mem::size_of::<T>())
|
||||||
|
};
|
||||||
|
|
||||||
|
let bit_off = bit_start as usize;
|
||||||
|
let bit_end = cmp::min(bit_count as usize, bytes.len() * 8) + bit_off;
|
||||||
|
|
||||||
|
let mut last_word_off = bit_off / 32;
|
||||||
|
let mut last_word = unsafe { block.address().add(last_word_off).read_volatile() };
|
||||||
|
|
||||||
|
let word_bit_off = bit_off % 32;
|
||||||
|
let word_bit_ext = 32 - word_bit_off;
|
||||||
|
|
||||||
|
let mut word_off = last_word_off;
|
||||||
|
for bit_off in (bit_off..bit_end).step_by(32) {
|
||||||
|
if word_off != last_word_off {
|
||||||
|
// Read a new word:
|
||||||
|
last_word_off = word_off;
|
||||||
|
last_word = unsafe { block.address().add(last_word_off).read_volatile() };
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut word = last_word >> word_bit_off;
|
||||||
|
word_off += 1;
|
||||||
|
|
||||||
|
let word_bit_len = cmp::min(bit_end - bit_off, 32);
|
||||||
|
if word_bit_len > word_bit_ext {
|
||||||
|
// Read the next word:
|
||||||
|
last_word_off = word_off;
|
||||||
|
last_word = unsafe { block.address().add(last_word_off).read_volatile() };
|
||||||
|
// Append bits from a beginning of the next word:
|
||||||
|
word |= last_word.wrapping_shl((32 - word_bit_off) as u32);
|
||||||
|
};
|
||||||
|
|
||||||
|
if word_bit_len < 32 {
|
||||||
|
// Mask only needed bits of a word:
|
||||||
|
word &= u32::MAX >> (32 - word_bit_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Represent word as a byte slice:
|
||||||
|
let byte_len = word_bit_len.div_ceil(8);
|
||||||
|
let word_bytes =
|
||||||
|
unsafe { slice::from_raw_parts(&word as *const u32 as *const u8, byte_len) };
|
||||||
|
|
||||||
|
// Copy word bytes to output value bytes:
|
||||||
|
bytes[..byte_len].copy_from_slice(word_bytes);
|
||||||
|
|
||||||
|
// Move read window forward:
|
||||||
|
bytes = &mut bytes[byte_len..];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill untouched bytes with zeros:
|
||||||
|
bytes.fill(0);
|
||||||
|
|
||||||
|
unsafe { output.assume_init() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read bit value.
|
||||||
|
///
|
||||||
|
/// This function panics if the field's bit length is not equal to 1.
|
||||||
|
#[inline(always)]
|
||||||
|
#[instability::unstable]
|
||||||
|
pub fn read_bit(field: EfuseField) -> bool {
|
||||||
|
assert_eq!(field.bit_count, 1);
|
||||||
|
Self::read_field_le::<u8>(field) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the base mac address
|
||||||
|
///
|
||||||
|
/// The new value will be returned by `read_mac_address` instead of the one
|
||||||
|
/// hard-coded in eFuse. This does not persist across device resets.
|
||||||
|
///
|
||||||
|
/// Can only be called once. Returns `Err(SetMacError::AlreadySet)`
|
||||||
|
/// otherwise.
|
||||||
|
#[instability::unstable]
|
||||||
|
pub fn set_mac_address(mac: [u8; 6]) -> Result<(), SetMacError> {
|
||||||
|
if MAC_OVERRIDE_STATE
|
||||||
|
.compare_exchange(0, 1, Ordering::Relaxed, Ordering::Relaxed)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
return Err(SetMacError::AlreadySet);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
MAC_OVERRIDE = mac;
|
||||||
|
}
|
||||||
|
|
||||||
|
MAC_OVERRIDE_STATE.store(2, Ordering::Relaxed);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get base mac address
|
||||||
|
///
|
||||||
|
/// By default this reads the base mac address from eFuse, but it can be
|
||||||
|
/// overridden by `set_mac_address`.
|
||||||
|
#[instability::unstable]
|
||||||
|
pub fn mac_address() -> [u8; 6] {
|
||||||
|
if MAC_OVERRIDE_STATE.load(Ordering::Relaxed) == 2 {
|
||||||
|
unsafe { MAC_OVERRIDE }
|
||||||
|
} else {
|
||||||
|
Self::read_base_mac_address()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indicates the state of setting the mac address
|
||||||
|
// 0 -- unset
|
||||||
|
// 1 -- in the process of being set
|
||||||
|
// 2 -- set
|
||||||
|
//
|
||||||
|
// Values other than 0 indicate that we cannot attempt setting the mac address
|
||||||
|
// again, and values other than 2 indicate that we should read the mac address
|
||||||
|
// from eFuse.
|
||||||
|
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
||||||
|
static MAC_OVERRIDE_STATE: AtomicU8 = AtomicU8::new(0);
|
||||||
|
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
||||||
|
static mut MAC_OVERRIDE: [u8; 6] = [0; 6];
|
||||||
|
|
||||||
|
/// Error indicating issues with setting the MAC address.
|
||||||
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
|
#[instability::unstable]
|
||||||
|
pub enum SetMacError {
|
||||||
|
/// The MAC address has already been set and cannot be changed.
|
||||||
|
AlreadySet,
|
||||||
|
}
|
@ -225,10 +225,6 @@ pub(crate) use peripherals::pac;
|
|||||||
#[cfg_attr(not(feature = "unstable"), doc(hidden))]
|
#[cfg_attr(not(feature = "unstable"), doc(hidden))]
|
||||||
pub use xtensa_lx_rt::{self, xtensa_lx};
|
pub use xtensa_lx_rt::{self, xtensa_lx};
|
||||||
|
|
||||||
#[cfg(soc_has_efuse)]
|
|
||||||
#[instability::unstable]
|
|
||||||
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
|
||||||
pub use self::soc::efuse;
|
|
||||||
#[cfg(lp_core)]
|
#[cfg(lp_core)]
|
||||||
#[instability::unstable]
|
#[instability::unstable]
|
||||||
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
||||||
@ -333,6 +329,7 @@ unstable_module! {
|
|||||||
pub mod otg_fs;
|
pub mod otg_fs;
|
||||||
#[cfg(psram)] // DMA needs some things from here
|
#[cfg(psram)] // DMA needs some things from here
|
||||||
pub mod psram;
|
pub mod psram;
|
||||||
|
pub mod efuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
unstable_driver! {
|
unstable_driver! {
|
||||||
|
@ -18,9 +18,10 @@ use crate::{
|
|||||||
esp32c6_rtc_update_to_xtal_raw,
|
esp32c6_rtc_update_to_xtal_raw,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
efuse::Efuse,
|
||||||
peripherals::TIMG0,
|
peripherals::TIMG0,
|
||||||
rtc_cntl::RtcClock,
|
rtc_cntl::RtcClock,
|
||||||
soc::{efuse::Efuse, regi2c},
|
soc::regi2c,
|
||||||
time::Rate,
|
time::Rate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
use core::{cmp, mem, slice};
|
|
||||||
|
|
||||||
use bytemuck::AnyBitPattern;
|
|
||||||
|
|
||||||
use crate::soc::efuse::{Efuse, EfuseBlock};
|
|
||||||
|
|
||||||
/// The bit field for get access to efuse data
|
|
||||||
#[allow(unused)]
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct EfuseField {
|
|
||||||
/// The block
|
|
||||||
pub(crate) block: EfuseBlock,
|
|
||||||
/// Word number - this is just informational
|
|
||||||
pub(crate) word: u32,
|
|
||||||
/// Starting bit in the efuse block
|
|
||||||
pub(crate) bit_start: u32,
|
|
||||||
/// Number of bits
|
|
||||||
pub(crate) bit_count: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EfuseField {
|
|
||||||
pub(crate) const fn new(block: u32, word: u32, bit_start: u32, bit_count: u32) -> Self {
|
|
||||||
Self {
|
|
||||||
block: EfuseBlock::from_repr(block).unwrap(),
|
|
||||||
word,
|
|
||||||
bit_start,
|
|
||||||
bit_count,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Efuse {
|
|
||||||
/// Reads chip's MAC address from the eFuse storage.
|
|
||||||
pub fn read_base_mac_address() -> [u8; 6] {
|
|
||||||
let mut mac_addr = [0u8; 6];
|
|
||||||
|
|
||||||
let mac0 = Self::read_field_le::<[u8; 4]>(crate::soc::efuse::MAC0);
|
|
||||||
let mac1 = Self::read_field_le::<[u8; 2]>(crate::soc::efuse::MAC1);
|
|
||||||
|
|
||||||
// MAC address is stored in big endian, so load the bytes in reverse:
|
|
||||||
mac_addr[0] = mac1[1];
|
|
||||||
mac_addr[1] = mac1[0];
|
|
||||||
mac_addr[2] = mac0[3];
|
|
||||||
mac_addr[3] = mac0[2];
|
|
||||||
mac_addr[4] = mac0[1];
|
|
||||||
mac_addr[5] = mac0[0];
|
|
||||||
|
|
||||||
mac_addr
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read field value in a little-endian order
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn read_field_le<T: AnyBitPattern>(field: EfuseField) -> T {
|
|
||||||
let EfuseField {
|
|
||||||
block,
|
|
||||||
bit_start,
|
|
||||||
bit_count,
|
|
||||||
..
|
|
||||||
} = field;
|
|
||||||
|
|
||||||
// Represent output value as a bytes slice:
|
|
||||||
let mut output = mem::MaybeUninit::<T>::uninit();
|
|
||||||
let mut bytes = unsafe {
|
|
||||||
slice::from_raw_parts_mut(output.as_mut_ptr() as *mut u8, mem::size_of::<T>())
|
|
||||||
};
|
|
||||||
|
|
||||||
let bit_off = bit_start as usize;
|
|
||||||
let bit_end = cmp::min(bit_count as usize, bytes.len() * 8) + bit_off;
|
|
||||||
|
|
||||||
let mut last_word_off = bit_off / 32;
|
|
||||||
let mut last_word = unsafe { block.address().add(last_word_off).read_volatile() };
|
|
||||||
|
|
||||||
let word_bit_off = bit_off % 32;
|
|
||||||
let word_bit_ext = 32 - word_bit_off;
|
|
||||||
|
|
||||||
let mut word_off = last_word_off;
|
|
||||||
for bit_off in (bit_off..bit_end).step_by(32) {
|
|
||||||
if word_off != last_word_off {
|
|
||||||
// Read a new word:
|
|
||||||
last_word_off = word_off;
|
|
||||||
last_word = unsafe { block.address().add(last_word_off).read_volatile() };
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut word = last_word >> word_bit_off;
|
|
||||||
word_off += 1;
|
|
||||||
|
|
||||||
let word_bit_len = cmp::min(bit_end - bit_off, 32);
|
|
||||||
if word_bit_len > word_bit_ext {
|
|
||||||
// Read the next word:
|
|
||||||
last_word_off = word_off;
|
|
||||||
last_word = unsafe { block.address().add(last_word_off).read_volatile() };
|
|
||||||
// Append bits from a beginning of the next word:
|
|
||||||
word |= last_word.wrapping_shl((32 - word_bit_off) as u32);
|
|
||||||
};
|
|
||||||
|
|
||||||
if word_bit_len < 32 {
|
|
||||||
// Mask only needed bits of a word:
|
|
||||||
word &= u32::MAX >> (32 - word_bit_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Represent word as a byte slice:
|
|
||||||
let byte_len = word_bit_len.div_ceil(8);
|
|
||||||
let word_bytes =
|
|
||||||
unsafe { slice::from_raw_parts(&word as *const u32 as *const u8, byte_len) };
|
|
||||||
|
|
||||||
// Copy word bytes to output value bytes:
|
|
||||||
bytes[..byte_len].copy_from_slice(word_bytes);
|
|
||||||
|
|
||||||
// Move read window forward:
|
|
||||||
bytes = &mut bytes[byte_len..];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill untouched bytes with zeros:
|
|
||||||
bytes.fill(0);
|
|
||||||
|
|
||||||
unsafe { output.assume_init() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read bit value.
|
|
||||||
///
|
|
||||||
/// This function panics if the field's bit length is not equal to 1.
|
|
||||||
#[inline(always)]
|
|
||||||
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
|
||||||
pub fn read_bit(field: EfuseField) -> bool {
|
|
||||||
assert_eq!(field.bit_count, 1);
|
|
||||||
Self::read_field_le::<u8>(field) != 0
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,6 @@
|
|||||||
//! for interacting with various system-related peripherals on `ESP32` chip.
|
//! for interacting with various system-related peripherals on `ESP32` chip.
|
||||||
|
|
||||||
crate::unstable_module! {
|
crate::unstable_module! {
|
||||||
pub mod efuse;
|
|
||||||
pub mod trng;
|
pub mod trng;
|
||||||
}
|
}
|
||||||
pub mod cpu_control;
|
pub mod cpu_control;
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
//! for interacting with various system-related peripherals on `ESP32-C2` chip.
|
//! for interacting with various system-related peripherals on `ESP32-C2` chip.
|
||||||
|
|
||||||
crate::unstable_module! {
|
crate::unstable_module! {
|
||||||
pub mod efuse;
|
|
||||||
pub mod trng;
|
pub mod trng;
|
||||||
}
|
}
|
||||||
pub mod gpio;
|
pub mod gpio;
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
||||||
|
|
||||||
crate::unstable_module! {
|
crate::unstable_module! {
|
||||||
pub mod efuse;
|
|
||||||
pub mod trng;
|
pub mod trng;
|
||||||
}
|
}
|
||||||
pub mod gpio;
|
pub mod gpio;
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
//! * I2S_SCLK: 160_000_000 - I2S clock frequency
|
//! * I2S_SCLK: 160_000_000 - I2S clock frequency
|
||||||
|
|
||||||
crate::unstable_module! {
|
crate::unstable_module! {
|
||||||
pub mod efuse;
|
|
||||||
pub mod lp_core;
|
pub mod lp_core;
|
||||||
pub mod trng;
|
pub mod trng;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
//! * I2S_SCLK: 96_000_000 - I2S clock frequency
|
//! * I2S_SCLK: 96_000_000 - I2S clock frequency
|
||||||
|
|
||||||
crate::unstable_module! {
|
crate::unstable_module! {
|
||||||
pub mod efuse;
|
|
||||||
pub mod trng;
|
pub mod trng;
|
||||||
}
|
}
|
||||||
pub mod gpio;
|
pub mod gpio;
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
||||||
|
|
||||||
crate::unstable_module! {
|
crate::unstable_module! {
|
||||||
pub mod efuse;
|
|
||||||
pub mod trng;
|
pub mod trng;
|
||||||
pub mod ulp_core;
|
pub mod ulp_core;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
||||||
|
|
||||||
crate::unstable_module! {
|
crate::unstable_module! {
|
||||||
pub mod efuse;
|
|
||||||
pub mod trng;
|
pub mod trng;
|
||||||
pub mod ulp_core;
|
pub mod ulp_core;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
|
||||||
use portable_atomic::{AtomicU8, Ordering};
|
|
||||||
|
|
||||||
pub use self::implementation::*;
|
pub use self::implementation::*;
|
||||||
|
|
||||||
#[cfg_attr(esp32, path = "esp32/mod.rs")]
|
#[cfg_attr(esp32, path = "esp32/mod.rs")]
|
||||||
@ -15,68 +13,6 @@ pub use self::implementation::*;
|
|||||||
#[cfg_attr(esp32s3, path = "esp32s3/mod.rs")]
|
#[cfg_attr(esp32s3, path = "esp32s3/mod.rs")]
|
||||||
mod implementation;
|
mod implementation;
|
||||||
|
|
||||||
mod efuse_field;
|
|
||||||
|
|
||||||
// Indicates the state of setting the mac address
|
|
||||||
// 0 -- unset
|
|
||||||
// 1 -- in the process of being set
|
|
||||||
// 2 -- set
|
|
||||||
//
|
|
||||||
// Values other than 0 indicate that we cannot attempt setting the mac address
|
|
||||||
// again, and values other than 2 indicate that we should read the mac address
|
|
||||||
// from eFuse.
|
|
||||||
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
|
||||||
static MAC_OVERRIDE_STATE: AtomicU8 = AtomicU8::new(0);
|
|
||||||
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
|
||||||
static mut MAC_OVERRIDE: [u8; 6] = [0; 6];
|
|
||||||
|
|
||||||
/// Error indicating issues with setting the MAC address.
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
|
||||||
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
|
||||||
pub enum SetMacError {
|
|
||||||
/// The MAC address has already been set and cannot be changed.
|
|
||||||
AlreadySet,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "unstable"), allow(unused))]
|
|
||||||
impl self::efuse::Efuse {
|
|
||||||
/// Set the base mac address
|
|
||||||
///
|
|
||||||
/// The new value will be returned by `read_mac_address` instead of the one
|
|
||||||
/// hard-coded in eFuse. This does not persist across device resets.
|
|
||||||
///
|
|
||||||
/// Can only be called once. Returns `Err(SetMacError::AlreadySet)`
|
|
||||||
/// otherwise.
|
|
||||||
pub fn set_mac_address(mac: [u8; 6]) -> Result<(), SetMacError> {
|
|
||||||
if MAC_OVERRIDE_STATE
|
|
||||||
.compare_exchange(0, 1, Ordering::Relaxed, Ordering::Relaxed)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
return Err(SetMacError::AlreadySet);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
MAC_OVERRIDE = mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
MAC_OVERRIDE_STATE.store(2, Ordering::Relaxed);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get base mac address
|
|
||||||
///
|
|
||||||
/// By default this reads the base mac address from eFuse, but it can be
|
|
||||||
/// overridden by `set_mac_address`.
|
|
||||||
pub fn mac_address() -> [u8; 6] {
|
|
||||||
if MAC_OVERRIDE_STATE.load(Ordering::Relaxed) == 2 {
|
|
||||||
unsafe { MAC_OVERRIDE }
|
|
||||||
} else {
|
|
||||||
Self::read_base_mac_address()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) fn is_valid_ram_address(address: usize) -> bool {
|
pub(crate) fn is_valid_ram_address(address: usize) -> bool {
|
||||||
addr_in_range(address, memory_range!("DRAM"))
|
addr_in_range(address, memory_range!("DRAM"))
|
||||||
|
@ -358,7 +358,7 @@ where
|
|||||||
|
|
||||||
#[cfg(any(esp32c3, esp32s3))]
|
#[cfg(any(esp32c3, esp32s3))]
|
||||||
{
|
{
|
||||||
use crate::soc::efuse::*;
|
use crate::efuse::{Efuse, USB_EXCHG_PINS};
|
||||||
|
|
||||||
// On the esp32c3, and esp32s3 the USB_EXCHG_PINS efuse is bugged and
|
// On the esp32c3, and esp32s3 the USB_EXCHG_PINS efuse is bugged and
|
||||||
// doesn't swap the pullups too, this works around that.
|
// doesn't swap the pullups too, this works around that.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user