We differentiate between read-only, write-only and read-write registers. According to the "type" of register the API exposes different operations: read or write or both + update (read-modify-write).
One can't directly write a u8/u16/u32 into a register. Instead one must deal with a wrapper (basically, a constructor) that restricts what parts of the register can be modified. For example, one can't set/clear "reserved" bits.
Setting/clearing bits is done via a fn(bool) function whose name matches the name of bit as per the device documentation.
We currently expose "instances" of register blocks via statics where the address associated to the static is supplied by the linker script magic.
For an example of the use of the current API, check the src/bin folder.
Constraints
The API must be compatible with a SVD -> struct generator (cc #36). IOW, we must be able to generate the associated struct/impls programatically.
I would prefer if using the API didn't require importing a bunch of traits or enums.
Unresolved questions:
Unclear how to set/modify "bit groups" via a setter. We could use a enum per bitflag (this can get clunky, IMO, because it requires importing the enums) or we could just accept a u8/u16/u32 as the value of the bitflag and panic! when an invalid value is passed e.g. you pass 0xFF where a 2-bit value is expected. (NOTE For those who think that panic! is a non-starter: LLVM does a great job at optimizing away the panic! branches when you feed constant/literal inputs to "panicky" functions)
How to name accessors. Note that $bit is taken by the setter, this could be get_$bit.
Are statics the right way to expose instances of register blocks? Another way could be to use functions like these:
Current design
read
orwrite
or both +update
(read-modify-write).u8
/u16
/u32
into a register. Instead one must deal with a wrapper (basically, a constructor) that restricts what parts of the register can be modified. For example, one can't set/clear "reserved" bits.fn(bool)
function whose name matches the name of bit as per the device documentation.static
s where the address associated to the static is supplied by the linker script magic.For an example of the use of the current API, check the src/bin folder.
Constraints
struct
generator (cc #36). IOW, we must be able to generate the associatedstruct
/impl
s programatically.Unresolved questions:
enum
per bitflag (this can get clunky, IMO, because it requires importing the enums) or we could just accept au8
/u16
/u32
as the value of the bitflag andpanic!
when an invalid value is passed e.g. you pass0xFF
where a 2-bit value is expected. (NOTE For those who think thatpanic!
is a non-starter: LLVM does a great job at optimizing away thepanic!
branches when you feed constant/literal inputs to "panicky" functions)$bit
is taken by the setter, this could beget_$bit
.