aboutsummaryrefslogtreecommitdiff
path: root/src/peripheral/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/peripheral/mod.rs')
-rw-r--r--src/peripheral/mod.rs119
1 files changed, 74 insertions, 45 deletions
diff --git a/src/peripheral/mod.rs b/src/peripheral/mod.rs
index 8854830..04fae31 100644
--- a/src/peripheral/mod.rs
+++ b/src/peripheral/mod.rs
@@ -1,5 +1,4 @@
-#![allow(clippy::needless_doctest_main)]
-//! Core peripherals
+//! Core peripherals.
//!
//! # API
//!
@@ -9,41 +8,32 @@
//! the [`Peripherals::take`](struct.Peripherals.html#method.take) method.
//!
//! ``` no_run
-//! use cortex_m::peripheral::Peripherals;
-//!
-//! fn main() {
-//! let mut peripherals = Peripherals::take().unwrap();
-//! peripherals.DWT.enable_cycle_counter();
-//! }
+//! # use cortex_m::peripheral::Peripherals;
+//! let mut peripherals = Peripherals::take().unwrap();
+//! peripherals.DWT.enable_cycle_counter();
//! ```
//!
//! This method can only be successfully called *once* -- this is why the method returns an
//! `Option`. Subsequent calls to the method will result in a `None` value being returned.
//!
-//! ``` no_run
-//! use cortex_m::peripheral::Peripherals;
-//!
-//! fn main() {
-//! let ok = Peripherals::take().unwrap();
-//! let panics = Peripherals::take().unwrap();
-//! }
+//! ``` no_run, should_panic
+//! # use cortex_m::peripheral::Peripherals;
+//! let ok = Peripherals::take().unwrap();
+//! let panics = Peripherals::take().unwrap();
//! ```
//! A part of the peripheral API doesn't require access to a peripheral instance. This part of the
//! API is provided as static methods on the peripheral types. One example is the
//! [`DWT::get_cycle_count`](struct.DWT.html#method.get_cycle_count) method.
//!
//! ``` no_run
-//! use cortex_m::peripheral::{DWT, Peripherals};
-//!
-//! fn main() {
-//! {
-//! let mut peripherals = Peripherals::take().unwrap();
-//! peripherals.DWT.enable_cycle_counter();
-//! } // all the peripheral singletons are destroyed here
+//! # use cortex_m::peripheral::{DWT, Peripherals};
+//! {
+//! let mut peripherals = Peripherals::take().unwrap();
+//! peripherals.DWT.enable_cycle_counter();
+//! } // all the peripheral singletons are destroyed here
//!
-//! // but this method can be called without a DWT instance
-//! let cyccnt = DWT::get_cycle_count();
-//! }
+//! // but this method can be called without a DWT instance
+//! let cyccnt = DWT::get_cycle_count();
//! ```
//!
//! The singleton property can be *unsafely* bypassed using the `ptr` static method which is
@@ -51,17 +41,14 @@
//! safe higher level abstractions.
//!
//! ``` no_run
-//! use cortex_m::peripheral::{DWT, Peripherals};
-//!
-//! fn main() {
-//! {
-//! let mut peripherals = Peripherals::take().unwrap();
-//! peripherals.DWT.enable_cycle_counter();
-//! } // all the peripheral singletons are destroyed here
+//! # use cortex_m::peripheral::{DWT, Peripherals};
+//! {
+//! let mut peripherals = Peripherals::take().unwrap();
+//! peripherals.DWT.enable_cycle_counter();
+//! } // all the peripheral singletons are destroyed here
//!
-//! // actually safe because this is an atomic read with no side effects
-//! let cyccnt = unsafe { (*DWT::ptr()).cyccnt.read() };
-//! }
+//! // actually safe because this is an atomic read with no side effects
+//! let cyccnt = unsafe { (*DWT::ptr()).cyccnt.read() };
//! ```
//!
//! # References
@@ -70,7 +57,6 @@
// TODO stand-alone registers: ICTR, ACTLR and STIR
-
use core::marker::PhantomData;
use core::ops;
@@ -86,10 +72,12 @@ pub mod fpb;
// NOTE(target_arch) is for documentation purposes
#[cfg(any(has_fpu, target_arch = "x86_64"))]
pub mod fpu;
-#[cfg(not(armv6m))]
+#[cfg(all(not(armv6m), not(armv8m_base)))]
pub mod itm;
pub mod mpu;
pub mod nvic;
+#[cfg(armv8m)]
+pub mod sau;
pub mod scb;
pub mod syst;
#[cfg(not(armv6m))]
@@ -103,7 +91,8 @@ mod test;
/// Core peripherals
#[allow(non_snake_case)]
pub struct Peripherals {
- /// Cache and branch predictor maintenance operations (not present on Cortex-M0 variants)
+ /// Cache and branch predictor maintenance operations.
+ /// Not available on Armv6-M.
pub CBP: CBP,
/// CPUID
@@ -115,13 +104,15 @@ pub struct Peripherals {
/// Data Watchpoint and Trace unit
pub DWT: DWT,
- /// Flash Patch and Breakpoint unit (not present on Cortex-M0 variants)
+ /// Flash Patch and Breakpoint unit.
+ /// Not available on Armv6-M.
pub FPB: FPB,
- /// Floating Point Unit (only present on `thumbv7em-none-eabihf`)
+ /// Floating Point Unit.
pub FPU: FPU,
- /// Instrumentation Trace Macrocell (not present on Cortex-M0 variants)
+ /// Instrumentation Trace Macrocell.
+ /// Not available on Armv6-M and Armv8-M Baseline.
pub ITM: ITM,
/// Memory Protection Unit
@@ -130,14 +121,22 @@ pub struct Peripherals {
/// Nested Vector Interrupt Controller
pub NVIC: NVIC,
+ /// Security Attribution Unit
+ pub SAU: SAU,
+
/// System Control Block
pub SCB: SCB,
/// SysTick: System Timer
pub SYST: SYST,
- /// Trace Port Interface Unit (not present on Cortex-M0 variants)
+ /// Trace Port Interface Unit.
+ /// Not available on Armv6-M.
pub TPIU: TPIU,
+
+ // Private field making `Peripherals` non-exhaustive. We don't use `#[non_exhaustive]` so we
+ // can support older Rust versions.
+ _priv: (),
}
// NOTE `no_mangle` is used here to prevent linking different minor versions of this crate as that
@@ -191,6 +190,9 @@ impl Peripherals {
NVIC: NVIC {
_marker: PhantomData,
},
+ SAU: SAU {
+ _marker: PhantomData,
+ },
SCB: SCB {
_marker: PhantomData,
},
@@ -200,6 +202,7 @@ impl Peripherals {
TPIU: TPIU {
_marker: PhantomData,
},
+ _priv: (),
}
}
}
@@ -368,7 +371,7 @@ pub struct ITM {
unsafe impl Send for ITM {}
-#[cfg(not(armv6m))]
+#[cfg(all(not(armv6m), not(armv8m_base)))]
impl ITM {
/// Returns a pointer to the register block
#[inline(always)]
@@ -377,7 +380,7 @@ impl ITM {
}
}
-#[cfg(not(armv6m))]
+#[cfg(all(not(armv6m), not(armv8m_base)))]
impl ops::Deref for ITM {
type Target = self::itm::RegisterBlock;
@@ -387,7 +390,7 @@ impl ops::Deref for ITM {
}
}
-#[cfg(not(armv6m))]
+#[cfg(all(not(armv6m), not(armv8m_base)))]
impl ops::DerefMut for ITM {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
@@ -443,6 +446,32 @@ impl ops::Deref for NVIC {
}
}
+/// Security Attribution Unit
+pub struct SAU {
+ _marker: PhantomData<*const ()>,
+}
+
+unsafe impl Send for SAU {}
+
+#[cfg(armv8m)]
+impl SAU {
+ /// Returns a pointer to the register block
+ #[inline(always)]
+ pub fn ptr() -> *const sau::RegisterBlock {
+ 0xE000_EDD0 as *const _
+ }
+}
+
+#[cfg(armv8m)]
+impl ops::Deref for SAU {
+ type Target = self::sau::RegisterBlock;
+
+ #[inline(always)]
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*Self::ptr() }
+ }
+}
+
/// System Control Block
pub struct SCB {
_marker: PhantomData<*const ()>,