diff options
Diffstat (limited to 'src/peripheral/mod.rs')
-rw-r--r-- | src/peripheral/mod.rs | 592 |
1 files changed, 0 insertions, 592 deletions
diff --git a/src/peripheral/mod.rs b/src/peripheral/mod.rs deleted file mode 100644 index bf18151..0000000 --- a/src/peripheral/mod.rs +++ /dev/null @@ -1,592 +0,0 @@ -//! Core peripherals. -//! -//! # API -//! -//! To use (most of) the peripheral API first you must get an *instance* of the peripheral. All the -//! core peripherals are modeled as singletons (there can only ever be, at most, one instance of any -//! one of them at any given point in time) and the only way to get an instance of them is through -//! the [`Peripherals::take`](struct.Peripherals.html#method.take) method. -//! -//! ``` no_run -//! # use cortex_m::peripheral::Peripherals; -//! let mut peripherals = Peripherals::take().unwrap(); -//! peripherals.DCB.enable_trace(); -//! ``` -//! -//! 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, 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::cycle_count`](struct.DWT.html#method.cycle_count) method. -//! -//! ``` no_run -//! # use cortex_m::peripheral::{DWT, Peripherals}; -//! { -//! let mut peripherals = Peripherals::take().unwrap(); -//! peripherals.DCB.enable_trace(); -//! 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::cycle_count(); -//! ``` -//! -//! The singleton property can be *unsafely* bypassed using the `ptr` static method which is -//! available on all the peripheral types. This method is a useful building block for implementing -//! safe higher level abstractions. -//! -//! ``` no_run -//! # use cortex_m::peripheral::{DWT, Peripherals}; -//! { -//! let mut peripherals = Peripherals::take().unwrap(); -//! peripherals.DCB.enable_trace(); -//! 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() }; -//! ``` -//! -//! # References -//! -//! - ARMv7-M Architecture Reference Manual (Issue E.b) - Chapter B3 - -use core::marker::PhantomData; -use core::ops; - -#[cfg(cm7)] -pub mod ac; -#[cfg(not(armv6m))] -pub mod cbp; -pub mod cpuid; -pub mod dcb; -pub mod dwt; -#[cfg(not(armv6m))] -pub mod fpb; -// NOTE(native) is for documentation purposes -#[cfg(any(has_fpu, native))] -pub mod fpu; -pub mod icb; -#[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))] -pub mod tpiu; - -#[cfg(test)] -mod test; - -// NOTE the `PhantomData` used in the peripherals proxy is to make them `Send` but *not* `Sync` - -/// Core peripherals -#[allow(non_snake_case)] -#[allow(clippy::manual_non_exhaustive)] -pub struct Peripherals { - /// Cortex-M7 TCM and cache access control. - #[cfg(cm7)] - pub AC: AC, - - /// Cache and branch predictor maintenance operations. - /// Not available on Armv6-M. - pub CBP: CBP, - - /// CPUID - pub CPUID: CPUID, - - /// Debug Control Block - pub DCB: DCB, - - /// Data Watchpoint and Trace unit - pub DWT: DWT, - - /// Flash Patch and Breakpoint unit. - /// Not available on Armv6-M. - pub FPB: FPB, - - /// Floating Point Unit. - pub FPU: FPU, - - /// Implementation Control Block. - /// - /// The name is from the v8-M spec, but the block existed in earlier - /// revisions, without a name. - pub ICB: ICB, - - /// Instrumentation Trace Macrocell. - /// Not available on Armv6-M and Armv8-M Baseline. - pub ITM: ITM, - - /// Memory Protection Unit - pub MPU: MPU, - - /// 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 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 -// would let you `take` the core peripherals more than once (one per minor version) -#[no_mangle] -static CORE_PERIPHERALS: () = (); - -/// Set to `true` when `take` or `steal` was called to make `Peripherals` a singleton. -static mut TAKEN: bool = false; - -impl Peripherals { - /// Returns all the core peripherals *once* - #[inline] - pub fn take() -> Option<Self> { - critical_section::with(|_| { - if unsafe { TAKEN } { - None - } else { - Some(unsafe { Peripherals::steal() }) - } - }) - } - - /// Unchecked version of `Peripherals::take` - #[inline] - pub unsafe fn steal() -> Self { - TAKEN = true; - - Peripherals { - #[cfg(cm7)] - AC: AC { - _marker: PhantomData, - }, - CBP: CBP { - _marker: PhantomData, - }, - CPUID: CPUID { - _marker: PhantomData, - }, - DCB: DCB { - _marker: PhantomData, - }, - DWT: DWT { - _marker: PhantomData, - }, - FPB: FPB { - _marker: PhantomData, - }, - FPU: FPU { - _marker: PhantomData, - }, - ICB: ICB { - _marker: PhantomData, - }, - ITM: ITM { - _marker: PhantomData, - }, - MPU: MPU { - _marker: PhantomData, - }, - NVIC: NVIC { - _marker: PhantomData, - }, - SAU: SAU { - _marker: PhantomData, - }, - SCB: SCB { - _marker: PhantomData, - }, - SYST: SYST { - _marker: PhantomData, - }, - TPIU: TPIU { - _marker: PhantomData, - }, - _priv: (), - } - } -} - -/// Access control -#[cfg(cm7)] -pub struct AC { - _marker: PhantomData<*const ()>, -} - -#[cfg(cm7)] -unsafe impl Send for AC {} - -#[cfg(cm7)] -impl AC { - /// Pointer to the register block - pub const PTR: *const self::ac::RegisterBlock = 0xE000_EF90 as *const _; -} - -/// Cache and branch predictor maintenance operations -#[allow(clippy::upper_case_acronyms)] -pub struct CBP { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for CBP {} - -#[cfg(not(armv6m))] -impl CBP { - #[inline(always)] - pub(crate) const unsafe fn new() -> Self { - CBP { - _marker: PhantomData, - } - } - - /// Pointer to the register block - pub const PTR: *const self::cbp::RegisterBlock = 0xE000_EF50 as *const _; -} - -#[cfg(not(armv6m))] -impl ops::Deref for CBP { - type Target = self::cbp::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// CPUID -#[allow(clippy::upper_case_acronyms)] -pub struct CPUID { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for CPUID {} - -impl CPUID { - /// Pointer to the register block - pub const PTR: *const self::cpuid::RegisterBlock = 0xE000_ED00 as *const _; -} - -impl ops::Deref for CPUID { - type Target = self::cpuid::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// Debug Control Block -#[allow(clippy::upper_case_acronyms)] -pub struct DCB { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for DCB {} - -impl DCB { - /// Pointer to the register block - pub const PTR: *const dcb::RegisterBlock = 0xE000_EDF0 as *const _; -} - -impl ops::Deref for DCB { - type Target = self::dcb::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*DCB::PTR } - } -} - -/// Data Watchpoint and Trace unit -#[allow(clippy::upper_case_acronyms)] -pub struct DWT { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for DWT {} - -impl DWT { - /// Pointer to the register block - pub const PTR: *const dwt::RegisterBlock = 0xE000_1000 as *const _; -} - -impl ops::Deref for DWT { - type Target = self::dwt::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// Flash Patch and Breakpoint unit -#[allow(clippy::upper_case_acronyms)] -pub struct FPB { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for FPB {} - -#[cfg(not(armv6m))] -impl FPB { - /// Pointer to the register block - pub const PTR: *const fpb::RegisterBlock = 0xE000_2000 as *const _; -} - -#[cfg(not(armv6m))] -impl ops::Deref for FPB { - type Target = self::fpb::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// Floating Point Unit -#[allow(clippy::upper_case_acronyms)] -pub struct FPU { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for FPU {} - -#[cfg(any(has_fpu, native))] -impl FPU { - /// Pointer to the register block - pub const PTR: *const fpu::RegisterBlock = 0xE000_EF30 as *const _; -} - -#[cfg(any(has_fpu, native))] -impl ops::Deref for FPU { - type Target = self::fpu::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// Implementation Control Block. -/// -/// This block contains implementation-defined registers like `ictr` and -/// `actlr`. It's called the "implementation control block" in the ARMv8-M -/// standard, but earlier standards contained the registers, just without a -/// name. -#[allow(clippy::upper_case_acronyms)] -pub struct ICB { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for ICB {} - -impl ICB { - /// Pointer to the register block - pub const PTR: *mut icb::RegisterBlock = 0xE000_E004 as *mut _; -} - -impl ops::Deref for ICB { - type Target = self::icb::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -impl ops::DerefMut for ICB { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *Self::PTR } - } -} - -/// Instrumentation Trace Macrocell -#[allow(clippy::upper_case_acronyms)] -pub struct ITM { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for ITM {} - -#[cfg(all(not(armv6m), not(armv8m_base)))] -impl ITM { - /// Pointer to the register block - pub const PTR: *mut itm::RegisterBlock = 0xE000_0000 as *mut _; -} - -#[cfg(all(not(armv6m), not(armv8m_base)))] -impl ops::Deref for ITM { - type Target = self::itm::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -#[cfg(all(not(armv6m), not(armv8m_base)))] -impl ops::DerefMut for ITM { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *Self::PTR } - } -} - -/// Memory Protection Unit -#[allow(clippy::upper_case_acronyms)] -pub struct MPU { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for MPU {} - -impl MPU { - /// Pointer to the register block - pub const PTR: *const mpu::RegisterBlock = 0xE000_ED90 as *const _; -} - -impl ops::Deref for MPU { - type Target = self::mpu::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// Nested Vector Interrupt Controller -#[allow(clippy::upper_case_acronyms)] -pub struct NVIC { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for NVIC {} - -impl NVIC { - /// Pointer to the register block - pub const PTR: *const nvic::RegisterBlock = 0xE000_E100 as *const _; -} - -impl ops::Deref for NVIC { - type Target = self::nvic::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// Security Attribution Unit -#[allow(clippy::upper_case_acronyms)] -pub struct SAU { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for SAU {} - -#[cfg(armv8m)] -impl SAU { - /// Pointer to the register block - pub const 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 -#[allow(clippy::upper_case_acronyms)] -pub struct SCB { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for SCB {} - -impl SCB { - /// Pointer to the register block - pub const PTR: *const scb::RegisterBlock = 0xE000_ED04 as *const _; -} - -impl ops::Deref for SCB { - type Target = self::scb::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// SysTick: System Timer -#[allow(clippy::upper_case_acronyms)] -pub struct SYST { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for SYST {} - -impl SYST { - /// Pointer to the register block - pub const PTR: *const syst::RegisterBlock = 0xE000_E010 as *const _; -} - -impl ops::Deref for SYST { - type Target = self::syst::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} - -/// Trace Port Interface Unit -#[allow(clippy::upper_case_acronyms)] -pub struct TPIU { - _marker: PhantomData<*const ()>, -} - -unsafe impl Send for TPIU {} - -#[cfg(not(armv6m))] -impl TPIU { - /// Pointer to the register block - pub const PTR: *const tpiu::RegisterBlock = 0xE004_0000 as *const _; -} - -#[cfg(not(armv6m))] -impl ops::Deref for TPIU { - type Target = self::tpiu::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } -} |