[][src]Macro bounded_registers::register

macro_rules! register {
    {
        $(#[$attrs:meta])*
        $name:ident,
        $width:ty,
        $mode:ident,
        Fields [$($fields:tt)*]
    } => { ... };
}

The register! macro generates the code necessary for ergonomic register access and manipulation. It is the crux of this crate. The expected input for the macro is as follows:

  1. The register name.
  2. Its mode, either RO (read only), RW (read write), or WO (write only).
  3. The register's fields, beginning with Fields [, and then a closing ] at the end.

A field constists of its name, its width, and its offset within the register. Optionally, one may also state enum-like key/value pairs for the values of the field, nested within the field declaration with []'s

The code which this macro generates is a tree of nested modules where the root is a module called $register_name. Within $register_name, there will be the register itself, as $register_name::Register, as well as a child module for each field.

Within each field module, one can find the field itself, as $register_name::$field_name::Field, as well as a few helpful aliases and constants.

  • $register_name::$field_name::Read: In order to read a field, an instance of that field must be given to have access to its mask and offset. Read can be used as an argument to get_field so one does not have to construct an arbitrary one when doing a read.
  • $register_name::$field_name::Clear: A field whose value is zero. Passing it to modify will clear that field in the register.
  • $register_name::$field_name::Set: A field whose value is $field_max. Passing it to modify will set that field to its max value in the register. This is useful particularly in the case of single-bit wide fields.
  • $register_name::$field_name::$enum_kvs: constants mapping the enum like field names to values.

An example register and its use is below:

#[macro_use]
extern crate typenum;
#[macro_use]
extern crate bounded_registers;

use typenum::consts::U1;

register! {
    Status,
    u8,
    RW,
    Fields [
        On WIDTH(U1) OFFSET(U0),
        Dead WIDTH(U1) OFFSET(U1),
        Color WIDTH(U3) OFFSET(U2) [
            Red = U1,
            Blue = U2,
            Green = U3,
            Yellow = U4
        ]
    ]
}

fn main() {
    let mut reg = Status::Register::new(0);
    reg.modify(Status::Dead::Field::checked::<U1>());
    assert_eq!(reg.read(), 2);
}