Skip to content

Commit dbd7b55

Browse files
authored
Merge pull request #240 from rust-embedded/expand-desc
expand functions for arrays
2 parents a54d1e5 + f988ce6 commit dbd7b55

File tree

8 files changed

+96
-52
lines changed

8 files changed

+96
-52
lines changed

svd-parser/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ thiserror = "1.0.31"
2727
[dev-dependencies]
2828
serde_json = { version = "1.0", features = ["preserve_order"] }
2929
serde_yaml = "0.8.26"
30-
svd-rs = { version = "0.14.1", path = "../svd-rs", features = ["serde"] }
30+
svd-rs = { version = "0.14.3", path = "../svd-rs", features = ["serde"] }
3131

3232
[[example]]
3333
name = "svd2json"

svd-parser/src/expand.rs

+10-47
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use std::collections::HashMap;
55
use std::fmt;
66
use std::mem::take;
77
use svd_rs::{
8-
array::names, cluster, field, peripheral, register, BitRange, Cluster, ClusterInfo, DeriveFrom,
9-
Device, EnumeratedValues, Field, Peripheral, Register, RegisterCluster, RegisterProperties,
8+
array::names, cluster, field, peripheral, register, Cluster, ClusterInfo, DeriveFrom, Device,
9+
EnumeratedValues, Field, Peripheral, Register, RegisterCluster, RegisterProperties,
1010
};
1111

1212
/// Path to `peripheral` or `cluster` element
@@ -319,15 +319,7 @@ fn expand_cluster_array(
319319
match c {
320320
Cluster::Single(c) => expand_cluster(regs, c),
321321
Cluster::Array(info, dim) => {
322-
for c in names(&info, &dim)
323-
.zip(cluster::address_offsets(&info, &dim))
324-
.map(|(name, address_offset)| {
325-
let mut info = info.clone();
326-
info.name = name;
327-
info.address_offset = address_offset;
328-
info
329-
})
330-
{
322+
for c in cluster::expand(&info, &dim) {
331323
expand_cluster(regs, c);
332324
}
333325
}
@@ -435,7 +427,7 @@ fn expand_cluster(regs: &mut Vec<RegisterCluster>, c: ClusterInfo) {
435427
RegisterCluster::Register(mut r) => {
436428
r.name = format!("{}_{}", c.name, r.name);
437429
r.address_offset += c.address_offset;
438-
regs.push(RegisterCluster::Register(r));
430+
regs.push(r.into());
439431
}
440432
}
441433
}
@@ -462,20 +454,10 @@ fn expand_register_array(
462454

463455
match r {
464456
Register::Single(_) => {
465-
regs.push(RegisterCluster::Register(r));
457+
regs.push(r.into());
466458
}
467459
Register::Array(info, dim) => {
468-
for rx in names(&info, &dim)
469-
.zip(register::address_offsets(&info, &dim))
470-
.map(|(name, address_offset)| {
471-
let mut info = info.clone();
472-
info.name = name;
473-
info.address_offset = address_offset;
474-
Register::Single(info)
475-
})
476-
{
477-
regs.push(RegisterCluster::Register(rx));
478-
}
460+
regs.extend(register::expand(&info, &dim).map(|r| r.single().into()));
479461
}
480462
}
481463
Ok(())
@@ -506,18 +488,7 @@ fn expand_field(
506488
fields.push(f);
507489
}
508490
Field::Array(info, dim) => {
509-
for fx in
510-
names(&info, &dim)
511-
.zip(field::bit_offsets(&info, &dim))
512-
.map(|(name, bit_offset)| {
513-
let mut info = info.clone();
514-
info.name = name;
515-
info.bit_range = BitRange::from_offset_width(bit_offset, info.bit_width());
516-
Field::Single(info)
517-
})
518-
{
519-
fields.push(fx);
520-
}
491+
fields.extend(field::expand(&info, &dim).map(Field::Single));
521492
}
522493
}
523494

@@ -630,17 +601,9 @@ pub fn expand(indevice: &Device) -> Result<Device> {
630601
device.peripherals.push(p);
631602
}
632603
Peripheral::Array(info, dim) => {
633-
for px in names(&info, &dim)
634-
.zip(peripheral::base_addresses(&info, &dim))
635-
.map(|(name, base_address)| {
636-
let mut info = info.clone();
637-
info.name = name;
638-
info.base_address = base_address;
639-
Peripheral::Single(info)
640-
})
641-
{
642-
device.peripherals.push(px);
643-
}
604+
device
605+
.peripherals
606+
.extend(peripheral::expand(&info, &dim).map(Peripheral::Single));
644607
}
645608
}
646609
}

