Skip to content

Commit 696fe2e

Browse files
authored
Merge pull request #754 from rust-embedded/writer-offset-names
support dimName and dimArrayIndex for array names and descriptions
2 parents 1ecb954 + f25950f commit 696fe2e

File tree

7 files changed

+103
-96
lines changed

7 files changed

+103
-96
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
99

1010
- Remove unstable lints
1111
- Mark `Vector` union as `repr(C)`
12+
- Support `dimArrayIndex` for array names and descriptions
1213

1314
## [v0.30.2] - 2023-10-22
1415

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ html-escape = "0.2"
6060

6161
[dependencies.svd-parser]
6262
features = ["expand"]
63-
version = "0.14.2"
63+
version = "0.14.3"
6464

6565
[dependencies.svd-rs]
6666
features = ["serde"]
67-
version = "0.14.2"
67+
version = "0.14.4"
6868

6969
[dependencies.syn]
7070
version = "2.0"

src/generate/array_proxy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub struct ArrayProxy<T, const COUNT: usize, const STRIDE: usize> {
1818
impl<T, const C: usize, const S: usize> ArrayProxy<T, C, S> {
1919
/// Get a reference from an [ArrayProxy] with no bounds checking.
2020
pub const unsafe fn get_ref(&self, index: usize) -> &T {
21-
&*(self as *const Self).cast::<u8>().add(S * index).cast::<T>()
21+
&*(self as *const Self).cast::<u8>().add(S * index).cast()
2222
}
2323
/// Get a reference from an [ArrayProxy], or return `None` if the index
2424
/// is out of bounds.

src/generate/peripheral.rs

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ use svd_parser::expand::{
77
};
88

99
use crate::svd::{
10-
array::names, Cluster, ClusterInfo, MaybeArray, Peripheral, Register, RegisterCluster,
11-
RegisterInfo,
10+
Cluster, ClusterInfo, MaybeArray, Peripheral, Register, RegisterCluster, RegisterInfo,
1211
};
1312
use log::{debug, trace, warn};
1413
use proc_macro2::{Ident, Punct, Spacing, Span, TokenStream};
@@ -74,36 +73,32 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
7473

7574
match &p {
7675
Peripheral::Array(p, dim) => {
77-
let names: Vec<Cow<str>> = names(p, dim).map(|n| n.into()).collect();
78-
let names_str = names.iter().map(|n| n.to_sanitized_constant_case());
79-
let names_constant_case = names_str.clone().map(|n| Ident::new(&n, span));
80-
let addresses =
81-
(0..=dim.dim).map(|i| util::hex(p.base_address + (i * dim.dim_increment) as u64));
82-
let snake_names = names
83-
.iter()
84-
.map(|p_name| p_name.to_sanitized_snake_case())
85-
.collect::<Vec<_>>();
86-
let feature_attribute_n = snake_names.iter().map(|p_snake| {
87-
let mut feature_attribute = feature_attribute.clone();
76+
let mut snake_names = Vec::with_capacity(dim.dim as _);
77+
for pi in crate::svd::peripheral::expand(p, dim) {
78+
let name = &pi.name;
79+
let description = pi.description.as_deref().unwrap_or(&p.name);
80+
let name_str = name.to_sanitized_constant_case();
81+
let name_constant_case = Ident::new(&name, span);
82+
let address = util::hex(pi.base_address);
83+
let p_snake = name.to_sanitized_snake_case();
84+
snake_names.push(p_snake.to_string());
85+
let mut feature_attribute_n = feature_attribute.clone();
8886
if config.feature_peripheral {
89-
feature_attribute.extend(quote! { #[cfg(feature = #p_snake)] })
87+
feature_attribute_n.extend(quote! { #[cfg(feature = #p_snake)] })
9088
};
91-
feature_attribute
92-
});
93-
// Insert the peripherals structure
94-
out.extend(quote! {
95-
#(
89+
// Insert the peripherals structure
90+
out.extend(quote! {
9691
#[doc = #description]
9792
#feature_attribute_n
98-
pub struct #names_constant_case { _marker: PhantomData<*const ()> }
93+
pub struct #name_constant_case { _marker: PhantomData<*const ()> }
9994

10095
#feature_attribute_n
101-
unsafe impl Send for #names_constant_case {}
96+
unsafe impl Send for #name_constant_case {}
10297

10398
#feature_attribute_n
104-
impl #names_constant_case {
99+
impl #name_constant_case {
105100
///Pointer to the register block
106-
pub const PTR: *const #base::RegisterBlock = #addresses as *const _;
101+
pub const PTR: *const #base::RegisterBlock = #address as *const _;
107102

108103
///Return the pointer to the register block
109104
#[inline(always)]
@@ -115,7 +110,7 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
115110
}
116111

117112
#feature_attribute_n
118-
impl Deref for #names_constant_case {
113+
impl Deref for #name_constant_case {
119114
type Target = #base::RegisterBlock;
120115

121116
#[inline(always)]
@@ -125,13 +120,13 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
125120
}
126121

127122
#feature_attribute_n
128-
impl core::fmt::Debug for #names_constant_case {
123+
impl core::fmt::Debug for #name_constant_case {
129124
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
130-
f.debug_struct(#names_str).finish()
125+
f.debug_struct(#name_str).finish()
131126
}
132127
}
133-
)*
134-
});
128+
});
129+
}
135130

136131
let feature_any_attribute = quote! {#[cfg(any(#(feature = #snake_names),*))]};
137132

@@ -1075,47 +1070,44 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
10751070
.is_some();
10761071

10771072
let convert_list = match config.keep_list {
1078-
true => match &array_info.dim_name {
1079-
Some(dim_name) => dim_name.contains("[%s]"),
1080-
None => info.name.contains("[%s]"),
1081-
},
1073+
true => info.name.contains("[%s]"),
10821074
false => true,
10831075
};
10841076

10851077
let array_convertible = sequential_addresses && convert_list;
10861078

10871079
if array_convertible {
1080+
let span = Span::call_site();
1081+
let nb_name_sc = if let Some(dim_name) = array_info.dim_name.as_ref() {
1082+
dim_name.to_snake_case_ident(span)
1083+
} else {
1084+
ty_name.to_snake_case_ident(span)
1085+
};
10881086
let accessors = if sequential_indexes_from0 {
10891087
Vec::new()
10901088
} else {
1091-
let span = Span::call_site();
10921089
let mut accessors = Vec::new();
1093-
let nb_name_cs = ty_name.to_snake_case_ident(span);
1094-
for (i, idx) in array_info.indexes().enumerate() {
1095-
let idx_name =
1096-
util::replace_suffix(&info.name, &idx).to_snake_case_ident(span);
1090+
for (i, ci) in crate::svd::cluster::expand(info, array_info).enumerate() {
1091+
let idx_name = ci.name.to_snake_case_ident(span);
10971092
let comment = make_comment(
10981093
cluster_size,
1099-
info.address_offset + (i as u32) * cluster_size / 8,
1100-
&description,
1094+
ci.address_offset,
1095+
ci.description.as_deref().unwrap_or(&ci.name),
11011096
);
11021097
let i = unsuffixed(i as _);
11031098
accessors.push(ArrayAccessor {
11041099
doc: comment,
11051100
name: idx_name,
11061101
ty: ty.clone(),
1107-
basename: nb_name_cs.clone(),
1102+
basename: nb_name_sc.clone(),
11081103
i,
11091104
});
11101105
}
11111106
accessors
11121107
};
11131108
let array_ty = new_syn_array(ty, array_info.dim);
11141109
cluster_expanded.push(RegisterBlockField {
1115-
syn_field: new_syn_field(
1116-
ty_name.to_snake_case_ident(Span::call_site()),
1117-
array_ty,
1118-
),
1110+
syn_field: new_syn_field(nb_name_sc, array_ty),
11191111
description,
11201112
offset: info.address_offset,
11211113
size: cluster_size * array_info.dim,
@@ -1135,15 +1127,14 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
11351127
accessors: Vec::new(),
11361128
});
11371129
} else {
1138-
for (field_num, idx) in array_info.indexes().enumerate() {
1139-
let nb_name = util::replace_suffix(&info.name, &idx);
1130+
for ci in crate::svd::cluster::expand(info, array_info) {
11401131
let syn_field =
1141-
new_syn_field(nb_name.to_snake_case_ident(Span::call_site()), ty.clone());
1132+
new_syn_field(ci.name.to_snake_case_ident(Span::call_site()), ty.clone());
11421133

11431134
cluster_expanded.push(RegisterBlockField {
11441135
syn_field,
1145-
description: description.clone(),
1146-
offset: info.address_offset + field_num as u32 * array_info.dim_increment,
1136+
description: ci.description.unwrap_or(ci.name),
1137+
offset: ci.address_offset,
11471138
size: cluster_size,
11481139
accessors: Vec::new(),
11491140
});
@@ -1197,10 +1188,7 @@ fn expand_register(
11971188
|| (register_size <= array_info.dim_increment * BITS_PER_BYTE);
11981189

11991190
let convert_list = match config.keep_list {
1200-
true => match &array_info.dim_name {
1201-
Some(dim_name) => dim_name.contains("[%s]"),
1202-
None => info.name.contains("[%s]"),
1203-
},
1191+
true => info.name.contains("[%s]"),
12041192
false => true,
12051193
};
12061194

@@ -1234,26 +1222,32 @@ fn expand_register(
12341222
let ty = name_to_ty(&ty_name);
12351223

12361224
if array_convertible || (array_proxy_convertible && config.const_generic) {
1225+
let span = Span::call_site();
1226+
let nb_name_sc = if let Some(dim_name) = array_info.dim_name.as_ref() {
1227+
util::fullname(dim_name, &info.alternate_group, config.ignore_groups)
1228+
.to_snake_case_ident(span)
1229+
} else {
1230+
ty_name.to_snake_case_ident(span)
1231+
};
12371232
let accessors = if sequential_indexes_from0 {
12381233
Vec::new()
12391234
} else {
1240-
let span = Span::call_site();
12411235
let mut accessors = Vec::new();
1242-
let nb_name_cs = ty_name.to_snake_case_ident(span);
1243-
for (i, idx) in array_info.indexes().enumerate() {
1236+
for (i, ri) in crate::svd::register::expand(info, array_info).enumerate() {
12441237
let idx_name =
1245-
util::replace_suffix(&info_name, &idx).to_snake_case_ident(span);
1238+
util::fullname(&ri.name, &info.alternate_group, config.ignore_groups)
1239+
.to_snake_case_ident(span);
12461240
let comment = make_comment(
12471241
register_size,
1248-
info.address_offset + (i as u32) * register_size / 8,
1249-
&description,
1242+
ri.address_offset,
1243+
ri.description.as_deref().unwrap_or(&ri.name),
12501244
);
12511245
let i = unsuffixed(i as _);
12521246
accessors.push(ArrayAccessor {
12531247
doc: comment,
12541248
name: idx_name,
12551249
ty: ty.clone(),
1256-
basename: nb_name_cs.clone(),
1250+
basename: nb_name_sc.clone(),
12571251
i,
12581252
});
12591253
}
@@ -1264,8 +1258,7 @@ fn expand_register(
12641258
} else {
12651259
array_proxy_type(ty, array_info)
12661260
};
1267-
let syn_field =
1268-
new_syn_field(ty_name.to_snake_case_ident(Span::call_site()), array_ty);
1261+
let syn_field = new_syn_field(nb_name_sc, array_ty);
12691262
register_expanded.push(RegisterBlockField {
12701263
syn_field,
12711264
description,
@@ -1278,15 +1271,14 @@ fn expand_register(
12781271
accessors,
12791272
});
12801273
} else {
1281-
for (field_num, idx) in array_info.indexes().enumerate() {
1282-
let nb_name = util::replace_suffix(&info_name, &idx);
1274+
for ri in crate::svd::register::expand(info, array_info) {
12831275
let syn_field =
1284-
new_syn_field(nb_name.to_snake_case_ident(Span::call_site()), ty.clone());
1276+
new_syn_field(ri.name.to_snake_case_ident(Span::call_site()), ty.clone());
12851277

12861278
register_expanded.push(RegisterBlockField {
12871279
syn_field,
1288-
description: description.clone(),
1289-
offset: info.address_offset + field_num as u32 * array_info.dim_increment,
1280+
description: ri.description.unwrap_or(ri.name),
1281+
offset: ri.address_offset,
12901282
size: register_size,
12911283
accessors: Vec::new(),
12921284
});

src/generate/register.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::svd::{
2-
Access, BitRange, EnumeratedValues, Field, MaybeArray, ModifiedWriteValues, ReadAction,
3-
Register, RegisterProperties, Usage, WriteConstraint,
2+
Access, BitRange, DimElement, EnumeratedValues, Field, MaybeArray, ModifiedWriteValues,
3+
ReadAction, Register, RegisterProperties, Usage, WriteConstraint,
44
};
55
use core::u64;
66
use log::warn;
@@ -571,7 +571,18 @@ pub fn fields(
571571
}
572572

573573
let name = util::replace_suffix(&f.name, "");
574-
let name_snake_case = name.to_snake_case_ident(span);
574+
let name_snake_case = if let Field::Array(
575+
_,
576+
DimElement {
577+
dim_name: Some(dim_name),
578+
..
579+
},
580+
) = &f
581+
{
582+
dim_name.to_snake_case_ident(span)
583+
} else {
584+
name.to_snake_case_ident(span)
585+
};
575586
let name_constant_case = name.to_sanitized_constant_case();
576587
let description_raw = f.description.as_deref().unwrap_or(""); // raw description, if absent using empty string
577588
let description = util::respace(&util::escape_special_chars(description_raw));
@@ -862,8 +873,8 @@ pub fn fields(
862873
}
863874
});
864875
}
865-
for (i, suffix) in de.indexes().enumerate() {
866-
let sub_offset = offset + (i as u64) * (increment as u64);
876+
for fi in crate::svd::field::expand(&f, de) {
877+
let sub_offset = fi.bit_offset() as u64;
867878
let value = if sub_offset != 0 {
868879
let sub_offset = &util::unsuffixed(sub_offset);
869880
quote! { (self.bits >> #sub_offset) }
@@ -877,11 +888,11 @@ pub fn fields(
877888
} else {
878889
value
879890
};
880-
let name_snake_case_n = util::replace_suffix(&f.name, &suffix)
881-
.to_snake_case_ident(Span::call_site());
882-
let doc = util::replace_suffix(
883-
&description_with_bits(description_raw, sub_offset, width),
884-
&suffix,
891+
let name_snake_case_n = fi.name.to_snake_case_ident(Span::call_site());
892+
let doc = description_with_bits(
893+
fi.description.as_deref().unwrap_or(&fi.name),
894+
sub_offset,
895+
width,
885896
);
886897
r_impl_items.extend(quote! {
887898
#[doc = #doc]
@@ -1098,7 +1109,6 @@ pub fn fields(
10981109
}
10991110

11001111
if let Field::Array(_, de) = &f {
1101-
let increment = de.dim_increment;
11021112
let doc = &util::replace_suffix(&description, &brief_suffix);
11031113
w_impl_items.extend(quote! {
11041114
#[doc = #doc]
@@ -1109,13 +1119,13 @@ pub fn fields(
11091119
}
11101120
});
11111121

1112-
for (i, suffix) in de.indexes().enumerate() {
1113-
let sub_offset = offset + (i as u64) * (increment as u64);
1114-
let name_snake_case_n = &util::replace_suffix(&f.name, &suffix)
1115-
.to_snake_case_ident(Span::call_site());
1116-
let doc = util::replace_suffix(
1117-
&description_with_bits(description_raw, sub_offset, width),
1118-
&suffix,
1122+
for fi in crate::svd::field::expand(&f, de) {
1123+
let sub_offset = fi.bit_offset() as u64;
1124+
let name_snake_case_n = &fi.name.to_snake_case_ident(Span::call_site());
1125+
let doc = description_with_bits(
1126+
fi.description.as_deref().unwrap_or(&fi.name),
1127+
sub_offset,
1128+
width,
11191129
);
11201130
let sub_offset = util::unsuffixed(sub_offset);
11211131

0 commit comments

Comments
 (0)