Skip to content

Commit 4850a80

Browse files
bors[bot]burrbull
andauthored
Merge #579
579: array accessors r=Emilgardis a=burrbull Closes #578 Co-authored-by: Andrey Zgarbul <zgarbul.andrey@gmail.com>
2 parents 8515d40 + 8d643bd commit 4850a80

File tree

2 files changed

+127
-61
lines changed

2 files changed

+127
-61
lines changed

CHANGELOG.md

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

1010
### Changed
1111

12+
- Generate Rust arrays for all register & cluster arrays with sequential_addresses.
13+
If their indices don't start from 0 add accessors with right names.
1214
- Bring documentation on how to generate MSP430 PACs up to date (in line with
1315
[msp430_svd](https://github.com/pftbest/msp430_svd)).
1416

src/generate/peripheral.rs

Lines changed: 125 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use quote::{quote, ToTokens};
1212
use syn::{parse_str, Token};
1313

1414
use crate::util::{
15-
self, handle_cluster_error, handle_reg_error, Config, FullName, ToSanitizedSnakeCase,
16-
ToSanitizedUpperCase, BITS_PER_BYTE,
15+
self, handle_cluster_error, handle_reg_error, unsuffixed, Config, FullName,
16+
ToSanitizedSnakeCase, ToSanitizedUpperCase, BITS_PER_BYTE,
1717
};
1818
use anyhow::{anyhow, bail, Context, Result};
1919

@@ -219,6 +219,7 @@ struct RegisterBlockField {
219219
description: String,
220220
offset: u32,
221221
size: u32,
222+
accessors: Option<TokenStream>,
222223
}
223224

224225
#[derive(Clone, Debug)]
@@ -435,6 +436,23 @@ impl FieldRegions {
435436
}
436437
}
437438

439+
fn make_comment(size: u32, offset: u32, description: &str) -> String {
440+
if size > 32 {
441+
format!(
442+
"0x{:02x}..0x{:02x} - {}",
443+
offset,
444+
offset + size / 8,
445+
util::escape_brackets(&util::respace(description)),
446+
)
447+
} else {
448+
format!(
449+
"0x{:02x} - {}",
450+
offset,
451+
util::escape_brackets(&util::respace(description)),
452+
)
453+
}
454+
}
455+
438456
fn register_or_cluster_block(
439457
ercs: &[RegisterCluster],
440458
defs: &RegisterProperties,
@@ -443,7 +461,6 @@ fn register_or_cluster_block(
443461
) -> Result<TokenStream> {
444462
let mut rbfs = TokenStream::new();
445463
let mut accessors = TokenStream::new();
446-
let mut have_accessors = false;
447464

448465
let ercs_expanded = expand(ercs, defs, name, config)
449466
.with_context(|| "Could not expand register or cluster block")?;
@@ -453,6 +470,9 @@ fn register_or_cluster_block(
453470

454471
for reg_block_field in &ercs_expanded {
455472
regions.add(reg_block_field)?;
473+
if let Some(ts) = &reg_block_field.accessors {
474+
accessors.extend(ts.clone());
475+
}
456476
}
457477

458478
// We need to compute the idents of each register/union block first to make sure no conflicts exists.
@@ -476,26 +496,16 @@ fn register_or_cluster_block(
476496
let is_region_a_union = region.is_union();
477497

478498
for reg_block_field in &region.rbfs {
479-
let comment = if reg_block_field.size > 32 {
480-
format!(
481-
"0x{:02x}..0x{:02x} - {}",
482-
reg_block_field.offset,
483-
reg_block_field.offset + reg_block_field.size / 8,
484-
util::escape_brackets(util::respace(&reg_block_field.description).as_ref()),
485-
)
486-
} else {
487-
format!(
488-
"0x{:02x} - {}",
489-
reg_block_field.offset,
490-
util::escape_brackets(util::respace(&reg_block_field.description).as_ref()),
491-
)
492-
};
499+
let comment = make_comment(
500+
reg_block_field.size,
501+
reg_block_field.offset,
502+
&reg_block_field.description,
503+
);
493504

494505
if is_region_a_union {
495506
let name = &reg_block_field.field.ident;
496507
let ty = &reg_block_field.field.ty;
497508
let offset = reg_block_field.offset as usize;
498-
have_accessors = true;
499509
accessors.extend(quote! {
500510
#[doc = #comment]
501511
#[inline(always)]
@@ -556,7 +566,7 @@ fn register_or_cluster_block(
556566
span,
557567
);
558568

559-
let accessors = if have_accessors {
569+
let accessors = if !accessors.is_empty() {
560570
quote! {
561571
impl #name {
562572
#accessors
@@ -700,6 +710,7 @@ fn expand_cluster(
700710
description: info.description.as_ref().unwrap_or(&info.name).into(),
701711
offset: info.address_offset,
702712
size: cluster_size,
713+
accessors: None,
703714
}),
704715
Cluster::Array(info, array_info) => {
705716
let sequential_addresses = cluster_size == array_info.dim_increment * BITS_PER_BYTE;
@@ -720,15 +731,51 @@ fn expand_cluster(
720731
false => true,
721732
};
722733

723-
let array_convertible = sequential_indexes && sequential_addresses && convert_list;
734+
let array_convertible = sequential_addresses && convert_list;
724735

725736
if array_convertible {
726-
cluster_expanded.push(RegisterBlockField {
727-
field: convert_svd_cluster(cluster, name)?,
728-
description: info.description.as_ref().unwrap_or(&info.name).into(),
729-
offset: info.address_offset,
730-
size: cluster_size * array_info.dim,
731-
});
737+
if sequential_indexes {
738+
cluster_expanded.push(RegisterBlockField {
739+
field: convert_svd_cluster(cluster, name)?,
740+
description: info.description.as_ref().unwrap_or(&info.name).into(),
741+
offset: info.address_offset,
742+
size: cluster_size * array_info.dim,
743+
accessors: None,
744+
});
745+
} else {
746+
let mut accessors = TokenStream::new();
747+
let nb_name = util::replace_suffix(&info.name, "");
748+
let ty = name_to_wrapped_ty(&nb_name, name)?;
749+
let nb_name_cs =
750+
Ident::new(&nb_name.to_sanitized_snake_case(), Span::call_site());
751+
let description = info.description.as_ref().unwrap_or(&info.name);
752+
for (i, idx) in array_info.indexes().enumerate() {
753+
let idx_name = Ident::new(
754+
&util::replace_suffix(&info.name, &idx).to_sanitized_snake_case(),
755+
Span::call_site(),
756+
);
757+
let comment = make_comment(
758+
cluster_size,
759+
info.address_offset + (i as u32) * cluster_size / 8,
760+
description,
761+
);
762+
let i = unsuffixed(i as _);
763+
accessors.extend(quote! {
764+
#[doc = #comment]
765+
#[inline(always)]
766+
pub fn #idx_name(&self) -> &#ty {
767+
&self.#nb_name_cs[#i]
768+
}
769+
});
770+
}
771+
cluster_expanded.push(RegisterBlockField {
772+
field: convert_svd_cluster(cluster, name)?,
773+
description: description.into(),
774+
offset: info.address_offset,
775+
size: cluster_size * array_info.dim,
776+
accessors: Some(accessors),
777+
});
778+
}
732779
} else if sequential_indexes && config.const_generic {
733780
// Include a ZST ArrayProxy giving indexed access to the
734781
// elements.
@@ -740,6 +787,7 @@ fn expand_cluster(
740787
description: info.description.as_ref().unwrap_or(&info.name).into(),
741788
offset: info.address_offset + field_num as u32 * array_info.dim_increment,
742789
size: cluster_size,
790+
accessors: None,
743791
});
744792
}
745793
}
@@ -772,6 +820,7 @@ fn expand_register(
772820
description: info.description.clone().unwrap_or_default(),
773821
offset: info.address_offset,
774822
size: register_size,
823+
accessors: None,
775824
}),
776825
Register::Array(info, array_info) => {
777826
let sequential_addresses = register_size == array_info.dim_increment * BITS_PER_BYTE;
@@ -792,15 +841,52 @@ fn expand_register(
792841
false => true,
793842
};
794843

795-
let array_convertible = sequential_indexes && sequential_addresses && convert_list;
844+
let array_convertible = sequential_addresses && convert_list;
796845

797846
if array_convertible {
798-
register_expanded.push(RegisterBlockField {
799-
field: convert_svd_register(register, name, config.ignore_groups)?,
800-
description: info.description.clone().unwrap_or_default(),
801-
offset: info.address_offset,
802-
size: register_size * array_info.dim,
803-
});
847+
if sequential_indexes {
848+
register_expanded.push(RegisterBlockField {
849+
field: convert_svd_register(register, name, config.ignore_groups)?,
850+
description: info.description.clone().unwrap_or_default(),
851+
offset: info.address_offset,
852+
size: register_size * array_info.dim,
853+
accessors: None,
854+
});
855+
} else {
856+
let mut accessors = TokenStream::new();
857+
let nb_name = util::replace_suffix(&info.fullname(config.ignore_groups), "");
858+
let ty = name_to_wrapped_ty(&nb_name, name)?;
859+
let nb_name_cs =
860+
Ident::new(&nb_name.to_sanitized_snake_case(), Span::call_site());
861+
let description = info.description.clone().unwrap_or_default();
862+
for (i, idx) in array_info.indexes().enumerate() {
863+
let idx_name = Ident::new(
864+
&util::replace_suffix(&info.fullname(config.ignore_groups), &idx)
865+
.to_sanitized_snake_case(),
866+
Span::call_site(),
867+
);
868+
let comment = make_comment(
869+
register_size,
870+
info.address_offset + (i as u32) * register_size / 8,
871+
&description,
872+
);
873+
let i = unsuffixed(i as _);
874+
accessors.extend(quote! {
875+
#[doc = #comment]
876+
#[inline(always)]
877+
pub fn #idx_name(&self) -> &#ty {
878+
&self.#nb_name_cs[#i]
879+
}
880+
});
881+
}
882+
register_expanded.push(RegisterBlockField {
883+
field: convert_svd_register(register, name, config.ignore_groups)?,
884+
description,
885+
offset: info.address_offset,
886+
size: register_size * array_info.dim,
887+
accessors: Some(accessors),
888+
});
889+
}
804890
} else {
805891
for (field_num, field) in expand_svd_register(register, name, config.ignore_groups)?
806892
.iter()
@@ -811,6 +897,7 @@ fn expand_register(
811897
description: info.description.clone().unwrap_or_default(),
812898
offset: info.address_offset + field_num as u32 * array_info.dim_increment,
813899
size: register_size,
900+
accessors: None,
814901
});
815902
}
816903
}
@@ -893,22 +980,10 @@ fn expand_svd_register(
893980
match register {
894981
Register::Single(_info) => out.push(convert_svd_register(register, name, ignore_group)?),
895982
Register::Array(info, array_info) => {
896-
let indices = array_info
897-
.dim_index
898-
.as_ref()
899-
.map(|v| Cow::from(&**v))
900-
.unwrap_or_else(|| {
901-
Cow::from(
902-
(0..array_info.dim)
903-
.map(|i| i.to_string())
904-
.collect::<Vec<_>>(),
905-
)
906-
});
907-
908983
let ty_name = util::replace_suffix(&info.fullname(ignore_group), "");
909984

910-
for (idx, _i) in indices.iter().zip(0..) {
911-
let nb_name = util::replace_suffix(&info.fullname(ignore_group), idx);
985+
for idx in array_info.indexes() {
986+
let nb_name = util::replace_suffix(&info.fullname(ignore_group), &idx);
912987

913988
let ty = name_to_wrapped_ty(&ty_name, name)?;
914989

@@ -968,6 +1043,7 @@ fn array_proxy(
9681043
description: info.description.as_ref().unwrap_or(&info.name).into(),
9691044
offset: info.address_offset,
9701045
size: 0,
1046+
accessors: None,
9711047
})
9721048
}
9731049

@@ -982,22 +1058,10 @@ fn expand_svd_cluster(
9821058
match &cluster {
9831059
Cluster::Single(_info) => out.push(convert_svd_cluster(cluster, name)?),
9841060
Cluster::Array(info, array_info) => {
985-
let indices = array_info
986-
.dim_index
987-
.as_ref()
988-
.map(|v| Cow::from(&**v))
989-
.unwrap_or_else(|| {
990-
Cow::from(
991-
(0..array_info.dim)
992-
.map(|i| i.to_string())
993-
.collect::<Vec<_>>(),
994-
)
995-
});
996-
9971061
let ty_name = util::replace_suffix(&info.name, "");
9981062

999-
for (idx, _i) in indices.iter().zip(0..) {
1000-
let nb_name = util::replace_suffix(&info.name, idx);
1063+
for idx in array_info.indexes() {
1064+
let nb_name = util::replace_suffix(&info.name, &idx);
10011065

10021066
let ty = name_to_ty(&ty_name, name)?;
10031067

0 commit comments

Comments
 (0)