11use anyhow:: { anyhow, Context } ;
22use svd_parser:: svd:: {
3- BitRange , DimElement , EnumeratedValues , Field , FieldInfo , Register , RegisterInfo , Usage ,
4- WriteConstraint , WriteConstraintRange ,
3+ BitRange , DimElement , EnumeratedValues , Field , FieldInfo , ModifiedWriteValues , ReadAction ,
4+ Register , RegisterInfo , Usage , WriteConstraint , WriteConstraintRange ,
55} ;
66use yaml_rust:: { yaml:: Hash , Yaml } ;
77
@@ -58,6 +58,12 @@ pub trait RegisterExt {
5858 usage : Usage ,
5959 ) -> PatchResult ;
6060
61+ /// Set readAction for field
62+ fn set_field_read_action ( & mut self , fspec : & str , action : ReadAction ) ;
63+
64+ /// Set modifiedWriteValues for field
65+ fn set_field_modified_write_values ( & mut self , fspec : & str , mwv : ModifiedWriteValues ) ;
66+
6167 /// Add a writeConstraint range given by field to all fspec in rtag
6268 fn process_field_range ( & mut self , pname : & str , fspec : & str , fmod : & [ Yaml ] ) -> PatchResult ;
6369
@@ -452,21 +458,67 @@ impl RegisterExt for Register {
452458 }
453459
454460 fn process_field ( & mut self , pname : & str , fspec : & str , fmod : & Yaml ) -> PatchResult {
461+ const READ_KEYS : [ & str ; 5 ] = [ "_read" , "_RM" , "_RS" , "_RC" , "_RME" ] ;
462+ const READ_VALS : [ Option < ReadAction > ; 5 ] = [
463+ None ,
464+ Some ( ReadAction :: Modify ) ,
465+ Some ( ReadAction :: Set ) ,
466+ Some ( ReadAction :: Clear ) ,
467+ Some ( ReadAction :: ModifyExternal ) ,
468+ ] ;
469+ const WRITE_KEYS : [ & str ; 10 ] = [
470+ "_write" , "_WM" , "_WS" , "_WC" , "_W1S" , "_W0C" , "_W1C" , "_W0S" , "_W1T" , "_W0T" ,
471+ ] ;
472+ const WRITE_VALS : [ Option < ModifiedWriteValues > ; 10 ] = [
473+ None ,
474+ Some ( ModifiedWriteValues :: Modify ) ,
475+ Some ( ModifiedWriteValues :: Set ) ,
476+ Some ( ModifiedWriteValues :: Clear ) ,
477+ Some ( ModifiedWriteValues :: OneToSet ) ,
478+ Some ( ModifiedWriteValues :: ZeroToClear ) ,
479+ Some ( ModifiedWriteValues :: OneToClear ) ,
480+ Some ( ModifiedWriteValues :: ZeroToSet ) ,
481+ Some ( ModifiedWriteValues :: OneToToggle ) ,
482+ Some ( ModifiedWriteValues :: ZeroToToggle ) ,
483+ ] ;
455484 match fmod {
456485 Yaml :: Hash ( fmod) => {
457- let is_read = fmod. get_hash ( "_read" ) ?;
458- let is_write = fmod. get_hash ( "_write" ) ?;
459- if is_read. is_none ( ) && is_write. is_none ( ) {
486+ let is_read = READ_KEYS
487+ . iter ( )
488+ . any ( |key| fmod. contains_key ( & key. to_yaml ( ) ) ) ;
489+ let is_write = WRITE_KEYS
490+ . iter ( )
491+ . any ( |key| fmod. contains_key ( & key. to_yaml ( ) ) ) ;
492+ if !is_read && !is_write {
460493 self . process_field_enum ( pname, fspec, fmod, Usage :: ReadWrite )
461494 . with_context ( || "Adding read-write enumeratedValues" ) ?;
462495 } else {
463- if let Some ( fmod) = is_read {
464- self . process_field_enum ( pname, fspec, fmod, Usage :: Read )
465- . with_context ( || "Adding read-only enumeratedValues" ) ?;
496+ if is_read {
497+ for ( key, action) in READ_KEYS . into_iter ( ) . zip ( READ_VALS . into_iter ( ) ) {
498+ if let Some ( fmod) = fmod. get_hash ( key) ? {
499+ if !fmod. is_empty ( ) {
500+ self . process_field_enum ( pname, fspec, fmod, Usage :: Read )
501+ . with_context ( || "Adding read-only enumeratedValues" ) ?;
502+ }
503+ if let Some ( action) = action {
504+ self . set_field_read_action ( fspec, action) ;
505+ }
506+ break ;
507+ }
508+ }
466509 }
467- if let Some ( fmod) = is_write {
468- self . process_field_enum ( pname, fspec, fmod, Usage :: Write )
469- . with_context ( || "Adding write-only enumeratedValues" ) ?;
510+ if is_write {
511+ for ( key, mwv) in WRITE_KEYS . into_iter ( ) . zip ( WRITE_VALS . into_iter ( ) ) {
512+ if let Some ( fmod) = fmod. get_hash ( key) ? {
513+ if !fmod. is_empty ( ) {
514+ self . process_field_enum ( pname, fspec, fmod, Usage :: Write )
515+ . with_context ( || "Adding write-only enumeratedValues" ) ?;
516+ }
517+ if let Some ( mwv) = mwv {
518+ self . set_field_modified_write_values ( fspec, mwv) ;
519+ }
520+ }
521+ }
470522 }
471523 }
472524 }
@@ -479,6 +531,26 @@ impl RegisterExt for Register {
479531 Ok ( ( ) )
480532 }
481533
534+ fn set_field_read_action ( & mut self , fspec : & str , action : ReadAction ) {
535+ for ftag in self . iter_fields ( fspec) {
536+ ftag. read_action = if action == ReadAction :: Modify {
537+ None
538+ } else {
539+ Some ( action)
540+ } ;
541+ }
542+ }
543+
544+ fn set_field_modified_write_values ( & mut self , fspec : & str , mwv : ModifiedWriteValues ) {
545+ for ftag in self . iter_fields ( fspec) {
546+ ftag. modified_write_values = if mwv == ModifiedWriteValues :: Modify {
547+ None
548+ } else {
549+ Some ( mwv)
550+ } ;
551+ }
552+ }
553+
482554 fn process_field_enum (
483555 & mut self ,
484556 pname : & str ,
0 commit comments