@@ -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 > {
@@ -852,3 +857,55 @@ impl Interpolate for FieldPath {
852
857
cow
853
858
}
854
859
}
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