@@ -12,8 +12,8 @@ use quote::{quote, ToTokens};
1212use syn:: { parse_str, Token } ;
1313
1414use 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} ;
1818use 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+
438456fn 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