cortex_m/register/
control.rs1#[cfg(cortex_m)]
4use core::arch::asm;
5#[cfg(cortex_m)]
6use core::sync::atomic::{Ordering, compiler_fence};
7use cortex_m_macros::asm_cfg;
8
9#[derive(Clone, Copy, Debug)]
11pub struct Control {
12 bits: u32,
13}
14
15impl Control {
16 #[inline]
18 pub const fn from_bits(bits: u32) -> Self {
19 Self { bits }
20 }
21
22 #[inline]
24 pub const fn bits(self) -> u32 {
25 self.bits
26 }
27
28 #[inline]
30 pub fn npriv(self) -> Npriv {
31 if self.bits & (1 << 0) == (1 << 0) {
32 Npriv::Unprivileged
33 } else {
34 Npriv::Privileged
35 }
36 }
37
38 #[inline]
40 pub fn set_npriv(&mut self, npriv: Npriv) {
41 let mask = 1 << 0;
42 match npriv {
43 Npriv::Unprivileged => self.bits |= mask,
44 Npriv::Privileged => self.bits &= !mask,
45 }
46 }
47
48 #[inline]
50 pub const fn with_npriv(self, npriv: Npriv) -> Self {
51 let mask = 1 << 0;
52 let bits = match npriv {
53 Npriv::Unprivileged => self.bits | mask,
54 Npriv::Privileged => self.bits & !mask,
55 };
56 Self { bits }
57 }
58
59 #[inline]
61 pub fn spsel(self) -> Spsel {
62 if self.bits & (1 << 1) == (1 << 1) {
63 Spsel::Psp
64 } else {
65 Spsel::Msp
66 }
67 }
68
69 #[inline]
71 pub fn set_spsel(&mut self, spsel: Spsel) {
72 let mask = 1 << 1;
73 match spsel {
74 Spsel::Psp => self.bits |= mask,
75 Spsel::Msp => self.bits &= !mask,
76 }
77 }
78
79 #[inline]
81 pub const fn with_spsel(self, spsel: Spsel) -> Self {
82 let mask = 1 << 1;
83 let bits = match spsel {
84 Spsel::Psp => self.bits | mask,
85 Spsel::Msp => self.bits & !mask,
86 };
87 Self { bits }
88 }
89
90 #[inline]
92 pub fn fpca(self) -> Fpca {
93 if self.bits & (1 << 2) == (1 << 2) {
94 Fpca::Active
95 } else {
96 Fpca::NotActive
97 }
98 }
99
100 #[inline]
102 pub fn set_fpca(&mut self, fpca: Fpca) {
103 let mask = 1 << 2;
104 match fpca {
105 Fpca::Active => self.bits |= mask,
106 Fpca::NotActive => self.bits &= !mask,
107 }
108 }
109}
110
111#[derive(Clone, Copy, Debug, Eq, PartialEq)]
113pub enum Npriv {
114 Privileged,
116 Unprivileged,
118}
119
120impl Npriv {
121 #[inline]
123 pub fn is_privileged(self) -> bool {
124 self == Npriv::Privileged
125 }
126
127 #[inline]
129 pub fn is_unprivileged(self) -> bool {
130 self == Npriv::Unprivileged
131 }
132}
133
134#[derive(Clone, Copy, Debug, Eq, PartialEq)]
136pub enum Spsel {
137 Msp,
139 Psp,
141}
142
143impl Spsel {
144 #[inline]
146 pub fn is_msp(self) -> bool {
147 self == Spsel::Msp
148 }
149
150 #[inline]
152 pub fn is_psp(self) -> bool {
153 self == Spsel::Psp
154 }
155}
156
157#[derive(Clone, Copy, Debug, Eq, PartialEq)]
159pub enum Fpca {
160 Active,
162 NotActive,
164}
165
166impl Fpca {
167 #[inline]
169 pub fn is_active(self) -> bool {
170 self == Fpca::Active
171 }
172
173 #[inline]
175 pub fn is_not_active(self) -> bool {
176 self == Fpca::NotActive
177 }
178}
179
180#[inline]
182#[asm_cfg(cortex_m)]
183pub fn read() -> Control {
184 let bits;
185 unsafe { asm!("mrs {}, CONTROL", out(reg) bits, options(nomem, nostack, preserves_flags)) };
186 Control { bits }
187}
188
189#[inline]
191#[asm_cfg(cortex_m)]
192pub unsafe fn write(control: Control) {
193 let control = control.bits();
194
195 unsafe {
198 asm!(
199 "msr CONTROL, {}",
200 "isb",
201 in(reg) control,
202 options(nomem, nostack, preserves_flags),
203 );
204 compiler_fence(Ordering::SeqCst);
205 }
206}