@@ -269,16 +269,27 @@ pub fn fields(
269269 let fs = fields. iter ( ) . map ( F :: from) . collect :: < Result < Vec < _ > > > ( ) ?;
270270
271271 // 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+ ) ?;
277291
278- let bits = & f. bits ;
279- let mask = & f. mask ;
280- let offset = & f. offset ;
281- let fty = & f. ty ;
292+ if can_read {
282293 let cast = if f. width == 1 {
283294 quote ! { != 0 }
284295 } else {
@@ -288,49 +299,9 @@ pub fn fields(
288299 ( ( self . bits >> #offset) & #mask) #cast
289300 } ;
290301
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 ) {
307303 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) ?;
334305
335306 let pc_r = & f. pc_r ;
336307 if let Some ( base) = & base {
@@ -380,7 +351,7 @@ pub fn fields(
380351 let mut vars = variants
381352 . iter ( )
382353 . map ( |v| {
383- let desc = util:: escape_brackets ( & v. description ) ;
354+ let desc = util:: escape_brackets ( & v. doc ) ;
384355 let pc = & v. pc ;
385356 quote ! {
386357 #[ doc = #desc]
@@ -557,39 +528,19 @@ pub fn fields(
557528 } ) ;
558529 }
559530 }
560- }
561-
562- if access != Access :: ReadOnly {
563- for f in & fs {
564- if f. access == Some ( Access :: ReadOnly ) {
565- continue ;
566- }
567531
532+ if can_write {
568533 let mut proxy_items = vec ! [ ] ;
569534
570535 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 ;
575536 let width = f. width ;
576537
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) ?;
592540
541+ if variants. len ( ) == 1 << f. width {
542+ unsafety = None ;
543+ }
593544 let pc_w = & f. pc_w ;
594545 let pc_w_doc = format ! ( "Values that can be written to the field `{}`" , f. name) ;
595546
@@ -637,37 +588,6 @@ pub fn fields(
637588 }
638589 } ) ;
639590
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-
671591 if base. is_none ( ) {
672592 let variants_pc = variants. iter ( ) . map ( |v| & v. pc ) ;
673593 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
808728 }
809729}
810730
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+
811769#[ derive( Clone , Debug ) ]
812770pub struct Base < ' a > {
813771 pub peripheral : Option < & ' a str > ,
@@ -822,8 +780,7 @@ fn lookup<'a>(
822780 all_registers : & ' a [ & ' a Register ] ,
823781 peripheral : & ' a Peripheral ,
824782 all_peripherals : & ' a [ Peripheral ] ,
825- usage : Usage ,
826- ) -> Result < Option < ( & ' a EnumeratedValues , Option < Base < ' a > > ) > > {
783+ ) -> Result < Vec < ( & ' a EnumeratedValues , Option < Base < ' a > > ) > > {
827784 let evs = evs. iter ( )
828785 . map ( |evs| {
829786 if let Some ( base) = & evs. derived_from {
@@ -864,13 +821,17 @@ fn lookup<'a>(
864821 } )
865822 . collect :: < Result < Vec < _ > > > ( ) ?;
866823
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 > > ) > {
867828 for ( evs, base) in evs. iter ( ) {
868829 if evs. usage == Some ( usage) {
869- return Ok ( Some ( ( * evs, base. clone ( ) ) ) ) ;
830+ return Some ( ( * evs, base. clone ( ) ) ) ;
870831 }
871832 }
872833
873- Ok ( evs. first ( ) . cloned ( ) )
834+ evs. first ( ) . cloned ( )
874835}
875836
876837fn lookup_in_fields < ' f > (
0 commit comments