hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
use core::sync::atomic::{AtomicUsize, Ordering};

pub struct Amba {
    pub base_addr: usize,
    pub periph_id: u32,
}

static AMBA_BASE: AtomicUsize = AtomicUsize::new(0);

impl Amba {
    pub fn new(base_addr: usize) -> Self {
        AMBA_BASE.store(base_addr, Ordering::Release);
        let pid = Self::read_periph_id(base_addr);
        Self {
            base_addr,
            periph_id: pid,
        }
    }

    fn read_periph_id(base: usize) -> u32 {
        let p0 = unsafe { core::ptr::read_volatile((base + 0xFE0) as *const u32) } & 0xFF;
        let p1 = unsafe { core::ptr::read_volatile((base + 0xFE4) as *const u32) } & 0xFF;
        let p2 = unsafe { core::ptr::read_volatile((base + 0xFE8) as *const u32) } & 0xFF;
        let p3 = unsafe { core::ptr::read_volatile((base + 0xFEC) as *const u32) } & 0xFF;
        (p3 << 24) | (p2 << 16) | (p1 << 8) | p0
    }

    pub fn read_reg(&self, offset: usize) -> u32 {
        unsafe { core::ptr::read_volatile((self.base_addr + offset) as *const u32) }
    }

    pub fn write_reg(&self, offset: usize, val: u32) {
        unsafe { core::ptr::write_volatile((self.base_addr + offset) as *mut u32, val) }
    }
}