Skip to main content

cortex_m/register/
basepri.rs

1//! Base Priority Mask Register
2
3#[cfg(any(armv7m, armv8m))]
4use core::arch::asm;
5#[cfg(any(armv7m, armv8m))]
6use core::sync::atomic::{Ordering, compiler_fence};
7use cortex_m_macros::asm_cfg;
8
9/// Reads the CPU register
10#[inline]
11#[asm_cfg(any(armv7m, armv8m_main))]
12pub fn read() -> u8 {
13    let r;
14    unsafe { asm!("mrs {}, BASEPRI", out(reg) r, options(nomem, nostack, preserves_flags)) };
15    r
16}
17
18/// Writes to the CPU register
19///
20/// Forms a read/write memory barrier for the compiler.
21///
22/// **IMPORTANT** If you are using a Cortex-M7 device with revision r0p1 you MUST enable the
23/// `cm7-r0p1` Cargo feature or this function WILL misbehave.
24#[inline]
25#[asm_cfg(any(armv7m, armv8m_main))]
26pub unsafe fn write(basepri: u8) {
27    // Release before enabling interrupts; acquire after disabling them.
28    // Work around missing asm synchronization effects: rust-lang/rust#144351.
29    compiler_fence(Ordering::Release);
30
31    #[cfg(not(feature = "cm7-r0p1"))]
32    {
33        unsafe {
34            asm!(
35                "msr BASEPRI, {}",
36                "isb",
37                in(reg) basepri,
38                options(nostack, preserves_flags),
39            )
40        };
41    }
42
43    #[cfg(feature = "cm7-r0p1")]
44    {
45        unsafe {
46            asm!(
47                "mrs {1}, PRIMASK",
48                "cpsid i",
49                "tst.w {1}, #1",
50                "msr BASEPRI, {0}",
51                "isb",
52                "it ne",
53                "bxne lr",
54                "cpsie i",
55                in(reg) basepri,
56                out(reg) _,
57                options(nostack, preserves_flags),
58            )
59        };
60    }
61    compiler_fence(Ordering::Acquire);
62}