-
Notifications
You must be signed in to change notification settings - Fork 156
enum based API #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enum based API #52
Conversation
To support SVD like this one ``` xml <peripheral> <name>GPIOA</name> .. <registers> <register> <name>MODER</name> .. <fields> <field> <name>MODER15</name> <description>Port x configuration bits (y = 0..15)</description> <bitOffset>30</bitOffset> <bitWidth>2</bitWidth> <access>read-write</access> <enumeratedValues> <name>Moder</name> <usage>read-write</usage> <enumeratedValue> <name>InputMode</name> <description>00: Input (reset state)</description> <value>0</value> </enumeratedValue> <enumeratedValue> <name>OutputMode</name> <description>01: General purpose output mode</description> <value>1</value> </enumeratedValue> <enumeratedValue> <name>AlternateMode</name> <description>10: Alternate function mode</description> <value>2</value> </enumeratedValue> <enumeratedValue> <name>AnalogMode</name> <description>11: Analog mode</description> <value>3</value> </enumeratedValue> </enumeratedValues> </field> <field> <name>MODER14</name> <description>Port x configuration bits (y = 0..15)</description> <bitOffset>28</bitOffset> <bitWidth>2</bitWidth> <enumeratedValues derivedFrom="MODER15"> </enumeratedValues> </field> ``` The derivedFrom value has to match the name of an *field* that's in the same register
I don't really like having to import enums to be able to perform writes to registers, which is a very commond operation. I have in mind a more ergonomic API that would look like this: #![no_main]
#![no_std]
extern crate nrf51822;
use nrf51822::peripheral;
use nrf51822::led::Led;
#[no_mangle]
pub fn main() -> ! {
let timer0 = unsafe { peripheral::timer0_mut() };
timer0.mode.write(|w| w.mode().timer());
timer0.bitmode.write(|w| w.bitmode()._24bit());
// prescaler = 2 ^ 4 = 16
timer0.prescaler.write(|w| w.prescaler(4));
timer0.shorts.modify(|_, w| w.compare0_clear().enabled());
// reset the timer after 1_000_000 ticks
// NOTE clock frequency = 16 MHz
timer0.cc0.write(1_000_000);
// start the timer
timer0.tasks_start.write(1);
let mut on = true;
loop {
if on {
Led.on();
} else {
Led.off();
}
on = !on;
while timer0.events_compare0.read() == 0 {}
timer0.events_compare0.write(0);
}
} When used in the blinky example. Note that no imports are necessary in this case. The variant / value of a bitfield is picked using a method. The read API would remain unchanged in this scenario. I have already prototyped this API "by hand". I'll implement this different API generation and post another PR tomorrow. |
instead of enumerating them from 0 to N
See #53. |
Closing in favor of #53. |
Auto-generated API for reads looks like this:
The
unreachable!()
will get optimized away when compiling in release mode.In the case where a bitfield is e.g. 2 bits wide but the SVD file lists less than 4 values / variants, svd2rust will create hidden reserved variants:
In the above example, the value
0b10
was not listed in the SVD.Auto-generated API for writes looks like this:
The
modify
API remains unchanged.To get an idea of what actually using this API looks like, check this PR.
cc @brandonedens