svd-parser/src/registercluster.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ impl Parse for RegisterCluster {
99

1010
fn parse(tree: &Node, config: &Self::Config) -> Result<Self, Self::Error> {
1111
match tree.tag_name().name() {
12-
"register" => Register::parse(tree, config).map(RegisterCluster::Register),
13-
"cluster" => Cluster::parse(tree, config).map(RegisterCluster::Cluster),
12+
"register" => Register::parse(tree, config).map(Into::into),
13+
"cluster" => Cluster::parse(tree, config).map(Into::into),
1414
_ => Err(
1515
SVDError::InvalidRegisterCluster(tree.tag_name().name().to_string()).at(tree.id()),
1616
),

svd-rs/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

10+
- Add `expand` functions for arrays
1011
- Fix `indexes_as_range`
1112

1213
## [v0.14.3] - 2023-04-04

svd-rs/src/cluster.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::{
2+
array::{descriptions, names},
23
registercluster::{
34
AllRegistersIter, AllRegistersIterMut, ClusterIter, ClusterIterMut, RegisterIter,
45
RegisterIterMut,
@@ -79,6 +80,23 @@ pub fn address_offsets<'a>(
7980
(0..dim.dim).map(move |i| info.address_offset + i * dim.dim_increment)
8081
}
8182

83+
/// Extract `ClusterInfo` items from array
84+
pub fn expand<'a>(
85+
info: &'a ClusterInfo,
86+
dim: &'a DimElement,
87+
) -> impl Iterator<Item = ClusterInfo> + 'a {
88+
names(info, dim)
89+
.zip(descriptions(info, dim))
90+
.zip(address_offsets(info, dim))
91+
.map(|((name, description), address_offset)| {
92+
let mut info = info.clone();
93+
info.name = name;
94+
info.description = description;
95+
info.address_offset = address_offset;
96+
info
97+
})
98+
}
99+
82100
/// Builder for [`ClusterInfo`]
83101
#[derive(Clone, Debug, Default, PartialEq)]
84102
pub struct ClusterInfoBuilder {

svd-rs/src/field.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::{
2+
array::{descriptions, names},
23
bitrange, Access, BitRange, BuildError, Description, DimElement, EmptyToNone, EnumeratedValues,
34
MaybeArray, ModifiedWriteValues, Name, ReadAction, SvdError, Usage, ValidateLevel,
45
WriteConstraint,
@@ -84,7 +85,24 @@ pub struct FieldInfo {
8485

8586
/// Return iterator over bit offsets of each field in array
8687
pub fn bit_offsets<'a>(info: &'a FieldInfo, dim: &'a DimElement) -> impl Iterator<Item = u32> + 'a {
87-
(0..dim.dim).map(move |i| info.bit_offset() + i * dim.dim_increment)
88+
(0..dim.dim).map(|i| info.bit_offset() + i * dim.dim_increment)
89+
}
90+
91+
/// Extract `FieldInfo` items from array
92+
pub fn expand<'a>(
93+
info: &'a FieldInfo,
94+
dim: &'a DimElement,
95+
) -> impl Iterator<Item = FieldInfo> + 'a {
96+
names(info, dim)
97+
.zip(descriptions(info, dim))
98+
.zip(bit_offsets(info, dim))
99+
.map(|((name, description), bit_offset)| {
100+
let mut info = info.clone();
101+
info.name = name;
102+
info.description = description;
103+
info.bit_range = BitRange::from_offset_width(bit_offset, info.bit_width());
104+
info
105+
})
88106
}
89107

90108
/// Builder for [`FieldInfo`]

svd-rs/src/peripheral.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::{
2+
array::{descriptions, names},
23
registercluster::{
34
AllRegistersIter, AllRegistersIterMut, ClusterIter, ClusterIterMut, RegisterIter,
45
RegisterIterMut,
@@ -128,7 +129,28 @@ pub fn base_addresses<'a>(
128129
info: &'a PeripheralInfo,
129130
dim: &'a DimElement,
130131
) -> impl Iterator<Item = u64> + 'a {
131-
(0..dim.dim as u64).map(move |i| info.base_address + i * dim.dim_increment as u64)
132+
(0..dim.dim as u64).map(|i| info.base_address + i * dim.dim_increment as u64)
133+
}
134+
135+
/// Extract `PeripheralInfo` items from array
136+
pub fn expand<'a>(
137+
info: &'a PeripheralInfo,
138+
dim: &'a DimElement,
139+
) -> impl Iterator<Item = PeripheralInfo> + 'a {
140+
dim.indexes()
141+
.zip(names(info, dim))
142+
.zip(descriptions(info, dim))
143+
.zip(base_addresses(info, dim))
144+
.map(|(((idx, name), description), base_address)| {
145+
let mut info = info.clone();
146+
info.name = name;
147+
info.description = description;
148+
info.base_address = base_address;
149+
info.display_name = info
150+
.display_name
151+
.map(|d| d.replace("[%s]", &idx).replace("%s", &idx));
152+
info
153+
})
132154
}
133155

134156
/// Builder for [`Peripheral`]

svd-rs/src/register.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::{
2+
array::{descriptions, names},
23
Access, BuildError, Description, DimElement, EmptyToNone, Field, MaybeArray,
34
ModifiedWriteValues, Name, ReadAction, RegisterProperties, SvdError, ValidateLevel,
45
WriteConstraint,
@@ -110,6 +111,27 @@ pub fn address_offsets<'a>(
110111
(0..dim.dim).map(move |i| info.address_offset + i * dim.dim_increment)
111112
}
112113

114+
/// Extract `RegisterInfo` items from array
115+
pub fn expand<'a>(
116+
info: &'a RegisterInfo,
117+
dim: &'a DimElement,
118+
) -> impl Iterator<Item = RegisterInfo> + 'a {
119+
dim.indexes()
120+
.zip(names(info, dim))
121+
.zip(descriptions(info, dim))
122+
.zip(address_offsets(info, dim))
123+
.map(|(((idx, name), description), address_offset)| {
124+
let mut info = info.clone();
125+
info.name = name;
126+
info.description = description;
127+
info.address_offset = address_offset;
128+
info.display_name = info
129+
.display_name
130+
.map(|d| d.replace("[%s]", &idx).replace("%s", &idx));
131+
info
132+
})
133+
}
134+
113135
/// Builder for [`RegisterInfo`]
114136
#[derive(Clone, Debug, Default, PartialEq, Eq)]
115137
pub struct RegisterInfoBuilder {

0 commit comments

Comments
 (0)