diff --git a/svd-parser/Cargo.toml b/svd-parser/Cargo.toml index 91317f6..dce25e4 100644 --- a/svd-parser/Cargo.toml +++ b/svd-parser/Cargo.toml @@ -27,7 +27,7 @@ thiserror = "1.0.31" [dev-dependencies] serde_json = { version = "1.0", features = ["preserve_order"] } serde_yaml = "0.8.26" -svd-rs = { version = "0.14.1", path = "../svd-rs", features = ["serde"] } +svd-rs = { version = "0.14.3", path = "../svd-rs", features = ["serde"] } [[example]] name = "svd2json" diff --git a/svd-parser/src/expand.rs b/svd-parser/src/expand.rs index 9dd8c0a..1f400c0 100644 --- a/svd-parser/src/expand.rs +++ b/svd-parser/src/expand.rs @@ -5,8 +5,8 @@ use std::collections::HashMap; use std::fmt; use std::mem::take; use svd_rs::{ - array::names, cluster, field, peripheral, register, BitRange, Cluster, ClusterInfo, DeriveFrom, - Device, EnumeratedValues, Field, Peripheral, Register, RegisterCluster, RegisterProperties, + array::names, cluster, field, peripheral, register, Cluster, ClusterInfo, DeriveFrom, Device, + EnumeratedValues, Field, Peripheral, Register, RegisterCluster, RegisterProperties, }; /// Path to `peripheral` or `cluster` element @@ -319,15 +319,7 @@ fn expand_cluster_array( match c { Cluster::Single(c) => expand_cluster(regs, c), Cluster::Array(info, dim) => { - for c in names(&info, &dim) - .zip(cluster::address_offsets(&info, &dim)) - .map(|(name, address_offset)| { - let mut info = info.clone(); - info.name = name; - info.address_offset = address_offset; - info - }) - { + for c in cluster::expand(&info, &dim) { expand_cluster(regs, c); } } @@ -435,7 +427,7 @@ fn expand_cluster(regs: &mut Vec, c: ClusterInfo) { RegisterCluster::Register(mut r) => { r.name = format!("{}_{}", c.name, r.name); r.address_offset += c.address_offset; - regs.push(RegisterCluster::Register(r)); + regs.push(r.into()); } } } @@ -462,20 +454,10 @@ fn expand_register_array( match r { Register::Single(_) => { - regs.push(RegisterCluster::Register(r)); + regs.push(r.into()); } Register::Array(info, dim) => { - for rx in names(&info, &dim) - .zip(register::address_offsets(&info, &dim)) - .map(|(name, address_offset)| { - let mut info = info.clone(); - info.name = name; - info.address_offset = address_offset; - Register::Single(info) - }) - { - regs.push(RegisterCluster::Register(rx)); - } + regs.extend(register::expand(&info, &dim).map(|r| r.single().into())); } } Ok(()) @@ -506,18 +488,7 @@ fn expand_field( fields.push(f); } Field::Array(info, dim) => { - for fx in - names(&info, &dim) - .zip(field::bit_offsets(&info, &dim)) - .map(|(name, bit_offset)| { - let mut info = info.clone(); - info.name = name; - info.bit_range = BitRange::from_offset_width(bit_offset, info.bit_width()); - Field::Single(info) - }) - { - fields.push(fx); - } + fields.extend(field::expand(&info, &dim).map(Field::Single)); } } @@ -630,17 +601,9 @@ pub fn expand(indevice: &Device) -> Result { device.peripherals.push(p); } Peripheral::Array(info, dim) => { - for px in names(&info, &dim) - .zip(peripheral::base_addresses(&info, &dim)) - .map(|(name, base_address)| { - let mut info = info.clone(); - info.name = name; - info.base_address = base_address; - Peripheral::Single(info) - }) - { - device.peripherals.push(px); - } + device + .peripherals + .extend(peripheral::expand(&info, &dim).map(Peripheral::Single)); } } } diff --git a/svd-parser/src/registercluster.rs b/svd-parser/src/registercluster.rs index 0fbc670..6bf378a 100644 --- a/svd-parser/src/registercluster.rs +++ b/svd-parser/src/registercluster.rs @@ -9,8 +9,8 @@ impl Parse for RegisterCluster { fn parse(tree: &Node, config: &Self::Config) -> Result { match tree.tag_name().name() { - "register" => Register::parse(tree, config).map(RegisterCluster::Register), - "cluster" => Cluster::parse(tree, config).map(RegisterCluster::Cluster), + "register" => Register::parse(tree, config).map(Into::into), + "cluster" => Cluster::parse(tree, config).map(Into::into), _ => Err( SVDError::InvalidRegisterCluster(tree.tag_name().name().to_string()).at(tree.id()), ), diff --git a/svd-rs/CHANGELOG.md b/svd-rs/CHANGELOG.md index 1b239f2..f71e28a 100644 --- a/svd-rs/CHANGELOG.md +++ b/svd-rs/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Add `expand` functions for arrays - Fix `indexes_as_range` ## [v0.14.3] - 2023-04-04 diff --git a/svd-rs/src/cluster.rs b/svd-rs/src/cluster.rs index d1a72ac..f5e8385 100644 --- a/svd-rs/src/cluster.rs +++ b/svd-rs/src/cluster.rs @@ -1,4 +1,5 @@ use super::{ + array::{descriptions, names}, registercluster::{ AllRegistersIter, AllRegistersIterMut, ClusterIter, ClusterIterMut, RegisterIter, RegisterIterMut, @@ -79,6 +80,23 @@ pub fn address_offsets<'a>( (0..dim.dim).map(move |i| info.address_offset + i * dim.dim_increment) } +/// Extract `ClusterInfo` items from array +pub fn expand<'a>( + info: &'a ClusterInfo, + dim: &'a DimElement, +) -> impl Iterator + 'a { + names(info, dim) + .zip(descriptions(info, dim)) + .zip(address_offsets(info, dim)) + .map(|((name, description), address_offset)| { + let mut info = info.clone(); + info.name = name; + info.description = description; + info.address_offset = address_offset; + info + }) +} + /// Builder for [`ClusterInfo`] #[derive(Clone, Debug, Default, PartialEq)] pub struct ClusterInfoBuilder { diff --git a/svd-rs/src/field.rs b/svd-rs/src/field.rs index ab0025c..55e68c5 100644 --- a/svd-rs/src/field.rs +++ b/svd-rs/src/field.rs @@ -1,4 +1,5 @@ use super::{ + array::{descriptions, names}, bitrange, Access, BitRange, BuildError, Description, DimElement, EmptyToNone, EnumeratedValues, MaybeArray, ModifiedWriteValues, Name, ReadAction, SvdError, Usage, ValidateLevel, WriteConstraint, @@ -84,7 +85,24 @@ pub struct FieldInfo { /// Return iterator over bit offsets of each field in array pub fn bit_offsets<'a>(info: &'a FieldInfo, dim: &'a DimElement) -> impl Iterator + 'a { - (0..dim.dim).map(move |i| info.bit_offset() + i * dim.dim_increment) + (0..dim.dim).map(|i| info.bit_offset() + i * dim.dim_increment) +} + +/// Extract `FieldInfo` items from array +pub fn expand<'a>( + info: &'a FieldInfo, + dim: &'a DimElement, +) -> impl Iterator + 'a { + names(info, dim) + .zip(descriptions(info, dim)) + .zip(bit_offsets(info, dim)) + .map(|((name, description), bit_offset)| { + let mut info = info.clone(); + info.name = name; + info.description = description; + info.bit_range = BitRange::from_offset_width(bit_offset, info.bit_width()); + info + }) } /// Builder for [`FieldInfo`] diff --git a/svd-rs/src/peripheral.rs b/svd-rs/src/peripheral.rs index 05e5031..aa1dd62 100644 --- a/svd-rs/src/peripheral.rs +++ b/svd-rs/src/peripheral.rs @@ -1,4 +1,5 @@ use super::{ + array::{descriptions, names}, registercluster::{ AllRegistersIter, AllRegistersIterMut, ClusterIter, ClusterIterMut, RegisterIter, RegisterIterMut, @@ -128,7 +129,28 @@ pub fn base_addresses<'a>( info: &'a PeripheralInfo, dim: &'a DimElement, ) -> impl Iterator + 'a { - (0..dim.dim as u64).map(move |i| info.base_address + i * dim.dim_increment as u64) + (0..dim.dim as u64).map(|i| info.base_address + i * dim.dim_increment as u64) +} + +/// Extract `PeripheralInfo` items from array +pub fn expand<'a>( + info: &'a PeripheralInfo, + dim: &'a DimElement, +) -> impl Iterator + 'a { + dim.indexes() + .zip(names(info, dim)) + .zip(descriptions(info, dim)) + .zip(base_addresses(info, dim)) + .map(|(((idx, name), description), base_address)| { + let mut info = info.clone(); + info.name = name; + info.description = description; + info.base_address = base_address; + info.display_name = info + .display_name + .map(|d| d.replace("[%s]", &idx).replace("%s", &idx)); + info + }) } /// Builder for [`Peripheral`] diff --git a/svd-rs/src/register.rs b/svd-rs/src/register.rs index c9b3d5a..f0999b2 100644 --- a/svd-rs/src/register.rs +++ b/svd-rs/src/register.rs @@ -1,4 +1,5 @@ use super::{ + array::{descriptions, names}, Access, BuildError, Description, DimElement, EmptyToNone, Field, MaybeArray, ModifiedWriteValues, Name, ReadAction, RegisterProperties, SvdError, ValidateLevel, WriteConstraint, @@ -110,6 +111,27 @@ pub fn address_offsets<'a>( (0..dim.dim).map(move |i| info.address_offset + i * dim.dim_increment) } +/// Extract `RegisterInfo` items from array +pub fn expand<'a>( + info: &'a RegisterInfo, + dim: &'a DimElement, +) -> impl Iterator + 'a { + dim.indexes() + .zip(names(info, dim)) + .zip(descriptions(info, dim)) + .zip(address_offsets(info, dim)) + .map(|(((idx, name), description), address_offset)| { + let mut info = info.clone(); + info.name = name; + info.description = description; + info.address_offset = address_offset; + info.display_name = info + .display_name + .map(|d| d.replace("[%s]", &idx).replace("%s", &idx)); + info + }) +} + /// Builder for [`RegisterInfo`] #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct RegisterInfoBuilder {