So, I've been mulling this over and I'm favoring moving away from the C-like 
struct-pointers for an eventual nim CMSIS-style API. As stated above, nim does 
not support the following C facilities (or correct me if I'm wrong):

  1. marking object fields volatile
  2. marking object fields read-only (`const`)
  3. Anonymous unions inside structs (used a lot in CMSIS headers, turns out)



So, all these would be pain points making CMSIS programming less ergonomic than 
in C, which isn't the point. Surely we can do better by working with the 
language than against it.

So, I've been thinking of a design like each peripheral is an object with each 
register as a field. A register object has a single private member, the raw 
`ptr` to the register memory address. The rest is a whole ton of codegen'd 
templates to get/set either whole registers or bitfields inside registers. 
Quick demo here based on the ARM_Example header I linked in a previous post: 
<https://play.nim-lang.org/#ix=3w83>

Downside: it's a crap ton of templates. Upsides: templates so no codegen if not 
used. No extra cost of a proc call. Automatically uses 
`volatileStore`/`volatileLoad` for register accesses. Can be used to prevent 
writing to a read-only register (ie by not generating a setter template).

I swear, API design has to be the hardest thing in programming. After naming 
things, of course.

Reply via email to