Skip to content

Commit dadde9a

Browse files
bors[bot]burrbull
andauthored
Merge #649
649: max cluster size r=adamgreig a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents db301c5 + 9df2cef commit dadde9a

File tree

4 files changed

+85
-33
lines changed

4 files changed

+85
-33
lines changed

CHANGELOG.md

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

88
## [Unreleased]
99

10+
- Fixed parentheses in RegisterBlock field accessors
11+
- Check cluster size, add `max_cluster_size` option
12+
1013
## [v0.25.0] - 2022-08-02
1114

1215
- Add `feature_peripheral` option which generates cfg features for each peripheral

src/generate/peripheral.rs

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,40 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
222222
Ok(out)
223223
}
224224

225+
#[derive(Clone, Debug)]
226+
pub struct ArrayAccessor {
227+
pub doc: String,
228+
pub name: Ident,
229+
pub ty: syn::Type,
230+
pub basename: Ident,
231+
pub i: syn::LitInt,
232+
}
233+
234+
impl ArrayAccessor {
235+
pub fn to_tokens(&self, method: bool) -> TokenStream {
236+
let parens = method.then(|| quote! {()});
237+
let doc = &self.doc;
238+
let name = &self.name;
239+
let ty = &self.ty;
240+
let basename = &self.basename;
241+
let i = &self.i;
242+
quote! {
243+
#[doc = #doc]
244+
#[inline(always)]
245+
pub fn #name(&self) -> &#ty {
246+
&self.#basename#parens[#i]
247+
}
248+
}
249+
}
250+
}
251+
225252
#[derive(Clone, Debug)]
226253
struct RegisterBlockField {
227254
syn_field: syn::Field,
228255
description: String,
229256
offset: u32,
230257
size: u32,
231-
accessors: Option<TokenStream>,
258+
accessors: Vec<ArrayAccessor>,
232259
}
233260

234261
#[derive(Clone, Debug)]
@@ -471,9 +498,6 @@ fn register_or_cluster_block(
471498

472499
for reg_block_field in &ercs_expanded {
473500
regions.add(reg_block_field)?;
474-
if let Some(ts) = &reg_block_field.accessors {
475-
accessors.extend(ts.clone());
476-
}
477501
}
478502

479503
// We need to compute the idents of each register/union block first to make sure no conflicts exists.
@@ -524,6 +548,12 @@ fn register_or_cluster_block(
524548
reg_block_field.syn_field.to_tokens(&mut region_rbfs);
525549
Punct::new(',', Spacing::Alone).to_tokens(&mut region_rbfs);
526550
}
551+
accessors.extend(
552+
reg_block_field
553+
.accessors
554+
.iter()
555+
.map(|a| a.to_tokens(is_region_a_union)),
556+
);
527557
}
528558

529559
if !is_region_a_union {
@@ -670,7 +700,7 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
670700
let mut cluster_expanded = vec![];
671701

672702
let cluster_size = cluster_info_size_in_bits(cluster, config)
673-
.with_context(|| format!("Cluster {} has no determinable `size` field", cluster.name))?;
703+
.with_context(|| format!("Can't calculate cluster {} size", cluster.name))?;
674704
let description = cluster
675705
.description
676706
.as_ref()
@@ -692,12 +722,21 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
692722
description,
693723
offset: info.address_offset,
694724
size: cluster_size,
695-
accessors: None,
725+
accessors: Vec::new(),
696726
})
697727
}
698728
Cluster::Array(info, array_info) => {
699-
let sequential_addresses =
700-
(array_info.dim == 1) || (cluster_size == array_info.dim_increment * BITS_PER_BYTE);
729+
let increment_bits = array_info.dim_increment * BITS_PER_BYTE;
730+
if cluster_size > increment_bits {
731+
let cname = &cluster.name;
732+
return Err(anyhow!("Cluster {cname} has size {cluster_size} bits that is more then array increment {increment_bits} bits"));
733+
}
734+
let cluster_size = if config.max_cluster_size {
735+
increment_bits
736+
} else {
737+
cluster_size
738+
};
739+
let sequential_addresses = (array_info.dim == 1) || (cluster_size == increment_bits);
701740

702741
// if dimIndex exists, test if it is a sequence of numbers from 0 to dim
703742
let sequential_indexes_from0 = array_info
@@ -717,10 +756,10 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
717756

718757
if array_convertible {
719758
let accessors = if sequential_indexes_from0 {
720-
None
759+
Vec::new()
721760
} else {
722761
let span = Span::call_site();
723-
let mut accessors = TokenStream::new();
762+
let mut accessors = Vec::new();
724763
let nb_name_cs = ty_name.to_snake_case_ident(span);
725764
for (i, idx) in array_info.indexes().enumerate() {
726765
let idx_name =
@@ -731,15 +770,15 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
731770
&description,
732771
);
733772
let i = unsuffixed(i as _);
734-
accessors.extend(quote! {
735-
#[doc = #comment]
736-
#[inline(always)]
737-
pub fn #idx_name(&self) -> &#ty {
738-
&self.#nb_name_cs[#i]
739-
}
773+
accessors.push(ArrayAccessor {
774+
doc: comment,
775+
name: idx_name,
776+
ty: ty.clone(),
777+
basename: nb_name_cs.clone(),
778+
i,
740779
});
741780
}
742-
Some(accessors)
781+
accessors
743782
};
744783
let array_ty = new_syn_array(ty, array_info.dim);
745784
cluster_expanded.push(RegisterBlockField {
@@ -763,7 +802,7 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
763802
description: info.description.as_ref().unwrap_or(&info.name).into(),
764803
offset: info.address_offset,
765804
size: 0,
766-
accessors: None,
805+
accessors: Vec::new(),
767806
});
768807
} else {
769808
for (field_num, idx) in array_info.indexes().enumerate() {
@@ -776,7 +815,7 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
776815
description: description.clone(),
777816
offset: info.address_offset + field_num as u32 * array_info.dim_increment,
778817
size: cluster_size,
779-
accessors: None,
818+
accessors: Vec::new(),
780819
});
781820
}
782821
}
@@ -813,7 +852,7 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
813852
description,
814853
offset: info.address_offset,
815854
size: register_size,
816-
accessors: None,
855+
accessors: Vec::new(),
817856
})
818857
}
819858
Register::Array(info, array_info) => {
@@ -838,10 +877,10 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
838877
.is_some();
839878

840879
let accessors = if sequential_indexes_from0 {
841-
None
880+
Vec::new()
842881
} else {
843882
let span = Span::call_site();
844-
let mut accessors = TokenStream::new();
883+
let mut accessors = Vec::new();
845884
let nb_name_cs = ty_name.to_snake_case_ident(span);
846885
for (i, idx) in array_info.indexes().enumerate() {
847886
let idx_name =
@@ -852,15 +891,15 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
852891
&description,
853892
);
854893
let i = unsuffixed(i as _);
855-
accessors.extend(quote! {
856-
#[doc = #comment]
857-
#[inline(always)]
858-
pub fn #idx_name(&self) -> &#ty {
859-
&self.#nb_name_cs[#i]
860-
}
894+
accessors.push(ArrayAccessor {
895+
doc: comment,
896+
name: idx_name,
897+
ty: ty.clone(),
898+
basename: nb_name_cs.clone(),
899+
i,
861900
});
862901
}
863-
Some(accessors)
902+
accessors
864903
};
865904
let array_ty = new_syn_array(ty, array_info.dim);
866905
let syn_field =
@@ -883,7 +922,7 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
883922
description: description.clone(),
884923
offset: info.address_offset + field_num as u32 * array_info.dim_increment,
885924
size: register_size,
886-
accessors: None,
925+
accessors: Vec::new(),
887926
});
888927
}
889928
}

