Skip to main content

cortex_m/register/
basepri_max.rs

1//! Base Priority Mask Register (conditional write)
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/// Writes to BASEPRI *if*
10///
11/// - `basepri != 0` AND `basepri::read() == 0`, OR
12/// - `basepri != 0` AND `basepri < basepri::read()`
13///
14/// Forms a read/write memory barrier for the compiler.
15///
16/// **IMPORTANT** If you are using a Cortex-M7 device with revision r0p1 you MUST enable the
17/// `cm7-r0p1` Cargo feature or this function WILL misbehave.
18#[inline]
19#[asm_cfg(any(armv7m, armv8m_main))]
20pub fn write(basepri: u8) {
21    #[cfg(not(feature = "cm7-r0p1"))]
22    {
23        unsafe {
24            asm!(
25                "msr BASEPRI_MAX, {}",
26                "isb",
27                in(reg) basepri,
28                options(nostack, preserves_flags)
29            )
30        };
31    }
32
33    #[cfg(feature = "cm7-r0p1")]
34    {
35        unsafe {
36            asm!(
37                "mrs {1}, PRIMASK",
38                "cpsid i",
39                "tst.w {1}, #1",
40                "msr BASEPRI_MAX, {0}",
41                "isb",
42                "it ne",
43                "bxne lr",
44                "cpsie i",
45                in(reg) basepri,
46                out(reg) _,
47                options(nostack, preserves_flags),
48            )
49        };
50    }
51    // Acquire after disabling interrupts. See rust-lang/rust#144351.
52    compiler_fence(Ordering::Acquire);
53}