Skip to content

Commit

Permalink
Merge pull request #240 from rust-embedded/expand-desc
Browse files Browse the repository at this point in the history
expand functions for arrays
  • Loading branch information
Emilgardis authored Nov 15, 2023
2 parents a54d1e5 + f988ce6 commit dbd7b55
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 52 deletions.
2 changes: 1 addition & 1 deletion svd-parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
57 changes: 10 additions & 47 deletions svd-parser/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -435,7 +427,7 @@ fn expand_cluster(regs: &mut Vec<RegisterCluster>, 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());
}
}
}
Expand All @@ -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(())
Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -630,17 +601,9 @@ pub fn expand(indevice: &Device) -> Result<Device> {
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));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions svd-parser/src/registercluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ impl Parse for RegisterCluster {

fn parse(tree: &Node, config: &Self::Config) -> Result<Self, Self::Error> {
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()),
),
Expand Down
1 change: 1 addition & 0 deletions svd-rs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions svd-rs/src/cluster.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{
array::{descriptions, names},
registercluster::{
AllRegistersIter, AllRegistersIterMut, ClusterIter, ClusterIterMut, RegisterIter,
RegisterIterMut,
Expand Down Expand Up @@ -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<Item = ClusterInfo> + '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 {
Expand Down
20 changes: 19 additions & 1 deletion svd-rs/src/field.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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<Item = u32> + '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<Item = FieldInfo> + '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`]
Expand Down
24 changes: 23 additions & 1 deletion svd-rs/src/peripheral.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{
array::{descriptions, names},
registercluster::{
AllRegistersIter, AllRegistersIterMut, ClusterIter, ClusterIterMut, RegisterIter,
RegisterIterMut,
Expand Down Expand Up @@ -128,7 +129,28 @@ pub fn base_addresses<'a>(
info: &'a PeripheralInfo,
dim: &'a DimElement,
) -> impl Iterator<Item = u64> + '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<Item = PeripheralInfo> + '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`]
Expand Down
22 changes: 22 additions & 0 deletions svd-rs/src/register.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{
array::{descriptions, names},
Access, BuildError, Description, DimElement, EmptyToNone, Field, MaybeArray,
ModifiedWriteValues, Name, ReadAction, RegisterProperties, SvdError, ValidateLevel,
WriteConstraint,
Expand Down Expand Up @@ -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<Item = RegisterInfo> + '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 {
Expand Down

0 comments on commit dbd7b55

Please sign in to comment.