1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
//! Control register
/// Control register
#[derive(Clone, Copy, Debug)]
pub struct Control {
bits: u32,
}
impl Control {
/// Creates a `Control` value from raw bits.
#[inline]
pub fn from_bits(bits: u32) -> Self {
Self { bits }
}
/// Returns the contents of the register as raw bits
#[inline]
pub fn bits(self) -> u32 {
self.bits
}
/// Thread mode privilege level
#[inline]
pub fn npriv(self) -> Npriv {
if self.bits & (1 << 0) == (1 << 0) {
Npriv::Unprivileged
} else {
Npriv::Privileged
}
}
/// Sets the thread mode privilege level value (nPRIV).
#[inline]
pub fn set_npriv(&mut self, npriv: Npriv) {
let mask = 1 << 0;
match npriv {
Npriv::Unprivileged => self.bits |= mask,
Npriv::Privileged => self.bits &= !mask,
}
}
/// Currently active stack pointer
#[inline]
pub fn spsel(self) -> Spsel {
if self.bits & (1 << 1) == (1 << 1) {
Spsel::Psp
} else {
Spsel::Msp
}
}
/// Sets the SPSEL value.
#[inline]
pub fn set_spsel(&mut self, spsel: Spsel) {
let mask = 1 << 1;
match spsel {
Spsel::Psp => self.bits |= mask,
Spsel::Msp => self.bits &= !mask,
}
}
/// Whether context floating-point is currently active
#[inline]
pub fn fpca(self) -> Fpca {
if self.bits & (1 << 2) == (1 << 2) {
Fpca::Active
} else {
Fpca::NotActive
}
}
/// Sets the FPCA value.
#[inline]
pub fn set_fpca(&mut self, fpca: Fpca) {
let mask = 1 << 2;
match fpca {
Fpca::Active => self.bits |= mask,
Fpca::NotActive => self.bits &= !mask,
}
}
}
/// Thread mode privilege level
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Npriv {
/// Privileged
Privileged,
/// Unprivileged
Unprivileged,
}
impl Npriv {
/// Is in privileged thread mode?
#[inline]
pub fn is_privileged(self) -> bool {
self == Npriv::Privileged
}
/// Is in unprivileged thread mode?
#[inline]
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?
#[inline]
pub fn is_msp(self) -> bool {
self == Spsel::Msp
}
/// Is PSP the current stack pointer?
#[inline]
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?
#[inline]
pub fn is_active(self) -> bool {
self == Fpca::Active
}
/// Is a floating-point context not active?
#[inline]
pub fn is_not_active(self) -> bool {
self == Fpca::NotActive
}
}
/// Reads the CPU register
#[inline]
pub fn read() -> Control {
let bits: u32 = call_asm!(__control_r() -> u32);
Control { bits }
}
/// Writes to the CPU register.
#[inline]
pub unsafe fn write(control: Control) {
let control = control.bits();
call_asm!(__control_w(control: u32));
}