Skip to content
This repository was archived by the owner on Dec 9, 2018. It is now read-only.
This repository was archived by the owner on Dec 9, 2018. It is now read-only.

Settle on an API to manipulate registers #44

@japaric

Description

@japaric

Current design

  • 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.
extern {
    static mut GPIOA: Gpio;
    static mut GPIOB: Gpio;
}

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 Generate register block accessors from SVD files #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:
fn gpioa() -> &'static Gpio {
    unsafe { mem::transmute(0xdeadbeef) }
}

unsafe fn gpioa_mut() -> &'static mut Gpio {
    unsafe { mem::transmute(0xdeadbeef) }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions