Skip to content
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

make Device match specification #184

Merged
merged 1 commit into from
Jan 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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