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 130 131 132 133 134 135 136
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.
//! 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>
#![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;
pub mod debug;
mod local_register;
pub use local_register::LocalRegisterCopy;
use core::fmt::Debug;
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
+ Debug
{
/// 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 () {}