      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

    //! Volatile access to memory mapped hardware registers
    //!
    //! # Usage
    //!
    //! ``` no_run
    //! use volatile_register::RW;
    //!
    //! // Create a struct that represents the memory mapped register block
    //! /// Nested Vector Interrupt Controller
    //! #[repr(C)]
    //! pub struct Nvic {
    //!     /// Interrupt Set-Enable
    //!     pub iser: [RW<u32>; 8],
    //!     reserved0: [u32; 24],
    //!     /// Interrupt Clear-Enable
    //!     pub icer: [RW<u32>; 8],
    //!     reserved1: [u32; 24],
    //!     // .. more registers ..
    //! }
    //!
    //! // Access the registers by casting the base address of the register block
    //! // to the previously declared `struct`
    //! let nvic = 0xE000_E100 as *const Nvic;
    //! // Unsafe because the compiler can't verify the address is correct
    //! unsafe { (*nvic).iser[0].write(1) }
    //! ```

    #![deny(missing_docs)]
    #![no_std]

    extern crate vcell;

    use vcell::VolatileCell;

    /// Read-Only register
    pub struct RO<T>
        where T: Copy
    {
        register: VolatileCell<T>,
    }

    impl<T> RO<T>
        where T: Copy
    {
        /// Reads the value of the register
        #[inline(always)]
        pub fn read(&self) -> T {
            self.register.get()
        }
    }

    /// Read-Write register
    pub struct RW<T>
        where T: Copy
    {
        register: VolatileCell<T>,
    }

    impl<T> RW<T>
        where T: Copy
    {
        /// Performs a read-modify-write operation
        ///
        /// NOTE: `unsafe` because writes to a register are side effectful
        #[inline(always)]
        pub unsafe fn modify<F>(&self, f: F)
            where F: FnOnce(T) -> T
        {
            self.register.set(f(self.register.get()));
        }

        /// Reads the value of the register
        #[inline(always)]
        pub fn read(&self) -> T {
            self.register.get()
        }

        /// Writes a `value` into the register
        ///
        /// NOTE: `unsafe` because writes to a register are side effectful
        #[inline(always)]
        pub unsafe fn write(&self, value: T) {
            self.register.set(value)
        }
    }

    /// Write-Only register
    pub struct WO<T>
        where T: Copy
    {
        register: VolatileCell<T>,
    }

    impl<T> WO<T>
        where T: Copy
    {
        /// Writes `value` into the register
        ///
        /// NOTE: `unsafe` because writes to a register are side effectful
        #[inline(always)]
        pub unsafe fn write(&self, value: T) {
            self.register.set(value)
        }
    }

# 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`)