Skip to content

Commit 50ba4d9

Browse files
committed
derived_last
1 parent 47bccc7 commit 50ba4d9

File tree

5 files changed

+237
-66
lines changed

5 files changed

+237
-66
lines changed

svd-encoder/src/config.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ where
150150
}
151151
}
152152

153-
#[derive(Clone, Copy, Debug)]
153+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
154154
pub struct FieldBitRangeFormat(pub BitRangeType);
155155

156156
impl FromStr for FieldBitRangeFormat {
@@ -167,9 +167,14 @@ impl FromStr for FieldBitRangeFormat {
167167
}
168168

169169
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
170+
#[non_exhaustive]
171+
/// Apply a kind of sorting
170172
pub enum Sorting {
173+
/// Sort by addresses of offsets
171174
Offset,
175+
/// Same as [`Sorting::Offset`], but reversed
172176
OffsetReversed,
177+
/// Sort by name
173178
Name,
174179
}
175180

@@ -225,6 +230,9 @@ pub struct Config {
225230
/// Sort peripherals in specified order
226231
pub peripheral_sorting: Option<Sorting>,
227232

233+
/// Place derived peripherals in the end
234+
pub peripheral_derived_last: bool,
235+
228236
/// Format of addressBlock's offset element
229237
///
230238
/// format: hex, dec
@@ -256,6 +264,9 @@ pub struct Config {
256264
/// First write registers or clusters
257265
pub registers_or_clusters_first: Option<RegistersOrClustersFirst>,
258266

267+
/// Place derived registers and clusters in the end
268+
pub register_cluster_derived_last: bool,
269+
259270
/// Format of register's name-kind elements
260271
/// - `derivedFrom`
261272
/// - `name`
@@ -295,6 +306,9 @@ pub struct Config {
295306
/// Sort fields in specified order
296307
pub field_sorting: Option<Sorting>,
297308

309+
/// Place derived fields in the end
310+
pub field_derived_last: bool,
311+
298312
/// Format of enumeratedValues's name-kind elements
299313
/// - `derivedFrom`
300314
/// - `name`
@@ -329,13 +343,15 @@ impl Default for Config {
329343
peripheral_name: None,
330344
peripheral_base_address: NumberFormat::UpperHex8,
331345
peripheral_sorting: None,
346+
peripheral_derived_last: false,
332347
address_block_offset: NumberFormat::UpperHex,
333348
address_block_size: NumberFormat::UpperHex,
334349
interrupt_name: None,
335350
cluster_name: None,
336351
cluster_address_offset: NumberFormat::UpperHex,
337352
register_cluster_sorting: None,
338353
registers_or_clusters_first: None,
354+
register_cluster_derived_last: false,
339355
register_name: None,
340356
register_address_offset: NumberFormat::UpperHex,
341357
register_size: NumberFormat::LowerHex,
@@ -344,6 +360,7 @@ impl Default for Config {
344360
field_name: None,
345361
field_bit_range: None,
346362
field_sorting: None,
363+
field_derived_last: false,
347364
enumerated_values_name: None,
348365
enumerated_value_name: None,
349366
enumerated_value_value: NumberFormat::Dec,
@@ -363,6 +380,7 @@ impl Config {
363380
"peripheral_name" => self.peripheral_name = Some(value.parse().unwrap()),
364381
"peripheral_base_address" => self.peripheral_base_address = value.parse().unwrap(),
365382
"peripheral_sorting" => self.peripheral_sorting = Some(value.parse().unwrap()),
383+
"peripheral_derived_last" => self.peripheral_derived_last = value.parse().unwrap(),
366384
"address_block_offset" => self.address_block_offset = value.parse().unwrap(),
367385
"address_block_size" => self.address_block_size = value.parse().unwrap(),
368386
"interrupt_name" => self.interrupt_name = Some(value.parse().unwrap()),
@@ -374,6 +392,9 @@ impl Config {
374392
"registers_or_clusters_first" => {
375393
self.registers_or_clusters_first = Some(value.parse().unwrap())
376394
}
395+
"register_cluster_derived_last" => {
396+
self.register_cluster_derived_last = value.parse().unwrap()
397+
}
377398
"register_name" => self.register_name = Some(value.parse().unwrap()),
378399
"register_address_offset" => self.register_address_offset = value.parse().unwrap(),
379400
"register_size" => self.register_size = value.parse().unwrap(),
@@ -382,6 +403,7 @@ impl Config {
382403
"field_name" => self.field_name = Some(value.parse().unwrap()),
383404
"field_bit_range" => self.field_bit_range = Some(value.parse().unwrap()),
384405
"field_sorting" => self.field_sorting = Some(value.parse().unwrap()),
406+
"field_derived_last" => self.field_derived_last = value.parse().unwrap(),
385407
"enumerated_values_name" => self.enumerated_values_name = Some(value.parse().unwrap()),
386408
"enumerated_value_name" => self.enumerated_value_name = Some(value.parse().unwrap()),
387409
"enumerated_value_value" => self.enumerated_value_value = value.parse().unwrap(),
@@ -418,6 +440,14 @@ impl Config {
418440
self
419441
}
420442

443+
/// Place derived peripherals in the end
444+
///
445+
/// `false` means keep the original order
446+
pub fn peripheral_derived_last(mut self, val: bool) -> Self {
447+
self.peripheral_derived_last = val;
448+
self
449+
}
450+
421451
/// Format of addressBlock's offset element
422452
///
423453
/// format: hex, dec
@@ -470,6 +500,14 @@ impl Config {
470500
self
471501
}
472502

503+
/// Place derived registers and clusters in the end
504+
///
505+
/// `false` means keep the original order
506+
pub fn register_cluster_derived_last(mut self, val: bool) -> Self {
507+
self.register_cluster_derived_last = val;
508+
self
509+
}
510+
473511
/// Format of register's name-kind elements
474512
pub fn register_name(mut self, val: Option<IdentifierFormat>) -> Self {
475513
self.register_name = val;
@@ -530,6 +568,14 @@ impl Config {
530568
self
531569
}
532570

571+
/// Place derived fields in the end
572+
///
573+
/// `false` means keep the original order
574+
pub fn field_derived_last(mut self, val: bool) -> Self {
575+
self.field_derived_last = val;
576+
self
577+
}
578+
533579
/// Format of enumeratedValues's name-kind elements
534580
pub fn enumerated_values_name(mut self, val: Option<IdentifierFormat>) -> Self {
535581
self.enumerated_values_name = val;

svd-encoder/src/device.rs

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use svd_rs::Peripheral;
2+
13
use super::{new_node, Config, Element, Encode, EncodeChildren, EncodeError, XMLNode};
24
use crate::{config::Sorting, svd::Device};
35

@@ -57,24 +59,23 @@ impl Encode for Device {
5759
.encode_with_config(config)?,
5860
);
5961

60-
let peripherals: Result<Vec<_>, _> = if let Some(sorting) = config.peripheral_sorting {
61-
let mut refs = self.peripherals.iter().collect::<Vec<_>>();
62-
match sorting {
63-
Sorting::Offset => refs.sort_by_key(|p| p.base_address),
64-
Sorting::OffsetReversed => {
65-
refs.sort_by_key(|p| -(p.base_address as i32));
66-
}
67-
Sorting::Name => refs.sort_by_key(|p| &p.name),
68-
}
69-
refs.into_iter()
70-
.map(|peripheral| peripheral.encode_node_with_config(config))
71-
.collect()
72-
} else {
73-
self.peripherals
74-
.iter()
62+
let peripherals: Result<Vec<_>, _> =
63+
if !config.peripheral_derived_last && config.peripheral_sorting.is_none() {
64+
self.peripherals
65+
.iter()
66+
.map(|peripheral| peripheral.encode_node_with_config(config))
67+
.collect()
68+
} else {
69+
sort_derived_peripherals(
70+
&self.peripherals,
71+
config.peripheral_sorting,
72+
config.peripheral_derived_last,
73+
)
74+
.into_iter()
7575
.map(|peripheral| peripheral.encode_node_with_config(config))
7676
.collect()
77-
};
77+
};
78+
7879
elem.children.push({
7980
let mut e = Element::new("peripherals");
8081
e.children = peripherals?;
@@ -93,3 +94,40 @@ impl Encode for Device {
9394
Ok(elem)
9495
}
9596
}
97+
98+
fn sort_peripherals(refs: &mut [&Peripheral], sorting: Option<Sorting>) {
99+
if let Some(sorting) = sorting {
100+
match sorting {
101+
Sorting::Offset => refs.sort_by_key(|p| p.base_address),
102+
Sorting::OffsetReversed => {
103+
refs.sort_by_key(|p| -(p.base_address as i32));
104+
}
105+
Sorting::Name => refs.sort_by_key(|p| &p.name),
106+
}
107+
}
108+
}
109+
110+
fn sort_derived_peripherals(
111+
peripherals: &[Peripheral],
112+
sorting: Option<Sorting>,
113+
derived_last: bool,
114+
) -> Vec<&Peripheral> {
115+
if derived_last {
116+
let mut common_refs = peripherals
117+
.iter()
118+
.filter(|p| p.derived_from.is_none())
119+
.collect::<Vec<_>>();
120+
let mut derived_refs = peripherals
121+
.iter()
122+
.filter(|p| p.derived_from.is_some())
123+
.collect::<Vec<_>>();
124+
sort_peripherals(&mut common_refs, sorting);
125+
sort_peripherals(&mut derived_refs, sorting);
126+
common_refs.extend(derived_refs);
127+
common_refs
128+
} else {
129+
let mut refs = peripherals.iter().collect::<Vec<_>>();
130+
sort_peripherals(&mut refs, sorting);
131+
refs
132+
}
133+
}

svd-encoder/src/peripheral.rs

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -104,41 +104,53 @@ impl Encode for PeripheralInfo {
104104
elem.children.append(&mut interrupts?);
105105

106106
if let Some(v) = &self.registers {
107-
let children: Result<Vec<_>, _> =
108-
if let Some(first) = config.registers_or_clusters_first {
109-
let mut reg_refs = v
110-
.iter()
111-
.filter(|rc| matches!(rc, RegisterCluster::Register(_)))
112-
.collect::<Vec<_>>();
113-
sort_register_cluster(&mut reg_refs, config.register_cluster_sorting);
114-
let mut c_refs = v
115-
.iter()
116-
.filter(|rc| matches!(rc, RegisterCluster::Cluster(_)))
117-
.collect::<Vec<_>>();
118-
sort_register_cluster(&mut c_refs, config.register_cluster_sorting);
119-
match first {
120-
crate::RegistersOrClustersFirst::Registers => {
121-
reg_refs.into_iter().chain(c_refs.into_iter())
122-
}
123-
crate::RegistersOrClustersFirst::Clusters => {
124-
c_refs.into_iter().chain(reg_refs.into_iter())
125-
}
126-
}
107+
let children: Result<Vec<_>, _> = if config.registers_or_clusters_first.is_none()
108+
&& !config.register_cluster_derived_last
109+
&& config.register_cluster_sorting.is_none()
110+
{
111+
v.iter()
127112
.map(|e| e.encode_node_with_config(config))
128113
.collect()
129-
} else {
130-
if let Some(sorting) = config.register_cluster_sorting {
131-
let mut refs = v.iter().collect::<Vec<_>>();
132-
sort_register_cluster(&mut refs, Some(sorting));
133-
refs.into_iter()
134-
.map(|e| e.encode_node_with_config(config))
135-
.collect()
136-
} else {
137-
v.iter()
138-
.map(|e| e.encode_node_with_config(config))
139-
.collect()
114+
} else if let Some(first) = config.registers_or_clusters_first {
115+
let reg_refs = v
116+
.iter()
117+
.filter(|rc| matches!(rc, RegisterCluster::Register(_)))
118+
.collect::<Vec<_>>();
119+
let reg_refs = sort_derived_register_cluster(
120+
reg_refs,
121+
config.register_cluster_sorting,
122+
config.register_cluster_derived_last,
123+
);
124+
125+
let c_refs = v
126+
.iter()
127+
.filter(|rc| matches!(rc, RegisterCluster::Cluster(_)))
128+
.collect::<Vec<_>>();
129+
let c_refs = sort_derived_register_cluster(
130+
c_refs,
131+
config.register_cluster_sorting,
132+
config.register_cluster_derived_last,
133+
);
134+
match first {
135+
crate::RegistersOrClustersFirst::Registers => {
136+
reg_refs.into_iter().chain(c_refs.into_iter())
137+
}
138+
crate::RegistersOrClustersFirst::Clusters => {
139+
c_refs.into_iter().chain(reg_refs.into_iter())
140140
}
141-
};
141+
}
142+
.map(|e| e.encode_node_with_config(config))
143+
.collect()
144+
} else {
145+
sort_derived_register_cluster(
146+
v,
147+
config.register_cluster_sorting,
148+
config.register_cluster_derived_last,
149+
)
150+
.into_iter()
151+
.map(|e| e.encode_node_with_config(config))
152+
.collect()
153+
};
142154

143155
elem.children.push({
144156
let mut e = Element::new("registers");
@@ -169,3 +181,29 @@ fn sort_register_cluster(refs: &mut [&RegisterCluster], sorting: Option<Sorting>
169181
}
170182
}
171183
}
184+
185+
fn sort_derived_register_cluster<'a>(
186+
rcs: impl IntoIterator<Item = &'a RegisterCluster>,
187+
sorting: Option<Sorting>,
188+
derived_last: bool,
189+
) -> Vec<&'a RegisterCluster> {
190+
if derived_last {
191+
let mut common_refs = Vec::new();
192+
let mut derived_refs = Vec::new();
193+
for rc in rcs {
194+
if rc.derived_from().is_some() {
195+
derived_refs.push(rc);
196+
} else {
197+
common_refs.push(rc);
198+
}
199+
}
200+
sort_register_cluster(&mut common_refs, sorting);
201+
sort_register_cluster(&mut derived_refs, sorting);
202+
common_refs.extend(derived_refs);
203+
common_refs
204+
} else {
205+
let mut refs = rcs.into_iter().collect::<Vec<_>>();
206+
sort_register_cluster(&mut refs, sorting);
207+
refs
208+
}
209+
}

0 commit comments

Comments
 (0)