This crate provides a procedural macro for effortless definitions of registers in embedded device drivers.
Currently, embedded-registers requires you to use #![feature(generic_arg_infer)].
Attribute macro
Registers are defined by adding #[register(...)] to the definition of a bondrewd bitfield.
As a short reminder, bondrewd is another proc macro that allows you to define a bitfield structure,
which is very handy when dealing with registers, where multiple values are often tightly packed bit-on-bit.
The register attribute macro supports the following arguments:
Adding this attribute to a bondrewd struct Foo will result in two types being defined:
Foowill become the register, essentially a byte array with the correct size that provides getter and setter functions for the individual fields.FooBitfieldwill become the underlying bondrewd bitfield, which may be used to construct a register from scratch, or can be obtained viaFoo::read_allif you want to unpack all values.
This has the advantage that reading a register incurs no additional memory and CPU cost to unpack all values of the bitfield. You only pay for the members you actually access.
Simple Example
This simple example defines the DeviceId register of an MCP9808. It has
the virtual address 0b111 (0x7), uses big endian byte order with the first
member of the struct positioned at the most significant bit, is 2 bytes in size
and is read-only:
use ;
// The register may now be read from an I2C bus using sync or async operations:
# async # where
# I: I2c + ErrorType
#
Complex Example
A more complex example may involve adding your own Bondrewd-capable enums. Have a look at this excerpt of the Configuration register from the MCP9808:
# use ;
use ;
use BitfieldEnum;
#
# async # where
# I: I2c + ErrorType
#