Skip to main content

spmi_register

Macro spmi_register 

Source
macro_rules! spmi_register {
    (@map_reg RO, $val:ty, $addr:expr, BE) => { ... };
    (@map_reg RO, $val:ty, $addr:expr, LE) => { ... };
    (@map_reg WO, $val:ty, $addr:expr, BE) => { ... };
    (@map_reg WO, $val:ty, $addr:expr, LE) => { ... };
    (@map_reg RW, $val:ty, $addr:expr, BE) => { ... };
    (@map_reg RW, $val:ty, $addr:expr, LE) => { ... };
    (@byteorder_type u8, $endianness:ident) => { ... };
    (@byteorder_type u16, LE) => { ... };
    (@byteorder_type u16, BE) => { ... };
    (@byteorder_type u32, LE) => { ... };
    (@byteorder_type u32, BE) => { ... };
    (@new u8, $endianness:ident, $val:expr) => { ... };
    (@new u16, $endianness:ident, $val:expr) => { ... };
    (@new u32, $endianness:ident, $val:expr) => { ... };
    (@get u8, $endianness:ident, $val:expr) => { ... };
    (@get u16, $endianness:ident, $val:expr) => { ... };
    (@get u32, $endianness:ident, $val:expr) => { ... };
    (
        $name:ident,
        $value_type:ident,
        $addr:expr,
        $mode:ident,
        $endianness:ident,
        {
            $($tail:tt)*
        }
    ) => { ... };
    (
        $name:ident, u8, $addr:expr, $mode:ident, {
            $($tail:tt)*
        }
    ) => { ... };
    (@is_big BE) => { ... };
    (@is_big LE) => { ... };
}
Expand description

Defines a module for accessing a single SPMI hardware register.

This macro generates a public module named $name containing:

  • ADDRESS: A u16 constant for the register address.
  • Value: A struct wrapping the raw register value ($value_type) and providing const-fn accessors for defined fields.
  • Register<'a>: A struct with an asynchronous read and potentially write method to interact with the SPMI device.

§Arguments

  1. $name: The identifier for the generated module.
  2. $value_type:ty: The Rust integer type representing the register’s width (e.g., u8, u16, u32).
  3. $addr:expr: The base address of the register as a u16.
  4. $mode:ident: The access mode, one of RO (Read Only), WO (Write Only), or RW (Read/Write).
  5. $endianness:ident: The endianness of the register. Required for u16 and larger. Can be LE (Little Endian) or BE (Big Endian). For u8 registers, this argument is omitted because endianness is irrelevant for u8 registers.
  6. { ... }: A block defining the fields within the register. Each field definition ends with a semicolon. The following formats are supported within the block:
    • Single-bit field: $vis $field_name $(, $setter_name)? : $bit;

      • $vis: Visibility (e.g., pub).
      • $field_name: The name of the getter method (returns bool).
      • $setter_name: (Optional) The name of the setter method (takes bool, returns Self).
      • $bit_index: The index of the single bit (e.g., 7). Example: pub enable, set_enable: 7;
    • Multi-bit field: $vis $field_name $(, $setter_name)? \ : $msb, $lsb;

      • $vis: Visibility.
      • $field_name: The getter method (returns $value_type).
      • $setter_name: (Optional) The setter method (takes $value_type, returns Self).
      • $msb: The Most Significant Bit index.
      • $lsb: The Least Significant Bit index. Example: pub field_val, set_field_val: 5, 2;
    • Enum field (external type): $vis enum $enum_type, $field_name \ $(, $setter_name)? : $msb, $lsb;

      • $vis: Visibility.
      • $enum_type: The path to an existing enum type (e.g., super::PowerMode). This enum must have a pub const fn \ from_val(val: $value_type) -> Self associated function.
      • $field_name: The getter method (returns $enum_type).
      • $setter_name: (Optional) The setter method (takes $enum_type, returns Self).
      • $msb, $lsb: The bit range. Example: pub enum super::PowerMode, mode, set_mode: 3, 2;
    • In-line Enum field: $vis enum $enum_name { ... }, $field_name \ $(, $setter_name)? : $msb, $lsb;

      • $vis: Visibility.
      • $enum_name: The name for the enum type, defined within the generated module.
      • { ... }: The enum variants and their $value_type values.
      • $field_name: The getter method (returns Result<$enum_name, \ $value_type>).
      • $setter_name: (Optional) The setter method (takes $enum_name, returns Self).
      • $msb, $lsb: The bit range. Example: pub enum InlineMode { A = 0, B = 1 }, \ mode, set_mode: 1, 0;
    • Custom constant: pub const $const_name : $type = $val;

      • Allows defining constants within the generated register module. Example: pub const MAX_VALUE: u8 = 0xFF;

§Examples

// Define a register at address 0x10, 8-bit, Read/Write,
// Little Endian (default)
spmi_register! {
    my_reg, u8, 0x10, RW, {
        // Single bit flag
        pub enable, set_enable: 7;
        // 4-bit field
        pub value, set_value: 3, 0;
        // Inline enum field
        pub enum Status {
            Idle = 0,
            Active = 1,
            Error = 2,
        }, status, set_status: 6, 5;
    }
}

// Define a register at address 0x20, 16-bit, Read Only, Big Endian
spmi_register! {
    status_be_reg, u16, 0x20, RO, BE, {
        pub error_code: 15, 8;
        pub ready: 0;
    }
}