src/main.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ fn run() -> Result<()> {
8585
.long("feature_peripheral")
8686
.help("Use independent cfg feature flags for each peripheral"),
8787
)
88+
.arg(
89+
Arg::with_name("max_cluster_size")
90+
.long("max_cluster_size")
91+
.help("Use array increment for cluster size"),
92+
)
8893
.arg(
8994
Arg::with_name("make_mod")
9095
.long("make_mod")
@@ -183,6 +188,8 @@ fn run() -> Result<()> {
183188
cfg.bool_flag("feature_group", Filter::Arg) || cfg.bool_flag("feature_group", Filter::Conf);
184189
let feature_peripheral = cfg.bool_flag("feature_peripheral", Filter::Arg)
185190
|| cfg.bool_flag("feature_peripheral", Filter::Conf);
191+
let max_cluster_size = cfg.bool_flag("max_cluster_size", Filter::Arg)
192+
|| cfg.bool_flag("max_cluster_size", Filter::Conf);
186193

187194
let mut source_type = cfg
188195
.grab()
@@ -209,6 +216,7 @@ fn run() -> Result<()> {
209216
derive_more,
210217
feature_group,
211218
feature_peripheral,
219+
max_cluster_size,
212220
output_dir: path.clone(),
213221
source_type,
214222
};

src/util.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub const BITS_PER_BYTE: u32 = 8;
2222
/// that are not valid in Rust ident
2323
const BLACKLIST_CHARS: &[char] = &['(', ')', '[', ']', '/', ' ', '-'];
2424

25-
#[derive(Clone, PartialEq, Debug)]
25+
#[derive(Clone, PartialEq, Eq, Debug)]
2626
pub struct Config {
2727
pub target: Target,
2828
pub nightly: bool,
@@ -36,6 +36,7 @@ pub struct Config {
3636
pub derive_more: bool,
3737
pub feature_group: bool,
3838
pub feature_peripheral: bool,
39+
pub max_cluster_size: bool,
3940
pub output_dir: PathBuf,
4041
pub source_type: SourceType,
4142
}
@@ -55,6 +56,7 @@ impl Default for Config {
5556
derive_more: false,
5657
feature_group: false,
5758
feature_peripheral: false,
59+
max_cluster_size: false,
5860
output_dir: PathBuf::from("."),
5961
source_type: SourceType::default(),
6062
}
@@ -63,7 +65,7 @@ impl Default for Config {
6365

6466
#[allow(clippy::upper_case_acronyms)]
6567
#[allow(non_camel_case_types)]
66-
#[derive(Clone, Copy, PartialEq, Debug)]
68+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
6769
pub enum Target {
6870
CortexM,
6971
Msp430,
@@ -93,7 +95,7 @@ impl Default for Target {
9395
}
9496
}
9597

96-
#[derive(Clone, Copy, PartialEq, Debug)]
98+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
9799
pub enum SourceType {
98100
Xml,
99101
#[cfg(feature = "yaml")]

0 commit comments

Comments
 (0)