      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119

    //! Abstractions common to bare metal systems

    #![deny(missing_docs)]
    #![deny(warnings)]
    #![cfg_attr(
        feature = "const-fn",
        feature(const_fn)
    )]
    #![no_std]

    use core::cell::UnsafeCell;

    /// A peripheral
    #[derive(Debug)]
    pub struct Peripheral<T>
    where
        T: 'static,
    {
        address: *mut T,
    }

    impl<T> Peripheral<T> {
        /// Creates a new peripheral
        ///
        /// `address` is the base address of the register block
        #[cfg(feature = "const-fn")]
        pub const unsafe fn new(address: usize) -> Self {
            Peripheral {
                address: address as *mut T,
            }
        }

        /// Creates a new peripheral
        ///
        /// `address` is the base address of the register block
        #[cfg(not(feature = "const-fn"))]
        pub unsafe fn new(address: usize) -> Self {
            Peripheral {
                address: address as *mut T,
            }
        }

        /// Borrows the peripheral for the duration of a critical section
        pub fn borrow<'cs>(&self, _ctxt: &'cs CriticalSection) -> &'cs T {
            unsafe { &*self.get() }
        }

        /// Returns a pointer to the register block
        pub fn get(&self) -> *mut T {
            self.address as *mut T
        }
    }

    /// Critical section token
    ///
    /// Indicates that you are executing code within a critical section
    pub struct CriticalSection {
        _0: (),
    }

    impl CriticalSection {
        /// Creates a critical section token
        ///
        /// This method is meant to be used to create safe abstractions rather than
        /// meant to be directly used in applications.
        pub unsafe fn new() -> Self {
            CriticalSection { _0: () }
        }
    }

    /// A "mutex" based on critical sections
    pub struct Mutex<T> {
        inner: UnsafeCell<T>,
    }

    impl<T> Mutex<T> {
        /// Creates a new mutex
        #[cfg(feature = "const-fn")]
        pub const fn new(value: T) -> Self {
            Mutex {
                inner: UnsafeCell::new(value),
            }
        }

        /// Creates a new mutex
        #[cfg(not(feature = "const-fn"))]
        pub fn new(value: T) -> Self {
            Mutex {
                inner: UnsafeCell::new(value),
            }
        }
    }

    impl<T> Mutex<T> {
        /// Borrows the data for the duration of the critical section
        pub fn borrow<'cs>(&'cs self, _cs: &'cs CriticalSection) -> &'cs T {
            unsafe { &*self.inner.get() }
        }
    }

    /// ``` compile_fail
    /// fn bad(cs: &bare_metal::CriticalSection) -> &u32 {
    ///     let x = bare_metal::Mutex::new(42u32);
    ///     x.borrow(cs)
    /// }
    /// ```
    #[allow(dead_code)]
    const GH_6: () = ();

    /// Interrupt number
    pub unsafe trait Nr {
        /// Returns the number associated with an interrupt
        fn nr(&self) -> u8;
    }

    // NOTE A `Mutex` can be used as a channel so the protected data must be `Send`
    // to prevent sending non-Sendable stuff (e.g. access tokens) across different
    // execution contexts (e.g. interrupts)
    unsafe impl<T> Sync for Mutex<T> where T: Send {}

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g. `str,u8` or `String,struct:Vec,test`)