volatile_register/lib.rs
1//! Volatile access to memory mapped hardware registers
2//!
3//! # Usage
4//!
5//! ``` no_run
6//! use volatile_register::RW;
7//!
8//! // Create a struct that represents the memory mapped register block
9//! /// Nested Vector Interrupt Controller
10//! #[repr(C)]
11//! pub struct Nvic {
12//! /// Interrupt Set-Enable
13//! pub iser: [RW<u32>; 8],
14//! reserved0: [u32; 24],
15//! /// Interrupt Clear-Enable
16//! pub icer: [RW<u32>; 8],
17//! reserved1: [u32; 24],
18//! // .. more registers ..
19//! }
20//!
21//! // Access the registers by casting the base address of the register block
22//! // to the previously declared `struct`
23//! let nvic = 0xE000_E100 as *const Nvic;
24//! // Unsafe because the compiler can't verify the address is correct
25//! unsafe { (*nvic).iser[0].write(1) }
26//! ```
27
28#![deny(missing_docs)]
29#![no_std]
30
31extern crate vcell;
32
33use vcell::VolatileCell;
34
35/// Read-Only register
36#[repr(transparent)]
37pub struct RO<T>
38 where T: Copy
39{
40 register: VolatileCell<T>,
41}
42
43impl<T> RO<T>
44 where T: Copy
45{
46 /// Reads the value of the register
47 #[inline(always)]
48 pub fn read(&self) -> T {
49 self.register.get()
50 }
51}
52
53/// Read-Write register
54#[repr(transparent)]
55pub struct RW<T>
56 where T: Copy
57{
58 register: VolatileCell<T>,
59}
60
61impl<T> RW<T>
62 where T: Copy
63{
64 /// Performs a read-modify-write operation
65 ///
66 /// NOTE: `unsafe` because writes to a register are side effectful
67 #[inline(always)]
68 pub unsafe fn modify<F>(&self, f: F)
69 where F: FnOnce(T) -> T
70 {
71 self.register.set(f(self.register.get()));
72 }
73
74 /// Reads the value of the register
75 #[inline(always)]
76 pub fn read(&self) -> T {
77 self.register.get()
78 }
79
80 /// Writes a `value` into the register
81 ///
82 /// NOTE: `unsafe` because writes to a register are side effectful
83 #[inline(always)]
84 pub unsafe fn write(&self, value: T) {
85 self.register.set(value)
86 }
87}
88
89/// Write-Only register
90#[repr(transparent)]
91pub struct WO<T>
92 where T: Copy
93{
94 register: VolatileCell<T>,
95}
96
97impl<T> WO<T>
98 where T: Copy
99{
100 /// Writes `value` into the register
101 ///
102 /// NOTE: `unsafe` because writes to a register are side effectful
103 #[inline(always)]
104 pub unsafe fn write(&self, value: T) {
105 self.register.set(value)
106 }
107}