@@ -223,113 +223,81 @@ pub fn fields(
223223    r_impl_items :  & mut  Vec < TokenStream > , 
224224    w_impl_items :  & mut  Vec < TokenStream > , 
225225)  -> Result < ( ) >  { 
226-     impl < ' a >  F < ' a >  { 
227-         fn  from ( f :  & ' a  Field )  -> Result < Self >  { 
228-             // TODO(AJM) - do we need to do anything with this range type? 
229-             let  BitRange  {  offset,  width,  .. }  = f. bit_range ; 
230-             let  sc = f. name . to_sanitized_snake_case ( ) ; 
231-             let  pc = f. name . to_sanitized_upper_case ( ) ; 
232-             let  span = Span :: call_site ( ) ; 
233-             let  pc_r = Ident :: new ( & format ! ( "{}_A" ,  pc) ,  span) ; 
234-             let  _pc_r = Ident :: new ( & format ! ( "{}_R" ,  pc) ,  span) ; 
235-             let  pc_w = Ident :: new ( & format ! ( "{}_AW" ,  pc) ,  span) ; 
236-             let  _pc_w = Ident :: new ( & format ! ( "{}_W" ,  pc) ,  span) ; 
237-             let  _sc = Ident :: new ( & format ! ( "_{}" ,  sc) ,  span) ; 
238-             let  bits = Ident :: new ( if  width == 1  {  "bit"  }  else  {  "bits"  } ,  Span :: call_site ( ) ) ; 
239-             let  mut  description_with_bits = if  width == 1  { 
240-                 format ! ( "Bit {}" ,  offset) 
241-             }  else  { 
242-                 format ! ( "Bits {}:{}" ,  offset,  offset + width - 1 ) 
243-             } ; 
244-             if  let  Some ( d)  = & f. description  { 
245-                 description_with_bits. push_str ( " - " ) ; 
246-                 description_with_bits. push_str ( & util:: respace ( & util:: escape_brackets ( d) ) ) ; 
247-             } 
248-             let  description = if  let  Some ( d)  = & f. description  { 
249-                 util:: respace ( & util:: escape_brackets ( d) ) 
250-             }  else  { 
251-                 "" . to_owned ( ) 
252-             } ; 
253- 
254-             Ok ( F  { 
255-                 _pc_w, 
256-                 _sc, 
257-                 description, 
258-                 description_with_bits, 
259-                 pc_r, 
260-                 _pc_r, 
261-                 pc_w, 
262-                 bits, 
263-                 width, 
264-                 access :  f. access , 
265-                 evs :  & f. enumerated_values , 
266-                 sc :  Ident :: new ( & sc,  Span :: call_site ( ) ) , 
267-                 mask :  1u64 . wrapping_neg ( )  >> ( 64  - width) , 
268-                 name :  & f. name , 
269-                 offset :  u64:: from ( offset) , 
270-                 ty :  width. to_ty ( ) ?, 
271-                 write_constraint :  f. write_constraint . as_ref ( ) , 
272-             } ) 
226+     // TODO enumeratedValues 
227+     for  f in  fields. into_iter ( )  { 
228+         // TODO(AJM) - do we need to do anything with this range type? 
229+         let  BitRange  {  offset,  width,  .. }  = f. bit_range ; 
230+         let  span = Span :: call_site ( ) ; 
231+         let  sc = Ident :: new ( & f. name . to_sanitized_snake_case ( ) ,  span) ; 
232+         let  pc = f. name . to_sanitized_upper_case ( ) ; 
233+         let  bits = Ident :: new ( if  width == 1  {  "bit"  }  else  {  "bits"  } ,  span) ; 
234+         let  mut  description_with_bits = if  width == 1  { 
235+             format ! ( "Bit {}" ,  offset) 
236+         }  else  { 
237+             format ! ( "Bits {}:{}" ,  offset,  offset + width - 1 ) 
238+         } ; 
239+         let  description = if  let  Some ( d)  = & f. description  { 
240+             util:: respace ( & util:: escape_brackets ( d) ) 
241+         }  else  { 
242+             "" . to_owned ( ) 
243+         } ; 
244+         if  !description. is_empty ( )  { 
245+             description_with_bits. push_str ( " - " ) ; 
246+             description_with_bits. push_str ( & description) ; 
273247        } 
274-     } 
275248
276-     let  fs = fields. iter ( ) . map ( F :: from) . collect :: < Result < Vec < _ > > > ( ) ?; 
277- 
278-     // TODO enumeratedValues 
279-     for  f in  & fs { 
280249        let  can_read = [ Access :: ReadOnly ,  Access :: ReadWriteOnce ,  Access :: ReadWrite ] 
281250            . contains ( & access) 
282251            && ( f. access  != Some ( Access :: WriteOnly ) ) 
283252            && ( f. access  != Some ( Access :: WriteOnce ) ) ; 
284253        let  can_write = ( access != Access :: ReadOnly )  && ( f. access  != Some ( Access :: ReadOnly ) ) ; 
285254
286-         let  bits = & f. bits ; 
287-         let  mask = & util:: hex ( f. mask ) ; 
288-         let  offset = f. offset ; 
289-         let  rv = reset_value. map ( |rv| ( rv >> offset)  &  f. mask ) ; 
290-         let  fty = & f. ty ; 
255+         let  mask = 1u64 . wrapping_neg ( )  >> ( 64  - width) ; 
256+         let  hexmask = & util:: hex ( mask) ; 
257+         let  offset = u64:: from ( offset) ; 
258+         let  rv = reset_value. map ( |rv| ( rv >> offset)  &  mask) ; 
259+         let  fty = width. to_ty ( ) ?; 
260+         let  evs = & f. enumerated_values ; 
291261
292262        let  lookup_results = lookup ( 
293-             & f . evs , 
263+             evs, 
294264            fields, 
295265            parent, 
296266            all_registers, 
297267            peripheral, 
298268            all_peripherals, 
299269        ) ?; 
300270
301-         let  pc_r = & f. pc_r ; 
302-         let  mut  pc_w = & f. pc_r ; 
271+         // Reader and writer use one common `Enum_A` unless a fields have two `enumeratedValues`, 
272+         // then we have one for read-only `Enum_A` and another for write-only `Enum_AW` 
273+         let  pc_r = Ident :: new ( & ( pc. clone ( )  + "_A" ) ,  span) ; 
274+         let  mut  pc_w = & pc_r; 
303275
304276        let  mut  base_pc_w = None ; 
305277        let  mut  evs_r = None ; 
306278
307-         let  _pc_r = & f. _pc_r ; 
308-         let  _pc_w = & f. _pc_w ; 
309-         let  description = & f. description ; 
310-         let  description_with_bits = & f. description_with_bits ; 
311- 
312279        if  can_read { 
313-             let  cast = if  f. width  == 1  { 
280+             let  _pc_r = Ident :: new ( & ( pc. clone ( )  + "_R" ) ,  span) ; 
281+ 
282+             let  cast = if  width == 1  { 
314283                quote !  {  != 0  } 
315284            }  else  { 
316285                quote !  {  as  #fty } 
317286            } ; 
318287            let  value = if  offset != 0  { 
319288                let  offset = & util:: unsuffixed ( offset) ; 
320289                quote !  { 
321-                     ( ( self . bits >> #offset)  &  #mask )  #cast
290+                     ( ( self . bits >> #offset)  &  #hexmask )  #cast
322291                } 
323292            }  else  { 
324293                quote !  { 
325-                     ( self . bits &  #mask )  #cast
294+                     ( self . bits &  #hexmask )  #cast
326295                } 
327296            } ; 
328297
329298            if  let  Some ( ( evs,  base) )  = lookup_filter ( & lookup_results,  Usage :: Read )  { 
330299                evs_r = Some ( evs. clone ( ) ) ; 
331300
332-                 let  sc = & f. sc ; 
333301                r_impl_items. push ( quote !  { 
334302                    #[ doc = #description_with_bits] 
335303                    #[ inline( always) ] 
@@ -340,9 +308,9 @@ pub fn fields(
340308
341309                base_pc_w = base. as_ref ( ) . map ( |base| { 
342310                    let  pc = base. field . to_sanitized_upper_case ( ) ; 
343-                     let  base_pc_r = Ident :: new ( & format ! ( "{} _A",  pc ) ,  Span :: call_site ( ) ) ; 
311+                     let  base_pc_r = Ident :: new ( & ( pc . clone ( )  +  " _A") ,  span ) ; 
344312                    let  base_pc_r =
345-                         derive_from_base ( mod_items,  & base,  & pc_r,  & base_pc_r,  description) ; 
313+                         derive_from_base ( mod_items,  & base,  & pc_r,  & base_pc_r,  & description) ; 
346314
347315                    let  doc = format ! ( "Reader of field `{}`" ,  f. name) ; 
348316                    mod_items. push ( quote !  { 
@@ -354,17 +322,17 @@ pub fn fields(
354322                } ) ; 
355323
356324                if  base. is_none ( )  { 
357-                     let  has_reserved_variant = evs. values . len ( )  != ( 1  << f . width ) ; 
325+                     let  has_reserved_variant = evs. values . len ( )  != ( 1  << width) ; 
358326                    let  variants = Variant :: from_enumerated_values ( evs) ?; 
359327
360-                     add_from_variants ( mod_items,  & variants,  pc_r,  & f ,   description,  rv) ; 
328+                     add_from_variants ( mod_items,  & variants,  & pc_r,  & fty ,   & description,  rv) ; 
361329
362330                    let  mut  enum_items = vec ! [ ] ; 
363331
364332                    let  mut  arms = variants
365333                        . iter ( ) 
366334                        . map ( |v| { 
367-                             let  i = util:: unsuffixed_or_bool ( v. value ,  f . width ) ; 
335+                             let  i = util:: unsuffixed_or_bool ( v. value ,  width) ; 
368336                            let  pc = & v. pc ; 
369337
370338                            if  has_reserved_variant { 
@@ -379,7 +347,7 @@ pub fn fields(
379347                        arms. push ( quote !  { 
380348                            i => Res ( i) 
381349                        } ) ; 
382-                     }  else  if  1  << f . width . to_ty_width ( ) ? != variants. len ( )  { 
350+                     }  else  if  1  << width. to_ty_width ( ) ? != variants. len ( )  { 
383351                        arms. push ( quote !  { 
384352                            _ => unreachable!( ) 
385353                        } ) ; 
@@ -418,7 +386,7 @@ pub fn fields(
418386                            }  else  { 
419387                                format ! ( "is_{}" ,  sc) 
420388                            } , 
421-                             Span :: call_site ( ) , 
389+                             span , 
422390                        ) ; 
423391
424392                        let  doc = format ! ( "Checks if the value of the field is `{}`" ,  pc) ; 
@@ -441,7 +409,6 @@ pub fn fields(
441409                    } ) ; 
442410                } 
443411            }  else  { 
444-                 let  sc = & f. sc ; 
445412                r_impl_items. push ( quote !  { 
446413                    #[ doc = #description_with_bits] 
447414                    #[ inline( always) ] 
@@ -459,29 +426,29 @@ pub fn fields(
459426        } 
460427
461428        if  can_write { 
462-             let  mut  proxy_items = vec ! [ ] ; 
429+             let  new_pc_w = Ident :: new ( & ( pc. clone ( )  + "_AW" ) ,  span) ; 
430+             let  _pc_w = Ident :: new ( & ( pc. clone ( )  + "_W" ) ,  span) ; 
463431
464-             let  mut  unsafety  = unsafety ( f . write_constraint ,  f . width ) ; 
465-             let  width = f . width ; 
432+             let  mut  proxy_items  = vec ! [ ] ; 
433+             let  mut  unsafety =  unsafety ( f . write_constraint . as_ref ( ) ,   width) ; 
466434
467435            if  let  Some ( ( evs,  base) )  = lookup_filter ( & lookup_results,  Usage :: Write )  { 
468436                let  variants = Variant :: from_enumerated_values ( evs) ?; 
469437
470-                 if  variants. len ( )  == 1  << f . width  { 
438+                 if  variants. len ( )  == 1  << width { 
471439                    unsafety = None ; 
472440                } 
473441
474442                if  Some ( evs)  != evs_r. as_ref ( )  { 
475-                     pc_w = & f. pc_w ; 
476- 
443+                     pc_w = & new_pc_w; 
477444                    base_pc_w = base. as_ref ( ) . map ( |base| { 
478445                        let  pc = base. field . to_sanitized_upper_case ( ) ; 
479-                         let  base_pc_w = Ident :: new ( & format ! ( "{} _AW",  pc ) ,  Span :: call_site ( ) ) ; 
480-                         derive_from_base ( mod_items,  & base,  & pc_w,  & base_pc_w,  description) 
446+                         let  base_pc_w = Ident :: new ( & ( pc +  " _AW") ,  span ) ; 
447+                         derive_from_base ( mod_items,  & base,  & pc_w,  & base_pc_w,  & description) 
481448                    } ) ; 
482449
483450                    if  base. is_none ( )  { 
484-                         add_from_variants ( mod_items,  & variants,  pc_w,  & f ,   description,  rv) ; 
451+                         add_from_variants ( mod_items,  & variants,  & pc_w,  & fty ,   & description,  rv) ; 
485452                    } 
486453                } 
487454
@@ -542,7 +509,7 @@ pub fn fields(
542509                    ///Writes raw bits to the field 
543510[ inline( always) ] 
544511                    pub  #unsafety fn  #bits( self ,  value:  #fty)  -> & ' a mut  W  { 
545-                         self . w. bits = ( self . w. bits &  !( #mask  << #offset) )  | ( ( ( value as  #rty)  &  #mask )  << #offset) ; 
512+                         self . w. bits = ( self . w. bits &  !( #hexmask  << #offset) )  | ( ( ( value as  #rty)  &  #hexmask )  << #offset) ; 
546513                        self . w
547514                    } 
548515                } 
@@ -551,7 +518,7 @@ pub fn fields(
551518                    ///Writes raw bits to the field 
552519[ inline( always) ] 
553520                    pub  #unsafety fn  #bits( self ,  value:  #fty)  -> & ' a mut  W  { 
554-                         self . w. bits = ( self . w. bits &  !#mask )  | ( ( value as  #rty)  &  #mask ) ; 
521+                         self . w. bits = ( self . w. bits &  !#hexmask )  | ( ( value as  #rty)  &  #hexmask ) ; 
555522                        self . w
556523                    } 
557524                } 
@@ -569,7 +536,6 @@ pub fn fields(
569536                } 
570537            } ) ; 
571538
572-             let  sc = & f. sc ; 
573539            w_impl_items. push ( quote !  { 
574540                #[ doc = #description_with_bits] 
575541                #[ inline( always) ] 
@@ -641,13 +607,11 @@ fn add_from_variants(
641607    mod_items :  & mut  Vec < TokenStream > , 
642608    variants :  & [ Variant ] , 
643609    pc :  & Ident , 
644-     f :  & F , 
610+     fty :  & Ident , 
645611    desc :  & str , 
646612    reset_value :  Option < u64 > , 
647613)  { 
648-     let  fty = & f. ty ; 
649- 
650-     let  ( repr,  cast)  = if  f. ty  == "bool"  { 
614+     let  ( repr,  cast)  = if  fty == "bool"  { 
651615        ( quote !  { } ,  quote !  {  variant as  u8  != 0  } ) 
652616    }  else  { 
653617        ( quote !  {  #[ repr( #fty) ]  } ,  quote !  {  variant as  _ } ) 
@@ -736,26 +700,6 @@ fn derive_from_base(
736700    } 
737701} 
738702
739- struct  F < ' a >  { 
740-     _pc_w :  Ident , 
741-     _sc :  Ident , 
742-     access :  Option < Access > , 
743-     description :  String , 
744-     description_with_bits :  String , 
745-     evs :  & ' a  [ EnumeratedValues ] , 
746-     mask :  u64 , 
747-     name :  & ' a  str , 
748-     offset :  u64 , 
749-     pc_r :  Ident , 
750-     _pc_r :  Ident , 
751-     pc_w :  Ident , 
752-     sc :  Ident , 
753-     bits :  Ident , 
754-     ty :  Ident , 
755-     width :  u32 , 
756-     write_constraint :  Option < & ' a  WriteConstraint > , 
757- } 
758- 
759703#[ derive( Clone ,  Debug ) ]  
760704pub  struct  Base < ' a >  { 
761705    pub  peripheral :  Option < & ' a  str > , 
0 commit comments