@@ -473,7 +473,8 @@ fn make_field(fadd: &Hash, rpath: Option<&RegisterPath>) -> Result<FieldInfoBuil
473
473
fadd. get_str ( "modifiedWriteValues" ) ?
474
474
. and_then ( ModifiedWriteValues :: parse_str) ,
475
475
)
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) ?) ;
477
478
478
479
if let Some ( name) = fadd. get_str ( "name" ) ? {
479
480
fnew = fnew. name ( name. into ( ) ) ;
@@ -503,6 +504,7 @@ fn make_register(radd: &Hash, path: Option<&BlockPath>) -> Result<RegisterInfoBu
503
504
. alternate_group ( radd. get_string ( "alternateGroup" ) ?)
504
505
. alternate_register ( radd. get_string ( "alternateRegister" ) ?)
505
506
. properties ( get_register_properties ( radd) ?)
507
+ . write_constraint ( get_write_constraint ( radd) ?)
506
508
. fields ( match radd. get_hash ( "fields" ) ? {
507
509
Some ( h) => {
508
510
let mut fields = Vec :: new ( ) ;
@@ -526,32 +528,35 @@ fn make_register(radd: &Hash, path: Option<&BlockPath>) -> Result<RegisterInfoBu
526
528
rnew = rnew. address_offset ( address_offset as u32 ) ;
527
529
}
528
530
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
530
536
. get_yaml ( "_write_constraint" )
531
- . or_else ( || radd . get_yaml ( "writeConstraint" ) )
537
+ . or_else ( || h . get_yaml ( "writeConstraint" ) )
532
538
{
533
- let wc = match write_constraint {
539
+ match write_constraint {
534
540
Yaml :: String ( s) if s == "none" => {
535
541
// Completely remove the existing writeConstraint
536
- None
542
+ Ok ( None )
537
543
}
538
544
Yaml :: String ( s) if s == "enum" => {
539
545
// Only allow enumerated values
540
- Some ( WriteConstraint :: UseEnumeratedValues ( true ) )
546
+ Ok ( Some ( WriteConstraint :: UseEnumeratedValues ( true ) ) )
541
547
}
542
548
Yaml :: Array ( a) => {
543
549
// Allow a certain range
544
- Some ( WriteConstraint :: Range ( WriteConstraintRange {
550
+ Ok ( Some ( WriteConstraint :: Range ( WriteConstraintRange {
545
551
min : a[ 0 ] . i64 ( ) ? as u64 ,
546
552
max : a[ 1 ] . i64 ( ) ? as u64 ,
547
- } ) )
553
+ } ) ) )
548
554
}
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 )
552
559
}
553
-
554
- Ok ( rnew)
555
560
}
556
561
557
562
fn make_cluster ( cadd : & Hash , path : Option < & BlockPath > ) -> Result < ClusterInfoBuilder > {
@@ -856,3 +861,55 @@ impl Interpolate for FieldPath {
856
861
cow
857
862
}
858
863
}
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