@@ -269,16 +269,27 @@ pub fn fields(
269
269
let fs = fields. iter ( ) . map ( F :: from) . collect :: < Result < Vec < _ > > > ( ) ?;
270
270
271
271
// TODO enumeratedValues
272
- if [ Access :: ReadOnly , Access :: ReadWriteOnce , Access :: ReadWrite ] . contains ( & access) {
273
- for f in & fs {
274
- if f. access == Some ( Access :: WriteOnly ) || f. access == Some ( Access :: WriteOnce ) {
275
- continue ;
276
- }
272
+ for f in & fs {
273
+ let can_read = [ Access :: ReadOnly , Access :: ReadWriteOnce , Access :: ReadWrite ] . contains ( & access) &&
274
+ ( f. access != Some ( Access :: WriteOnly ) ) &&
275
+ ( f. access != Some ( Access :: WriteOnce ) ) ;
276
+ let can_write = ( access != Access :: ReadOnly ) && ( f. access != Some ( Access :: ReadOnly ) ) ;
277
+
278
+ let bits = & f. bits ;
279
+ let mask = & f. mask ;
280
+ let offset = & f. offset ;
281
+ let fty = & f. ty ;
282
+
283
+ let lookup_results = lookup (
284
+ & f. evs ,
285
+ fields,
286
+ parent,
287
+ all_registers,
288
+ peripheral,
289
+ all_peripherals,
290
+ ) ?;
277
291
278
- let bits = & f. bits ;
279
- let mask = & f. mask ;
280
- let offset = & f. offset ;
281
- let fty = & f. ty ;
292
+ if can_read {
282
293
let cast = if f. width == 1 {
283
294
quote ! { != 0 }
284
295
} else {
@@ -288,49 +299,9 @@ pub fn fields(
288
299
( ( self . bits >> #offset) & #mask) #cast
289
300
} ;
290
301
291
- if let Some ( ( evs, base) ) = lookup (
292
- f. evs ,
293
- fields,
294
- parent,
295
- all_registers,
296
- peripheral,
297
- all_peripherals,
298
- Usage :: Read ,
299
- ) ? {
300
- struct Variant < ' a > {
301
- description : & ' a str ,
302
- pc : Ident ,
303
- sc : Ident ,
304
- value : u64 ,
305
- }
306
-
302
+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
307
303
let has_reserved_variant = evs. values . len ( ) != ( 1 << f. width ) ;
308
- let variants = evs. values
309
- . iter ( )
310
- // filter out all reserved variants, as we should not
311
- // generate code for them
312
- . filter ( |field| field. name . to_lowercase ( ) != "reserved" )
313
- . map ( |ev| {
314
- let sc =
315
- Ident :: from ( & * ev. name . to_sanitized_snake_case ( ) ) ;
316
- let description = ev. description
317
- . as_ref ( )
318
- . map ( |s| & * * s)
319
- . unwrap_or ( "undocumented" ) ;
320
-
321
- let value = u64 ( ev. value . ok_or_else ( || {
322
- format ! ( "EnumeratedValue {} has no <value> field" ,
323
- ev. name)
324
- } ) ?) ;
325
- Ok ( Variant {
326
- description,
327
- sc,
328
- pc : Ident :: from ( & * ev. name
329
- . to_sanitized_upper_case ( ) ) ,
330
- value,
331
- } )
332
- } )
333
- . collect :: < Result < Vec < _ > > > ( ) ?;
304
+ let variants = Variant :: from_enumerated_values ( evs) ?;
334
305
335
306
let pc_r = & f. pc_r ;
336
307
if let Some ( base) = & base {
@@ -380,7 +351,7 @@ pub fn fields(
380
351
let mut vars = variants
381
352
. iter ( )
382
353
. map ( |v| {
383
- let desc = util:: escape_brackets ( & v. description ) ;
354
+ let desc = util:: escape_brackets ( & v. doc ) ;
384
355
let pc = & v. pc ;
385
356
quote ! {
386
357
#[ doc = #desc]
@@ -557,39 +528,19 @@ pub fn fields(
557
528
} ) ;
558
529
}
559
530
}
560
- }
561
-
562
- if access != Access :: ReadOnly {
563
- for f in & fs {
564
- if f. access == Some ( Access :: ReadOnly ) {
565
- continue ;
566
- }
567
531
532
+ if can_write {
568
533
let mut proxy_items = vec ! [ ] ;
569
534
570
535
let mut unsafety = unsafety ( f. write_constraint , f. width ) ;
571
- let bits = & f. bits ;
572
- let fty = & f. ty ;
573
- let offset = & f. offset ;
574
- let mask = & f. mask ;
575
536
let width = f. width ;
576
537
577
- if let Some ( ( evs, base) ) = lookup (
578
- & f. evs ,
579
- fields,
580
- parent,
581
- all_registers,
582
- peripheral,
583
- all_peripherals,
584
- Usage :: Write ,
585
- ) ? {
586
- struct Variant {
587
- doc : String ,
588
- pc : Ident ,
589
- sc : Ident ,
590
- value : u64 ,
591
- }
538
+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
539
+ let variants = Variant :: from_enumerated_values ( evs) ?;
592
540
541
+ if variants. len ( ) == 1 << f. width {
542
+ unsafety = None ;
543
+ }
593
544
let pc_w = & f. pc_w ;
594
545
let pc_w_doc = format ! ( "Values that can be written to the field `{}`" , f. name) ;
595
546
@@ -637,37 +588,6 @@ pub fn fields(
637
588
}
638
589
} ) ;
639
590
640
- let variants = evs. values
641
- . iter ( )
642
- // filter out all reserved variants, as we should not
643
- // generate code for them
644
- . filter ( |field| field. name . to_lowercase ( ) != "reserved" )
645
- . map (
646
- |ev| {
647
- let value = u64 ( ev. value . ok_or_else ( || {
648
- format ! ( "EnumeratedValue {} has no `<value>` field" ,
649
- ev. name) } ) ?) ;
650
-
651
- Ok ( Variant {
652
- doc : ev. description
653
- . clone ( )
654
- . unwrap_or_else ( || {
655
- format ! ( "`{:b}`" , value)
656
- } ) ,
657
- pc : Ident :: from ( & * ev. name
658
- . to_sanitized_upper_case ( ) ) ,
659
- sc : Ident :: from ( & * ev. name
660
- . to_sanitized_snake_case ( ) ) ,
661
- value,
662
- } )
663
- } ,
664
- )
665
- . collect :: < Result < Vec < _ > > > ( ) ?;
666
-
667
- if variants. len ( ) == 1 << f. width {
668
- unsafety = None ;
669
- }
670
-
671
591
if base. is_none ( ) {
672
592
let variants_pc = variants. iter ( ) . map ( |v| & v. pc ) ;
673
593
let variants_doc = variants. iter ( ) . map ( |v| util:: escape_brackets ( & v. doc ) . to_owned ( ) ) ;
@@ -808,6 +728,44 @@ fn unsafety(write_constraint: Option<&WriteConstraint>, width: u32) -> Option<Id
808
728
}
809
729
}
810
730
731
+ struct Variant {
732
+ doc : String ,
733
+ pc : Ident ,
734
+ sc : Ident ,
735
+ value : u64 ,
736
+ }
737
+
738
+ impl Variant {
739
+ fn from_enumerated_values ( evs : & EnumeratedValues ) -> Result < Vec < Self > > {
740
+ evs. values
741
+ . iter ( )
742
+ // filter out all reserved variants, as we should not
743
+ // generate code for them
744
+ . filter ( |field| field. name . to_lowercase ( ) != "reserved" )
745
+ . map (
746
+ |ev| {
747
+ let value = u64 ( ev. value . ok_or_else ( || {
748
+ format ! ( "EnumeratedValue {} has no `<value>` field" ,
749
+ ev. name) } ) ?) ;
750
+
751
+ Ok ( Variant {
752
+ doc : ev. description
753
+ . clone ( )
754
+ . unwrap_or_else ( || {
755
+ format ! ( "`{:b}`" , value)
756
+ } ) ,
757
+ pc : Ident :: from ( & * ev. name
758
+ . to_sanitized_upper_case ( ) ) ,
759
+ sc : Ident :: from ( & * ev. name
760
+ . to_sanitized_snake_case ( ) ) ,
761
+ value,
762
+ } )
763
+ } ,
764
+ )
765
+ . collect :: < Result < Vec < _ > > > ( )
766
+ }
767
+ }
768
+
811
769
#[ derive( Clone , Debug ) ]
812
770
pub struct Base < ' a > {
813
771
pub peripheral : Option < & ' a str > ,
@@ -822,8 +780,7 @@ fn lookup<'a>(
822
780
all_registers : & ' a [ & ' a Register ] ,
823
781
peripheral : & ' a Peripheral ,
824
782
all_peripherals : & ' a [ Peripheral ] ,
825
- usage : Usage ,
826
- ) -> Result < Option < ( & ' a EnumeratedValues , Option < Base < ' a > > ) > > {
783
+ ) -> Result < Vec < ( & ' a EnumeratedValues , Option < Base < ' a > > ) > > {
827
784
let evs = evs. iter ( )
828
785
. map ( |evs| {
829
786
if let Some ( base) = & evs. derived_from {
@@ -864,13 +821,17 @@ fn lookup<'a>(
864
821
} )
865
822
. collect :: < Result < Vec < _ > > > ( ) ?;
866
823
824
+ Ok ( evs)
825
+ }
826
+
827
+ fn lookup_filter < ' a > ( evs : & Vec < ( & ' a EnumeratedValues , Option < Base < ' a > > ) > , usage : Usage ) -> Option < ( & ' a EnumeratedValues , Option < Base < ' a > > ) > {
867
828
for ( evs, base) in evs. iter ( ) {
868
829
if evs. usage == Some ( usage) {
869
- return Ok ( Some ( ( * evs, base. clone ( ) ) ) ) ;
830
+ return Some ( ( * evs, base. clone ( ) ) ) ;
870
831
}
871
832
}
872
833
873
- Ok ( evs. first ( ) . cloned ( ) )
834
+ evs. first ( ) . cloned ( )
874
835
}
875
836
876
837
fn lookup_in_fields < ' f > (
0 commit comments