use core::ops::Range;
use portable_atomic::{AtomicU8, Ordering};
pub use self::implementation::*;
#[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")]
mod implementation;
mod efuse_field;
#[cfg(feature = "psram")]
mod psram_common;
#[cfg(feature = "psram")]
static mut MAPPED_PSRAM: MappedPsram = MappedPsram { memory_range: 0..0 };
pub(crate) fn psram_range() -> Range<usize> {
cfg_if::cfg_if! {
if #[cfg(feature = "psram")] {
#[allow(static_mut_refs)]
unsafe { MAPPED_PSRAM.memory_range.clone() }
} else {
0..0
}
}
}
const DRAM: Range<usize> = self::constants::SOC_DRAM_LOW..self::constants::SOC_DRAM_HIGH;
#[cfg(feature = "psram")]
pub struct MappedPsram {
memory_range: Range<usize>,
}
#[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];
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
#[cfg_attr(not(feature = "unstable"), allow(unused))]
pub enum SetMacError {
AlreadySet,
}
#[cfg_attr(not(feature = "unstable"), allow(unused))]
impl self::efuse::Efuse {
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(())
}
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)]
pub(crate) fn is_valid_ram_address(address: usize) -> bool {
addr_in_range(address, DRAM)
}
#[allow(unused)]
pub(crate) fn is_slice_in_dram<T>(slice: &[T]) -> bool {
slice_in_range(slice, DRAM)
}
#[allow(unused)]
pub(crate) fn is_valid_psram_address(address: usize) -> bool {
addr_in_range(address, psram_range())
}
#[allow(unused)]
pub(crate) fn is_slice_in_psram<T>(slice: &[T]) -> bool {
slice_in_range(slice, psram_range())
}
#[allow(unused)]
pub(crate) fn is_valid_memory_address(address: usize) -> bool {
is_valid_ram_address(address) || is_valid_psram_address(address)
}
fn slice_in_range<T>(slice: &[T], range: Range<usize>) -> bool {
let slice = slice.as_ptr_range();
let start = slice.start as usize;
let end = slice.end as usize;
addr_in_range(start, range.clone()) && end <= range.end
}
pub(crate) fn addr_in_range(addr: usize, range: Range<usize>) -> bool {
range.contains(&addr)
}