@@ -2,7 +2,9 @@ use std::borrow::Cow;
2
2
use std:: cmp:: Ordering ;
3
3
use std:: collections:: HashMap ;
4
4
5
- use crate :: svd:: { Cluster , ClusterInfo , Peripheral , Register , RegisterCluster , RegisterProperties } ;
5
+ use crate :: svd:: {
6
+ Cluster , ClusterInfo , DimElement , Peripheral , Register , RegisterCluster , RegisterProperties ,
7
+ } ;
6
8
use log:: warn;
7
9
use proc_macro2:: TokenStream ;
8
10
use proc_macro2:: { Ident , Punct , Spacing , Span } ;
@@ -184,7 +186,9 @@ pub fn render(
184
186
185
187
// Push any register or cluster blocks into the output
186
188
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
+ ) ?) ;
188
192
189
193
// Push all cluster related information into the peripheral module
190
194
for c in & clusters {
@@ -445,6 +449,7 @@ impl FieldRegions {
445
449
446
450
fn register_or_cluster_block (
447
451
ercs : & [ RegisterCluster ] ,
452
+ dim : Option < & DimElement > ,
448
453
defs : & RegisterProperties ,
449
454
name : Option < & str > ,
450
455
config : & Config ,
@@ -555,6 +560,18 @@ fn register_or_cluster_block(
555
560
last_end = region. end ;
556
561
}
557
562
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
+
558
575
let name = Ident :: new (
559
576
& match name {
560
577
Some ( name) => name. to_sanitized_upper_case ( ) ,
@@ -620,14 +637,7 @@ fn cluster_size_in_bits(
620
637
// dimIncrement and the size of the array items, then the array
621
638
// will get expanded in expand_cluster below. The overall size
622
639
// 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 ) ,
631
641
}
632
642
}
633
643
@@ -671,19 +681,20 @@ fn expand_cluster(
671
681
672
682
let defs = cluster. default_register_properties . derive_from ( defs) ;
673
683
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
-
677
684
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
+ }
684
697
Cluster :: Array ( info, array_info) => {
685
- let sequential_addresses = cluster_size == array_info. dim_increment * BITS_PER_BYTE ;
686
-
687
698
// if dimIndex exists, test if it is a sequence of numbers from 0 to dim
688
699
let sequential_indexes = array_info. dim_index . as_ref ( ) . map_or ( true , |dim_index| {
689
700
dim_index
@@ -692,22 +703,20 @@ fn expand_cluster(
692
703
. eq ( ( 0 ..array_info. dim ) . map ( Ok ) )
693
704
} ) ;
694
705
695
- let array_convertible = sequential_indexes && sequential_addresses;
696
-
697
- if array_convertible {
706
+ if sequential_indexes {
698
707
cluster_expanded. push ( RegisterBlockField {
699
708
field : convert_svd_cluster ( & cluster, name) ?,
700
709
description : info. description . as_ref ( ) . unwrap_or ( & info. name ) . into ( ) ,
701
710
offset : info. address_offset ,
702
- size : cluster_size * array_info. dim ,
711
+ size : array_info . dim_increment * array_info. dim * BITS_PER_BYTE ,
703
712
} ) ;
704
713
} else {
705
714
for ( field_num, field) in expand_svd_cluster ( cluster, name) ?. iter ( ) . enumerate ( ) {
706
715
cluster_expanded. push ( RegisterBlockField {
707
716
field : field. clone ( ) ,
708
717
description : info. description . as_ref ( ) . unwrap_or ( & info. name ) . into ( ) ,
709
718
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 ,
711
720
} ) ;
712
721
}
713
722
}
@@ -804,7 +813,13 @@ fn cluster_block(
804
813
805
814
let defaults = c. default_register_properties . derive_from ( defaults) ;
806
815
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) ?;
808
823
809
824
// Generate definition for each of the registers.
810
825
let registers = util:: only_registers ( & c. children ) ;
0 commit comments