cortex-m 0.4.3

Low level access to Cortex-M processors
Documentation
//! Control register

/// Control register
#[derive(Clone, Copy, Debug)]
pub struct Control {
    bits: u32,
}

impl Control {
    /// Returns the contents of the register as raw bits
    pub fn bits(&self) -> u32 {
        self.bits
    }

    /// Thread mode privilege level
    pub fn npriv(&self) -> Npriv {
        if self.bits & (1 << 0) == (1 << 0) {
            Npriv::Unprivileged
        } else {
            Npriv::Privileged
        }
    }

    /// Currently active stack pointer
    pub fn spsel(&self) -> Spsel {
        if self.bits & (1 << 1) == (1 << 1) {
            Spsel::Psp
        } else {
            Spsel::Msp
        }
    }

    /// Whether context floating-point is currently active
    pub fn fpca(&self) -> Fpca {
        if self.bits & (1 << 2) == (1 << 2) {
            Fpca::Active
        } else {
            Fpca::NotActive
        }
    }
}

/// Thread mode privilege level
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Npriv {
    /// Privileged
    Privileged,
    /// Unprivileged
    Unprivileged,
}

impl Npriv {
    /// Is in privileged thread mode?
    pub fn is_privileged(&self) -> bool {
        *self == Npriv::Privileged
    }

    /// Is in unprivileged thread mode?
    pub fn is_unprivileged(&self) -> bool {
        *self == Npriv::Unprivileged
    }
}

/// Currently active stack pointer
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Spsel {
    /// MSP is the current stack pointer
    Msp,
    /// PSP is the current stack pointer
    Psp,
}

impl Spsel {
    /// Is MSP the current stack pointer?
    pub fn is_msp(&self) -> bool {
        *self == Spsel::Msp
    }

    /// Is PSP the current stack pointer?
    pub fn is_psp(&self) -> bool {
        *self == Spsel::Psp
    }
}

/// Whether context floating-point is currently active
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Fpca {
    /// Floating-point context active.
    Active,
    /// No floating-point context active
    NotActive,
}

impl Fpca {
    /// Is a floating-point context active?
    pub fn is_active(&self) -> bool {
        *self == Fpca::Active
    }

    /// Is a floating-point context not active?
    pub fn is_not_active(&self) -> bool {
        *self == Fpca::NotActive
    }
}

/// Reads the CPU register
#[inline]
pub fn read() -> Control {
    match () {
        #[cfg(target_arch = "arm")]
        () => {
            let r: u32;
            unsafe { asm!("mrs $0, CONTROL" : "=r"(r) ::: "volatile") }
            Control { bits: r }
        }
        #[cfg(not(target_arch = "arm"))]
        () => unimplemented!(),
    }
}