@@ -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