Skip to content

Commit

Permalink
make Device match specification
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Jan 1, 2022
1 parent 8bfae9c commit 69e54fc
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 74 deletions.
56 changes: 36 additions & 20 deletions svd-encoder/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,51 @@ impl Encode for Device {

fn encode(&self) -> Result<Element, EncodeError> {
let mut elem = Element::new("device");
if let Some(v) = &self.vendor {
elem.children.push(new_node("vendor", v.clone()));
}
if let Some(v) = &self.vendor_id {
elem.children.push(new_node("vendorID", v.clone()));
}

elem.children.push(new_node("name", self.name.clone()));

if let Some(v) = &self.version {
elem.children.push(new_node("version", v.clone()));
if let Some(v) = &self.series {
elem.children.push(new_node("series", v.clone()));
}

if let Some(v) = &self.description {
elem.children.push(new_node("description", v.clone()));
elem.children
.push(new_node("version", self.version.clone()));

elem.children
.push(new_node("description", self.description.clone()));

if let Some(v) = &self.license_text {
elem.children.push(new_node("licenseText", v.clone()));
}

if let Some(v) = &self.cpu {
elem.children.push(XMLNode::Element(v.encode()?));
}

if let Some(v) = &self.address_unit_bits {
if let Some(v) = &self.header_system_filename {
elem.children
.push(new_node("addressUnitBits", format!("{}", v)));
.push(new_node("headerSystemFilename", v.clone()));
}

if let Some(v) = &self.width {
elem.children.push(new_node("width", format!("{}", v)));
if let Some(v) = &self.header_definitions_prefix {
elem.children
.push(new_node("header_definitions_prefix", v.clone()));
}

elem.children.push(new_node(
"addressUnitBits",
format!("{}", self.address_unit_bits),
));

elem.children
.push(new_node("width", format!("{}", self.width)));

elem.children
.extend(self.default_register_properties.encode()?);

Expand All @@ -43,20 +65,14 @@ impl Encode for Device {
XMLNode::Element(e)
});

elem.attributes
.insert(String::from("schemaVersion"), self.schema_version.clone());
elem.attributes
.insert(String::from("xmlns:xs"), self.xmlns_xs.clone());
elem.attributes.insert(
String::from("xmlns:xs"),
String::from("http://www.w3.org/2001/XMLSchema-instance"),
String::from("xs:noNamespaceSchemaLocation"),
self.no_namespace_schema_location.clone(),
);
if let Some(schema_version) = &self.schema_version {
elem.attributes
.insert(String::from("schemaVersion"), schema_version.to_string());
}
if let Some(schema_version) = &self.schema_version {
elem.attributes.insert(
String::from("xs:noNamespaceSchemaLocation"),
format!("CMSIS-SVD_Schema_{}.xsd", schema_version.replace(".", "_")),
);
}

Ok(elem)
}
Expand Down
29 changes: 22 additions & 7 deletions svd-parser/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@ impl Parse for Device {
return Err(SVDError::NotExpectedTag("device".to_string()).at(tree.id()));
}

Device::builder()
let mut device = Device::builder()
.vendor(tree.get_child_text_opt("vendor")?)
.vendor_id(tree.get_child_text_opt("vendorID")?)
.name(tree.get_child_text("name")?)
.version(tree.get_child_text_opt("version")?)
.description(tree.get_child_text_opt("description")?)
.series(tree.get_child_text_opt("series")?)
.version(tree.get_child_text("version")?)
.description(tree.get_child_text("description")?)
.license_text(tree.get_child_text_opt("licenseText")?)
.cpu(optional::<Cpu>("cpu", tree, config)?)
.address_unit_bits(optional::<u32>("addressUnitBits", tree, &())?)
.width(optional::<u32>("width", tree, &())?)
.header_system_filename(tree.get_child_text_opt("headerSystemFilename")?)
.header_definitions_prefix(tree.get_child_text_opt("headerDefinitionsPrefix")?)
.address_unit_bits(tree.get_child_u32("addressUnitBits")?)
.width(tree.get_child_u32("width")?)
.default_register_properties(RegisterProperties::parse(tree, config)?)
.peripherals({
let ps: Result<Vec<_>, _> = tree
Expand All @@ -30,8 +36,17 @@ impl Parse for Device {
.map(|t| Peripheral::parse(&t, config))
.collect();
ps?
})
.schema_version(tree.attribute("schemaVersion").map(|s| s.to_string()))
});
if let Some(xmlns_xs) = tree.attribute("xmlns:xs") {
device = device.xmlns_xs(xmlns_xs.to_string());
}
if let Some(location) = tree.attribute("xs:noNamespaceSchemaLocation") {
device = device.no_namespace_schema_location(location.to_string());
}
if let Some(schema_version) = tree.attribute("schemaVersion") {
device = device.schema_version(schema_version.to_string());
}
device
.build(config.validate_level)
.map_err(|e| SVDError::from(e).at(tree.id()))
}
Expand Down
2 changes: 2 additions & 0 deletions svd-rs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

- add missing fields in `Device`, require `version`, `description`, `address_unit_bits` and `width`,
also `schema_version` is required, but skipped during (de)serialization
- merge `register` with `registerinfo` modules same as other `info`s
- `EnumeratedValues.usage()` now return `None` if it is derived, fix bug in usage check
- Use generic `SingleArray` enum for types which can be either collected into SVD arrays or have only one instance
Expand Down
4 changes: 2 additions & 2 deletions svd-rs/src/derive_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl DeriveFrom for ClusterInfo {
impl DeriveFrom for EnumeratedValues {
fn derive_from(&self, other: &Self) -> Self {
let mut derived = self.clone();
derived.usage = derived.usage.or_else(|| other.usage.clone());
derived.usage = derived.usage.or(other.usage);
if derived.values.is_empty() {
derived.values = other.values.clone();
}
Expand Down Expand Up @@ -80,7 +80,7 @@ impl DeriveFrom for RegisterInfo {

impl DeriveFrom for RegisterProperties {
fn derive_from(&self, other: &Self) -> Self {
let mut derived = self.clone();
let mut derived = *self;
derived.size = derived.size.or(other.size);
derived.access = derived.access.or(other.access);
derived.protection = derived.protection.or(other.protection);
Expand Down
Loading

0 comments on commit 69e54fc

Please sign in to comment.