@@ -473,7 +473,8 @@ fn make_field(fadd: &Hash, rpath: Option<&RegisterPath>) -> Result<FieldInfoBuil
473473 fadd. get_str ( "modifiedWriteValues" ) ?
474474 . and_then ( ModifiedWriteValues :: parse_str) ,
475475 )
476- . read_action ( fadd. get_str ( "readAction" ) ?. and_then ( ReadAction :: parse_str) ) ;
476+ . read_action ( fadd. get_str ( "readAction" ) ?. and_then ( ReadAction :: parse_str) )
477+ . write_constraint ( get_write_constraint ( fadd) ?) ;
477478
478479 if let Some ( name) = fadd. get_str ( "name" ) ? {
479480 fnew = fnew. name ( name. into ( ) ) ;
@@ -503,6 +504,7 @@ fn make_register(radd: &Hash, path: Option<&BlockPath>) -> Result<RegisterInfoBu
503504 . alternate_group ( radd. get_string ( "alternateGroup" ) ?)
504505 . alternate_register ( radd. get_string ( "alternateRegister" ) ?)
505506 . properties ( get_register_properties ( radd) ?)
507+ . write_constraint ( get_write_constraint ( radd) ?)
506508 . fields ( match radd. get_hash ( "fields" ) ? {
507509 Some ( h) => {
508510 let mut fields = Vec :: new ( ) ;
@@ -526,32 +528,35 @@ fn make_register(radd: &Hash, path: Option<&BlockPath>) -> Result<RegisterInfoBu
526528 rnew = rnew. address_offset ( address_offset as u32 ) ;
527529 }
528530
529- if let Some ( write_constraint) = radd
531+ Ok ( rnew)
532+ }
533+
534+ fn get_write_constraint ( h : & Hash ) -> Result < Option < WriteConstraint > > {
535+ if let Some ( write_constraint) = h
530536 . get_yaml ( "_write_constraint" )
531- . or_else ( || radd . get_yaml ( "writeConstraint" ) )
537+ . or_else ( || h . get_yaml ( "writeConstraint" ) )
532538 {
533- let wc = match write_constraint {
539+ match write_constraint {
534540 Yaml :: String ( s) if s == "none" => {
535541 // Completely remove the existing writeConstraint
536- None
542+ Ok ( None )
537543 }
538544 Yaml :: String ( s) if s == "enum" => {
539545 // Only allow enumerated values
540- Some ( WriteConstraint :: UseEnumeratedValues ( true ) )
546+ Ok ( Some ( WriteConstraint :: UseEnumeratedValues ( true ) ) )
541547 }
542548 Yaml :: Array ( a) => {
543549 // Allow a certain range
544- Some ( WriteConstraint :: Range ( WriteConstraintRange {
550+ Ok ( Some ( WriteConstraint :: Range ( WriteConstraintRange {
545551 min : a[ 0 ] . i64 ( ) ? as u64 ,
546552 max : a[ 1 ] . i64 ( ) ? as u64 ,
547- } ) )
553+ } ) ) )
548554 }
549- _ => return Err ( anyhow ! ( "Unknown writeConstraint type {write_constraint:?}" ) ) ,
550- } ;
551- rnew = rnew. write_constraint ( wc) ;
555+ _ => Err ( anyhow ! ( "Unknown writeConstraint type {write_constraint:?}" ) ) ,
556+ }
557+ } else {
558+ Ok ( None )
552559 }
553-
554- Ok ( rnew)
555560}
556561
557562fn make_cluster ( cadd : & Hash , path : Option < & BlockPath > ) -> Result < ClusterInfoBuilder > {
@@ -856,3 +861,55 @@ impl Interpolate for FieldPath {
856861 cow
857862 }
858863}
864+
865+ #[ cfg( test) ]
866+ mod tests {
867+ use super :: * ;
868+ use crate :: test_utils;
869+ use std:: path:: Path ;
870+
871+ #[ test]
872+ fn add_register ( ) -> Result < ( ) > {
873+ let ( mut device, yaml) = test_utils:: get_patcher ( Path :: new ( "add_register" ) ) . unwrap ( ) ;
874+ assert_eq ! ( device. peripherals. len( ) , 1 ) ;
875+ let registers = device. peripherals [ 0 ]
876+ . registers
877+ . as_ref ( )
878+ . ok_or ( anyhow ! ( "no registers" ) ) ?;
879+ assert_eq ! ( registers. len( ) , 1 ) ;
880+
881+ device. process ( & yaml, & Default :: default ( ) ) . unwrap ( ) ;
882+ assert_eq ! ( device. peripherals. len( ) , 1 ) ;
883+ let periph1 = & device. peripherals [ 0 ] ;
884+ assert_eq ! ( periph1. name, "DAC1" ) ;
885+ let registers = device. peripherals [ 0 ]
886+ . registers
887+ . as_ref ( )
888+ . ok_or ( anyhow ! ( "no registers" ) ) ?;
889+ assert_eq ! ( registers. len( ) , 2 ) ;
890+ let reg2 = match & registers[ 1 ] {
891+ RegisterCluster :: Register ( r) => r,
892+ RegisterCluster :: Cluster ( _) => return Err ( anyhow ! ( "expected register, found cluster" ) ) ,
893+ } ;
894+ assert_eq ! ( reg2. name, "ANOTHER_REG" ) ;
895+ assert_eq ! ( reg2. address_offset, 4 ) ;
896+ assert_eq ! ( reg2. properties. size, Some ( 32 ) ) ;
897+ assert_eq ! ( reg2. write_constraint, None ) ;
898+ let fields = reg2. fields . as_ref ( ) . ok_or ( anyhow ! ( "no fields" ) ) ?;
899+ assert_eq ! ( fields. len( ) , 1 ) ;
900+ let field1 = & fields[ 0 ] ;
901+ assert_eq ! ( field1. name, "MPS" ) ;
902+ assert_eq ! ( field1. bit_offset( ) , 0 ) ;
903+ assert_eq ! ( field1. bit_width( ) , 5 ) ;
904+ assert_eq ! ( field1. access, Some ( Access :: ReadWrite ) ) ;
905+ assert_eq ! (
906+ field1. write_constraint,
907+ Some ( WriteConstraint :: Range ( WriteConstraintRange {
908+ min: 0 ,
909+ max: 0x1f
910+ } ) )
911+ ) ;
912+
913+ Ok ( ( ) )
914+ }
915+ }
0 commit comments