cortex_m/register/primask.rs
1//! Priority mask register
2
3#[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/// All exceptions with configurable priority are ...
10#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11pub enum Primask {
12 /// Active
13 Active,
14 /// Inactive
15 Inactive,
16}
17
18impl Primask {
19 /// All exceptions with configurable priority are active
20 #[inline]
21 pub fn is_active(self) -> bool {
22 self == Primask::Active
23 }
24
25 /// All exceptions with configurable priority are inactive
26 #[inline]
27 pub fn is_inactive(self) -> bool {
28 self == Primask::Inactive
29 }
30}
31
32/// Reads the prioritizable interrupt mask
33#[inline]
34pub fn read() -> Primask {
35 if read_raw() & (1 << 0) == (1 << 0) {
36 Primask::Inactive
37 } else {
38 Primask::Active
39 }
40}
41
42/// Reads the entire PRIMASK register
43/// Note that bits `[31:1]` are reserved and UNK (Unknown)
44#[inline]
45#[asm_cfg(cortex_m)]
46pub fn read_raw() -> u32 {
47 let r: u32;
48 unsafe { asm!("mrs {}, PRIMASK", out(reg) r, options(nomem, nostack, preserves_flags)) };
49 r
50}
51
52/// Writes the entire PRIMASK register
53///
54/// Note that bits `[31:1]` are reserved and SBZP (Should-Be-Zero-or-Preserved)
55///
56/// # Safety
57///
58/// This method is unsafe as other unsafe code may rely on interrupts remaining disabled, for
59/// example during a critical section, and being able to safely re-enable them would lead to
60/// undefined behaviour. Do not call this function in a context where interrupts are expected to
61/// remain disabled -- for example, in the midst of a critical section or `interrupt::free()` call.
62#[inline]
63#[asm_cfg(cortex_m)]
64pub unsafe fn write_raw(r: u32) {
65 // Ensure no preceeding memory accesses are reordered to after interrupts are possibly enabled.
66 compiler_fence(Ordering::SeqCst);
67 unsafe { asm!("msr PRIMASK, {}", in(reg) r, options(nomem, nostack, preserves_flags)) };
68 // Ensure no subsequent memory accesses are reordered to before interrupts are possibly disabled.
69 compiler_fence(Ordering::SeqCst);
70}