Macro device_driver::implement_registers[][src]

macro_rules! implement_registers {
    (
        $(#[$register_set_doc:meta])*
        $device_name:ident.$register_set_name:ident<$register_address_type:ty> = {
            $(
                $(#[doc=$register_doc:literal])*
                $(#[generate($($generate_list:tt)*)])?
                $register_name:ident($register_access_specifier:tt, $register_address:tt, $register_size:expr) = $($register_bit_order:ident)? {
                    $(
                        $(#[$field_doc:meta])*
                        $field_name:ident: $field_type:ty $(:$field_bit_order:ident)? $(as $field_convert_type:ty)? = $field_access_specifier:tt $field_bit_range:expr
                    ),* $(,)?
                }
            ),* $(,)?
        }
    ) => { ... };
}

Defines a register interface for a low level device.

Format:

  • AccessSpecifier = WO (write-only) | RO (read-only) | RW (read-write)
  • FieldType = any int type
  • SomeType = any type that implements Into the field can be written and TryFrom if the field can be read
  • RegisterBitOrder = optional (can be left out. default = LSB) or LSB (Least Significant Bit) | MSB (Most Significant Bit) => This follows uses the ordering semantics of bitvec::slice::BitSlice when used with bitvec::field::BitField.
  • FieldBitOrder = optional (can be left out. default = BE) or :LE (Little Endian) | :BE (Big Endian) | :NE (Native Endian) => Specifies how the bits are read. Native Endian specifies that the CPU Architecture decides if it’s LE or BE. This only makes sense to specify for int types that have more than 1 byte.
implement_registers!(
    /// Possible docs for register set
    DeviceName.register_set_name<RegisterAddressType> = {
        /// Possible docs for register
        register_name(AccessSpecifier, register_address, register_size) = {
            /// Possible docs for register field
            field_name: FieldType = AccessSpecifier inclusive_start_bit_index..exclusive_end_bit_index,
            /// This field has a conversion and uses an inclusive range
            field_name: FieldType as SomeType = AccessSpecifier inclusive_start_bit_index..=inclusive_end_bit_index,
            /// This field is read with a specified endianness
            field_name: FieldType:FieldBitOrder = AccessSpecifier inclusive_start_bit_index..exclusive_end_bit_index,
        },
        /// This register is present at multiple addresses and has a specified register bit order
        register_name(AccessSpecifier, [register_address, register_address, register_address], register_size) = RegisterBitOrder {

        },
    }
);

See the examples folder for actual examples