svd-expander
Expands arrays and resolves inheritance chains in CMSIS-SVD specifications.
```rust use svd_expander::DeviceSpec;
fn main() {
let xml = r##"
<peripheral>
<name>GPIOA</name>
<baseAddress>0x40010000</baseAddress>
<registers>
<register>
<name>IDR</name>
<description>Input Data Register</description>
<addressOffset>0x00</addressOffset>
<fields>
<!--
This field is a template that will be expanded
out to 16 input fields named D1 through D16.
-->
<field>
<name>D%s</name>
<bitWidth>1</bitWidth>
<bitOffset>0</bitOffset>
<dim>16</dim>
<dimIndex>1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16</dimIndex>
<dimIncrement>1</dimIncrement>
</field>
</fields>
</register>
</registers>
</peripheral>
<!--
GPIOA will be copied to make GPIOB below, which is identical
except for any overridden properties (just name and
baseAddress in this case).
-->
<peripheral derivedFrom="GPIOA">
<name>GPIOB</name>
<baseAddress>0x40010100</baseAddress>
</peripheral>
</peripherals>
"##;
let device = DeviceSpec::from_xml(xml).unwrap();
// The IDR register on GPIOA has been expanded to 16 fields. asserteq!(16, device.getregister("GPIOA.IDR").unwrap().fields.len());
// Those fields each had their bit offset (location in the register) // incremented appropriately. asserteq!(0, device.getfield("GPIOA.IDR.D1").unwrap().offset); asserteq!(1, device.getfield("GPIOA.IDR.D2").unwrap().offset); // ...etc... asserteq!(9, device.getfield("GPIOA.IDR.D10").unwrap().offset); // ...etc...
// GPIOB also has an IDR register with 16 fields, which was inherited // from GPIOA. asserteq!(16, device.getregister("GPIOB.IDR").unwrap().fields.len());
// GPIOB kept its name and base address when it inherited properties // from GPIOA. asserteq!("GPIOB", device.getperipheral("GPIOB").unwrap().name); asserteq!(0x40010100, device.getperipheral("GPIOB").unwrap().base_address);
} ```
This crate is intended for use in code generators. It is under active development and bug reports and feature requests are welcome.