Skip to content

Commit d6f4dc6

Browse files
committed
Put padding for cluster-arrays inside each individual array element,
instead of breaking the array up into a list of items and adding padding between the items.
1 parent 1969890 commit d6f4dc6

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

src/generate/peripheral.rs

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use std::borrow::Cow;
22
use std::cmp::Ordering;
33
use std::collections::HashMap;
44

5-
use crate::svd::{Cluster, ClusterInfo, Peripheral, Register, RegisterCluster, RegisterProperties};
5+
use crate::svd::{
6+
Cluster, ClusterInfo, DimElement, Peripheral, Register, RegisterCluster, RegisterProperties,
7+
};
68
use log::warn;
79
use proc_macro2::TokenStream;
810
use proc_macro2::{Ident, Punct, Spacing, Span};
@@ -184,7 +186,9 @@ pub fn render(
184186

185187
// Push any register or cluster blocks into the output
186188
let mut mod_items = TokenStream::new();
187-
mod_items.extend(register_or_cluster_block(&ercs, &defaults, None, config)?);
189+
mod_items.extend(register_or_cluster_block(
190+
&ercs, None, &defaults, None, config,
191+
)?);
188192

189193
// Push all cluster related information into the peripheral module
190194
for c in &clusters {
@@ -445,6 +449,7 @@ impl FieldRegions {
445449

446450
fn register_or_cluster_block(
447451
ercs: &[RegisterCluster],
452+
dim: Option<&DimElement>,
448453
defs: &RegisterProperties,
449454
name: Option<&str>,
450455
config: &Config,
@@ -555,6 +560,18 @@ fn register_or_cluster_block(
555560
last_end = region.end;
556561
}
557562

563+
// If we are part of an array, then expand the size to the dim_increment
564+
// of the array. This allows the array to be emitted as a rust array.
565+
if let Some(dim) = dim {
566+
if last_end < dim.dim_increment {
567+
let pad = (dim.dim_increment - last_end) as usize;
568+
let pad = util::hex(pad as u64);
569+
rbfs.extend(quote! {
570+
_reserved_end: [u8; #pad],
571+
})
572+
}
573+
}
574+
558575
let name = Ident::new(
559576
&match name {
560577
Some(name) => name.to_sanitized_upper_case(),
@@ -620,14 +637,7 @@ fn cluster_size_in_bits(
620637
// dimIncrement and the size of the array items, then the array
621638
// will get expanded in expand_cluster below. The overall size
622639
// then ends at the last array entry.
623-
Cluster::Array(info, dim) => {
624-
if dim.dim == 0 {
625-
return Ok(0); // Special case!
626-
}
627-
let last_offset = (dim.dim - 1) * dim.dim_increment * BITS_PER_BYTE;
628-
let last_size = cluster_info_size_in_bits(info, defs, config);
629-
Ok(last_offset + last_size?)
630-
}
640+
Cluster::Array(_info, dim) => Ok(dim.dim_increment * dim.dim * BITS_PER_BYTE),
631641
}
632642
}
633643

@@ -671,19 +681,20 @@ fn expand_cluster(
671681

672682
let defs = cluster.default_register_properties.derive_from(defs);
673683

674-
let cluster_size = cluster_info_size_in_bits(cluster, &defs, config)
675-
.with_context(|| format!("Cluster {} has no determinable `size` field", cluster.name))?;
676-
677684
match cluster {
678-
Cluster::Single(info) => cluster_expanded.push(RegisterBlockField {
679-
field: convert_svd_cluster(cluster, name)?,
680-
description: info.description.as_ref().unwrap_or(&info.name).into(),
681-
offset: info.address_offset,
682-
size: cluster_size,
683-
}),
685+
Cluster::Single(info) => {
686+
let cluster_size =
687+
cluster_info_size_in_bits(info, &defs, config).with_context(|| {
688+
format!("Cluster {} has no determinable `size` field", info.name)
689+
})?;
690+
cluster_expanded.push(RegisterBlockField {
691+
field: convert_svd_cluster(cluster, name)?,
692+
description: info.description.as_ref().unwrap_or(&info.name).into(),
693+
offset: info.address_offset,
694+
size: cluster_size,
695+
})
696+
}
684697
Cluster::Array(info, array_info) => {
685-
let sequential_addresses = cluster_size == array_info.dim_increment * BITS_PER_BYTE;
686-
687698
// if dimIndex exists, test if it is a sequence of numbers from 0 to dim
688699
let sequential_indexes = array_info.dim_index.as_ref().map_or(true, |dim_index| {
689700
dim_index
@@ -692,22 +703,20 @@ fn expand_cluster(
692703
.eq((0..array_info.dim).map(Ok))
693704
});
694705

695-
let array_convertible = sequential_indexes && sequential_addresses;
696-
697-
if array_convertible {
706+
if sequential_indexes {
698707
cluster_expanded.push(RegisterBlockField {
699708
field: convert_svd_cluster(&cluster, name)?,
700709
description: info.description.as_ref().unwrap_or(&info.name).into(),
701710
offset: info.address_offset,
702-
size: cluster_size * array_info.dim,
711+
size: array_info.dim_increment * array_info.dim * BITS_PER_BYTE,
703712
});
704713
} else {
705714
for (field_num, field) in expand_svd_cluster(cluster, name)?.iter().enumerate() {
706715
cluster_expanded.push(RegisterBlockField {
707716
field: field.clone(),
708717
description: info.description.as_ref().unwrap_or(&info.name).into(),
709718
offset: info.address_offset + field_num as u32 * array_info.dim_increment,
710-
size: cluster_size,
719+
size: array_info.dim_increment * BITS_PER_BYTE,
711720
});
712721
}
713722
}
@@ -804,7 +813,13 @@ fn cluster_block(
804813

805814
let defaults = c.default_register_properties.derive_from(defaults);
806815

807-
let reg_block = register_or_cluster_block(&c.children, &defaults, Some(&mod_name), config)?;
816+
let (info, dim) = match c {
817+
Cluster::Single(info) => (info, None),
818+
Cluster::Array(info, dim) => (info, Some(dim)),
819+
};
820+
821+
let reg_block =
822+
register_or_cluster_block(&info.children, dim, &defaults, Some(&mod_name), config)?;
808823

809824
// Generate definition for each of the registers.
810825
let registers = util::only_registers(&c.children);

0 commit comments

Comments
 (0)