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 120 121 122 123 124 125 126 127 128 129
//! Tock Register Interface //! //! Provides efficient mechanisms to express and use type-checked //! memory mapped registers and bitfields. //! //! ```rust //! # fn main() {} //! //! use tock_registers::registers::{ReadOnly, ReadWrite}; //! use tock_registers::register_bitfields; //! //! // Register maps are specified like this: //! #[repr(C)] //! struct Registers { //! // Control register: read-write //! cr: ReadWrite<u32, Control::Register>, //! // Status register: read-only //! s: ReadOnly<u32, Status::Register>, //! } //! //! // Register fields and definitions look like this: //! register_bitfields![u32, //! // Simpler bitfields are expressed concisely: //! Control [ //! /// Stop the Current Transfer //! STOP 8, //! /// Software Reset //! SWRST 7, //! /// Master Disable //! MDIS 1, //! /// Master Enable //! MEN 0 //! ], //! //! // More complex registers can express subtypes: //! Status [ //! TXCOMPLETE OFFSET(0) NUMBITS(1) [], //! TXINTERRUPT OFFSET(1) NUMBITS(1) [], //! RXCOMPLETE OFFSET(2) NUMBITS(1) [], //! RXINTERRUPT OFFSET(3) NUMBITS(1) [], //! MODE OFFSET(4) NUMBITS(3) [ //! FullDuplex = 0, //! HalfDuplex = 1, //! Loopback = 2, //! Disabled = 3 //! ], //! ERRORCOUNT OFFSET(6) NUMBITS(3) [] //! ] //! ]; //! ``` //! //! Author //! ------ //! - Shane Leonard <shanel@stanford.edu> #![feature(const_fn_trait_bound)] #![no_std] // If we don't build any actual register types, we don't need unsafe // code in this crate #![cfg_attr(not(feature = "register_types"), forbid(unsafe_code))] pub mod fields; pub mod interfaces; pub mod macros; #[cfg(feature = "register_types")] pub mod registers; mod local_register; pub use local_register::LocalRegisterCopy; use core::ops::{BitAnd, BitOr, BitOrAssign, Not, Shl, Shr}; /// Trait representing the base type of registers. /// /// UIntLike defines basic properties of types required to /// read/write/modify a register through its methods and supertrait /// requirements. /// /// It features a range of default implementations for common unsigned /// integer types, such as [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], /// and [`usize`]. pub trait UIntLike: BitAnd<Output = Self> + BitOr<Output = Self> + BitOrAssign + Not<Output = Self> + Eq + Shr<usize, Output = Self> + Shl<usize, Output = Self> + Copy + Clone { /// Return the representation of the value `0` in the implementing /// type. /// /// This can be used to acquire values of the [`UIntLike`] type, /// even in generic implementations. For instance, to get the /// value `1`, one can use `<T as UIntLike>::zero() + 1`. To get /// the largest representable value, use a bitwise negation: `~(<T /// as UIntLike>::zero())`. fn zero() -> Self; } // Helper macro for implementing the UIntLike trait on differrent // types. macro_rules! UIntLike_impl_for { ($type:ty) => { impl UIntLike for $type { fn zero() -> Self { 0 } } }; } UIntLike_impl_for!(u8); UIntLike_impl_for!(u16); UIntLike_impl_for!(u32); UIntLike_impl_for!(u64); UIntLike_impl_for!(u128); UIntLike_impl_for!(usize); /// Descriptive name for each register. pub trait RegisterLongName {} // Useful implementation for when no RegisterLongName is required // (e.g. no fields need to be accessed, just the raw register values) impl RegisterLongName for () {}