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.
