@@ -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 > {
@@ -852,3 +857,55 @@ impl Interpolate for FieldPath {
852857 cow
853858 }
854859}
860+
861+ #[ cfg( test) ]
862+ mod tests {
863+ use super :: * ;
864+ use crate :: test_utils;
865+ use std:: path:: Path ;
866+
867+ #[ test]
868+ fn add_register ( ) -> Result < ( ) > {
869+ let ( mut device, yaml) = test_utils:: get_patcher ( Path :: new ( "add_register" ) ) . unwrap ( ) ;
870+ assert_eq ! ( device. peripherals. len( ) , 1 ) ;
871+ let registers = device. peripherals [ 0 ]
872+ . registers
873+ . as_ref ( )
874+ . ok_or ( anyhow ! ( "no registers" ) ) ?;
875+ assert_eq ! ( registers. len( ) , 1 ) ;
876+
877+ device. process ( & yaml, & Default :: default ( ) ) . unwrap ( ) ;
878+ assert_eq ! ( device. peripherals. len( ) , 1 ) ;
879+ let periph1 = & device. peripherals [ 0 ] ;
880+ assert_eq ! ( periph1. name, "DAC1" ) ;
881+ let registers = device. peripherals [ 0 ]
882+ . registers
883+ . as_ref ( )
884+ . ok_or ( anyhow ! ( "no registers" ) ) ?;
885+ assert_eq ! ( registers. len( ) , 2 ) ;
886+ let reg2 = match & registers[ 1 ] {
887+ RegisterCluster :: Register ( r) => r,
888+ RegisterCluster :: Cluster ( _) => return Err ( anyhow ! ( "expected register, found cluster" ) ) ,
889+ } ;
890+ assert_eq ! ( reg2. name, "ANOTHER_REG" ) ;
891+ assert_eq ! ( reg2. address_offset, 4 ) ;
892+ assert_eq ! ( reg2. properties. size, Some ( 32 ) ) ;
893+ assert_eq ! ( reg2. write_constraint, None ) ;
894+ let fields = reg2. fields . as_ref ( ) . ok_or ( anyhow ! ( "no fields" ) ) ?;
895+ assert_eq ! ( fields. len( ) , 1 ) ;
896+ let field1 = & fields[ 0 ] ;
897+ assert_eq ! ( field1. name, "MPS" ) ;
898+ assert_eq ! ( field1. bit_offset( ) , 0 ) ;
899+ assert_eq ! ( field1. bit_width( ) , 5 ) ;
900+ assert_eq ! ( field1. access, Some ( Access :: ReadWrite ) ) ;
901+ assert_eq ! (
902+ field1. write_constraint,
903+ Some ( WriteConstraint :: Range ( WriteConstraintRange {
904+ min: 0 ,
905+ max: 0x1f
906+ } ) )
907+ ) ;
908+
909+ Ok ( ( ) )
910+ }
911+ }
0 commit comments