@@ -223,133 +223,81 @@ pub fn fields(
223223 r_impl_items : & mut Vec < TokenStream > ,
224224 w_impl_items : & mut Vec < TokenStream > ,
225225) -> Result < ( ) > {
226- struct F < ' a > {
227- _pc_w : Ident ,
228- _sc : Ident ,
229- access : Option < Access > ,
230- description : String ,
231- description_with_bits : String ,
232- evs : & ' a [ EnumeratedValues ] ,
233- mask : u64 ,
234- name : & ' a str ,
235- offset : u64 ,
236- pc_r : Ident ,
237- _pc_r : Ident ,
238- pc_w : Ident ,
239- sc : Ident ,
240- bits : Ident ,
241- ty : Ident ,
242- width : u32 ,
243- write_constraint : Option < & ' a WriteConstraint > ,
244- }
245-
246- impl < ' a > F < ' a > {
247- fn from ( f : & ' a Field ) -> Result < Self > {
248- // TODO(AJM) - do we need to do anything with this range type?
249- let BitRange { offset, width, .. } = f. bit_range ;
250- let sc = f. name . to_sanitized_snake_case ( ) ;
251- let pc = f. name . to_sanitized_upper_case ( ) ;
252- let span = Span :: call_site ( ) ;
253- let pc_r = Ident :: new ( & format ! ( "{}_A" , pc) , span) ;
254- let _pc_r = Ident :: new ( & format ! ( "{}_R" , pc) , span) ;
255- let pc_w = Ident :: new ( & format ! ( "{}_AW" , pc) , span) ;
256- let _pc_w = Ident :: new ( & format ! ( "{}_W" , pc) , span) ;
257- let _sc = Ident :: new ( & format ! ( "_{}" , sc) , span) ;
258- let bits = Ident :: new ( if width == 1 { "bit" } else { "bits" } , span) ;
259- let mut description_with_bits = if width == 1 {
260- format ! ( "Bit {}" , offset)
261- } else {
262- format ! ( "Bits {}:{}" , offset, offset + width - 1 )
263- } ;
264- if let Some ( d) = & f. description {
265- description_with_bits. push_str ( " - " ) ;
266- description_with_bits. push_str ( & util:: respace ( & util:: escape_brackets ( d) ) ) ;
267- }
268- let description = if let Some ( d) = & f. description {
269- util:: respace ( & util:: escape_brackets ( d) )
270- } else {
271- "" . to_owned ( )
272- } ;
273-
274- Ok ( F {
275- _pc_w,
276- _sc,
277- description,
278- description_with_bits,
279- pc_r,
280- _pc_r,
281- pc_w,
282- bits,
283- width,
284- access : f. access ,
285- evs : & f. enumerated_values ,
286- sc : Ident :: new ( & sc, span) ,
287- mask : 1u64 . wrapping_neg ( ) >> ( 64 - width) ,
288- name : & f. name ,
289- offset : u64:: from ( offset) ,
290- ty : width. to_ty ( ) ?,
291- write_constraint : f. write_constraint . as_ref ( ) ,
292- } )
293- }
294- }
295-
296226 // TODO enumeratedValues
297- for f in fields. iter ( ) . map ( F :: from) {
298- let f = f?;
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) ;
247+ }
299248
300249 let can_read = [ Access :: ReadOnly , Access :: ReadWriteOnce , Access :: ReadWrite ]
301250 . contains ( & access)
302251 && ( f. access != Some ( Access :: WriteOnly ) )
303252 && ( f. access != Some ( Access :: WriteOnce ) ) ;
304253 let can_write = ( access != Access :: ReadOnly ) && ( f. access != Some ( Access :: ReadOnly ) ) ;
305254
306- let bits = & f. bits ;
307- let mask = & util:: hex ( f. mask ) ;
308- let offset = f. offset ;
309- let rv = reset_value. map ( |rv| ( rv >> offset) & f. mask ) ;
310- 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 ;
311261
312262 let lookup_results = lookup (
313- & f . evs ,
263+ evs,
314264 fields,
315265 parent,
316266 all_registers,
317267 peripheral,
318268 all_peripherals,
319269 ) ?;
320270
321- let pc_r = & f. pc_r ;
322- 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;
323275
324276 let mut base_pc_w = None ;
325277 let mut evs_r = None ;
326278
327- let _pc_r = & f. _pc_r ;
328- let _pc_w = & f. _pc_w ;
329- let description = & f. description ;
330- let description_with_bits = & f. description_with_bits ;
331-
332279 if can_read {
333- let cast = if f. width == 1 {
280+ let _pc_r = Ident :: new ( & ( pc. clone ( ) + "_R" ) , span) ;
281+
282+ let cast = if width == 1 {
334283 quote ! { != 0 }
335284 } else {
336285 quote ! { as #fty }
337286 } ;
338287 let value = if offset != 0 {
339288 let offset = & util:: unsuffixed ( offset) ;
340289 quote ! {
341- ( ( self . bits >> #offset) & #mask ) #cast
290+ ( ( self . bits >> #offset) & #hexmask ) #cast
342291 }
343292 } else {
344293 quote ! {
345- ( self . bits & #mask ) #cast
294+ ( self . bits & #hexmask ) #cast
346295 }
347296 } ;
348297
349298 if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
350299 evs_r = Some ( evs. clone ( ) ) ;
351300
352- let sc = & f. sc ;
353301 r_impl_items. push ( quote ! {
354302 #[ doc = #description_with_bits]
355303 #[ inline( always) ]
@@ -360,9 +308,9 @@ pub fn fields(
360308
361309 base_pc_w = base. as_ref ( ) . map ( |base| {
362310 let pc = base. field . to_sanitized_upper_case ( ) ;
363- let base_pc_r = Ident :: new ( & format ! ( "{} _A", pc ) , Span :: call_site ( ) ) ;
311+ let base_pc_r = Ident :: new ( & ( pc . clone ( ) + " _A") , span ) ;
364312 let base_pc_r =
365- 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) ;
366314
367315 let doc = format ! ( "Reader of field `{}`" , f. name) ;
368316 mod_items. push ( quote ! {
@@ -374,17 +322,17 @@ pub fn fields(
374322 } ) ;
375323
376324 if base. is_none ( ) {
377- let has_reserved_variant = evs. values . len ( ) != ( 1 << f . width ) ;
325+ let has_reserved_variant = evs. values . len ( ) != ( 1 << width) ;
378326 let variants = Variant :: from_enumerated_values ( evs) ?;
379327
380- add_from_variants ( mod_items, & variants, pc_r, fty, description, rv) ;
328+ add_from_variants ( mod_items, & variants, & pc_r, & fty, & description, rv) ;
381329
382330 let mut enum_items = vec ! [ ] ;
383331
384332 let mut arms = variants
385333 . iter ( )
386334 . map ( |v| {
387- let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
335+ let i = util:: unsuffixed_or_bool ( v. value , width) ;
388336 let pc = & v. pc ;
389337
390338 if has_reserved_variant {
@@ -399,7 +347,7 @@ pub fn fields(
399347 arms. push ( quote ! {
400348 i => Res ( i)
401349 } ) ;
402- } else if 1 << f . width . to_ty_width ( ) ? != variants. len ( ) {
350+ } else if 1 << width. to_ty_width ( ) ? != variants. len ( ) {
403351 arms. push ( quote ! {
404352 _ => unreachable!( )
405353 } ) ;
@@ -438,7 +386,7 @@ pub fn fields(
438386 } else {
439387 format ! ( "is_{}" , sc)
440388 } ,
441- Span :: call_site ( ) ,
389+ span ,
442390 ) ;
443391
444392 let doc = format ! ( "Checks if the value of the field is `{}`" , pc) ;
@@ -461,7 +409,6 @@ pub fn fields(
461409 } ) ;
462410 }
463411 } else {
464- let sc = & f. sc ;
465412 r_impl_items. push ( quote ! {
466413 #[ doc = #description_with_bits]
467414 #[ inline( always) ]
@@ -479,29 +426,29 @@ pub fn fields(
479426 }
480427
481428 if can_write {
482- 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) ;
483431
484- let mut unsafety = unsafety ( f . write_constraint , f . width ) ;
485- let width = f . width ;
432+ let mut proxy_items = vec ! [ ] ;
433+ let mut unsafety = unsafety ( f . write_constraint . as_ref ( ) , width) ;
486434
487435 if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
488436 let variants = Variant :: from_enumerated_values ( evs) ?;
489437
490- if variants. len ( ) == 1 << f . width {
438+ if variants. len ( ) == 1 << width {
491439 unsafety = None ;
492440 }
493441
494442 if Some ( evs) != evs_r. as_ref ( ) {
495- pc_w = & f. pc_w ;
496-
443+ pc_w = & new_pc_w;
497444 base_pc_w = base. as_ref ( ) . map ( |base| {
498445 let pc = base. field . to_sanitized_upper_case ( ) ;
499- let base_pc_w = Ident :: new ( & format ! ( "{} _AW", pc ) , Span :: call_site ( ) ) ;
500- 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)
501448 } ) ;
502449
503450 if base. is_none ( ) {
504- add_from_variants ( mod_items, & variants, pc_w, fty, description, rv) ;
451+ add_from_variants ( mod_items, & variants, & pc_w, & fty, & description, rv) ;
505452 }
506453 }
507454
@@ -562,7 +509,7 @@ pub fn fields(
562509 ///Writes raw bits to the field
563510 #[ inline( always) ]
564511 pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
565- 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) ;
566513 self . w
567514 }
568515 }
@@ -571,7 +518,7 @@ pub fn fields(
571518 ///Writes raw bits to the field
572519 #[ inline( always) ]
573520 pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
574- self . w. bits = ( self . w. bits & !#mask ) | ( ( value as #rty) & #mask ) ;
521+ self . w. bits = ( self . w. bits & !#hexmask ) | ( ( value as #rty) & #hexmask ) ;
575522 self . w
576523 }
577524 }
@@ -589,7 +536,6 @@ pub fn fields(
589536 }
590537 } ) ;
591538
592- let sc = & f. sc ;
593539 w_impl_items. push ( quote ! {
594540 #[ doc = #description_with_bits]
595541 #[ inline( always) ]
0 commit comments