@@ -223,113 +223,81 @@ pub fn fields(
223
223
r_impl_items : & mut Vec < TokenStream > ,
224
224
w_impl_items : & mut Vec < TokenStream > ,
225
225
) -> 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) ;
273
247
}
274
- }
275
248
276
- let fs = fields. iter ( ) . map ( F :: from) . collect :: < Result < Vec < _ > > > ( ) ?;
277
-
278
- // TODO enumeratedValues
279
- for f in & fs {
280
249
let can_read = [ Access :: ReadOnly , Access :: ReadWriteOnce , Access :: ReadWrite ]
281
250
. contains ( & access)
282
251
&& ( f. access != Some ( Access :: WriteOnly ) )
283
252
&& ( f. access != Some ( Access :: WriteOnce ) ) ;
284
253
let can_write = ( access != Access :: ReadOnly ) && ( f. access != Some ( Access :: ReadOnly ) ) ;
285
254
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 ;
291
261
292
262
let lookup_results = lookup (
293
- & f . evs ,
263
+ evs,
294
264
fields,
295
265
parent,
296
266
all_registers,
297
267
peripheral,
298
268
all_peripherals,
299
269
) ?;
300
270
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;
303
275
304
276
let mut base_pc_w = None ;
305
277
let mut evs_r = None ;
306
278
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
-
312
279
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 {
314
283
quote ! { != 0 }
315
284
} else {
316
285
quote ! { as #fty }
317
286
} ;
318
287
let value = if offset != 0 {
319
288
let offset = & util:: unsuffixed ( offset) ;
320
289
quote ! {
321
- ( ( self . bits >> #offset) & #mask ) #cast
290
+ ( ( self . bits >> #offset) & #hexmask ) #cast
322
291
}
323
292
} else {
324
293
quote ! {
325
- ( self . bits & #mask ) #cast
294
+ ( self . bits & #hexmask ) #cast
326
295
}
327
296
} ;
328
297
329
298
if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
330
299
evs_r = Some ( evs. clone ( ) ) ;
331
300
332
- let sc = & f. sc ;
333
301
r_impl_items. push ( quote ! {
334
302
#[ doc = #description_with_bits]
335
303
#[ inline( always) ]
@@ -340,9 +308,9 @@ pub fn fields(
340
308
341
309
base_pc_w = base. as_ref ( ) . map ( |base| {
342
310
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 ) ;
344
312
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) ;
346
314
347
315
let doc = format ! ( "Reader of field `{}`" , f. name) ;
348
316
mod_items. push ( quote ! {
@@ -354,17 +322,17 @@ pub fn fields(
354
322
} ) ;
355
323
356
324
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) ;
358
326
let variants = Variant :: from_enumerated_values ( evs) ?;
359
327
360
- add_from_variants ( mod_items, & variants, pc_r, & f , description, rv) ;
328
+ add_from_variants ( mod_items, & variants, & pc_r, & fty , & description, rv) ;
361
329
362
330
let mut enum_items = vec ! [ ] ;
363
331
364
332
let mut arms = variants
365
333
. iter ( )
366
334
. map ( |v| {
367
- let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
335
+ let i = util:: unsuffixed_or_bool ( v. value , width) ;
368
336
let pc = & v. pc ;
369
337
370
338
if has_reserved_variant {
@@ -379,7 +347,7 @@ pub fn fields(
379
347
arms. push ( quote ! {
380
348
i => Res ( i)
381
349
} ) ;
382
- } else if 1 << f . width . to_ty_width ( ) ? != variants. len ( ) {
350
+ } else if 1 << width. to_ty_width ( ) ? != variants. len ( ) {
383
351
arms. push ( quote ! {
384
352
_ => unreachable!( )
385
353
} ) ;
@@ -418,7 +386,7 @@ pub fn fields(
418
386
} else {
419
387
format ! ( "is_{}" , sc)
420
388
} ,
421
- Span :: call_site ( ) ,
389
+ span ,
422
390
) ;
423
391
424
392
let doc = format ! ( "Checks if the value of the field is `{}`" , pc) ;
@@ -441,7 +409,6 @@ pub fn fields(
441
409
} ) ;
442
410
}
443
411
} else {
444
- let sc = & f. sc ;
445
412
r_impl_items. push ( quote ! {
446
413
#[ doc = #description_with_bits]
447
414
#[ inline( always) ]
@@ -459,29 +426,29 @@ pub fn fields(
459
426
}
460
427
461
428
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) ;
463
431
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) ;
466
434
467
435
if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
468
436
let variants = Variant :: from_enumerated_values ( evs) ?;
469
437
470
- if variants. len ( ) == 1 << f . width {
438
+ if variants. len ( ) == 1 << width {
471
439
unsafety = None ;
472
440
}
473
441
474
442
if Some ( evs) != evs_r. as_ref ( ) {
475
- pc_w = & f. pc_w ;
476
-
443
+ pc_w = & new_pc_w;
477
444
base_pc_w = base. as_ref ( ) . map ( |base| {
478
445
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)
481
448
} ) ;
482
449
483
450
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) ;
485
452
}
486
453
}
487
454
@@ -542,7 +509,7 @@ pub fn fields(
542
509
///Writes raw bits to the field
543
510
#[ inline( always) ]
544
511
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) ;
546
513
self . w
547
514
}
548
515
}
@@ -551,7 +518,7 @@ pub fn fields(
551
518
///Writes raw bits to the field
552
519
#[ inline( always) ]
553
520
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 ) ;
555
522
self . w
556
523
}
557
524
}
@@ -569,7 +536,6 @@ pub fn fields(
569
536
}
570
537
} ) ;
571
538
572
- let sc = & f. sc ;
573
539
w_impl_items. push ( quote ! {
574
540
#[ doc = #description_with_bits]
575
541
#[ inline( always) ]
@@ -641,13 +607,11 @@ fn add_from_variants(
641
607
mod_items : & mut Vec < TokenStream > ,
642
608
variants : & [ Variant ] ,
643
609
pc : & Ident ,
644
- f : & F ,
610
+ fty : & Ident ,
645
611
desc : & str ,
646
612
reset_value : Option < u64 > ,
647
613
) {
648
- let fty = & f. ty ;
649
-
650
- let ( repr, cast) = if f. ty == "bool" {
614
+ let ( repr, cast) = if fty == "bool" {
651
615
( quote ! { } , quote ! { variant as u8 != 0 } )
652
616
} else {
653
617
( quote ! { #[ repr( #fty) ] } , quote ! { variant as _ } )
@@ -736,26 +700,6 @@ fn derive_from_base(
736
700
}
737
701
}
738
702
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
-
759
703
#[ derive( Clone , Debug ) ]
760
704
pub struct Base < ' a > {
761
705
pub peripheral : Option < & ' a str > ,
0 commit comments