@@ -230,10 +230,14 @@ pub fn render_register_mod(
230
230
}
231
231
232
232
let mut r_impl_items = TokenStream :: new ( ) ;
233
+ let mut r_debug_impl = TokenStream :: new ( ) ;
233
234
let mut w_impl_items = TokenStream :: new ( ) ;
234
235
let mut zero_to_modify_fields_bitmap = 0 ;
235
236
let mut one_to_modify_fields_bitmap = 0 ;
236
237
238
+ let open = Punct :: new ( '{' , Spacing :: Alone ) ;
239
+ let close = Punct :: new ( '}' , Spacing :: Alone ) ;
240
+
237
241
if let Some ( cur_fields) = register. fields . as_ref ( ) {
238
242
// filter out all reserved fields, as we should not generate code for
239
243
// them
@@ -243,6 +247,15 @@ pub fn render_register_mod(
243
247
. collect ( ) ;
244
248
245
249
if !cur_fields. is_empty ( ) {
250
+ if config. impl_debug {
251
+ r_debug_impl. extend ( render_register_mod_debug (
252
+ register,
253
+ & access,
254
+ & cur_fields,
255
+ config,
256
+ ) )
257
+ }
258
+
246
259
(
247
260
r_impl_items,
248
261
w_impl_items,
@@ -260,16 +273,57 @@ pub fn render_register_mod(
260
273
config,
261
274
) ?;
262
275
}
276
+ } else if !access. can_read ( ) || register. read_action . is_some ( ) {
277
+ if let Some ( feature) = & config. impl_debug_feature {
278
+ r_debug_impl. extend ( quote ! {
279
+ #[ cfg( feature=#feature) ]
280
+ } ) ;
281
+ }
282
+ r_debug_impl. extend ( quote ! {
283
+ impl core:: fmt:: Debug for crate :: generic:: Reg <#regspec_ident> {
284
+ fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
285
+ write!( f, "(not readable)" )
286
+ }
287
+ }
288
+ } ) ;
289
+ } else {
290
+ // no register fields are defined so implement Debug to get entire register value
291
+ if let Some ( feature) = & config. impl_debug_feature {
292
+ r_debug_impl. extend ( quote ! {
293
+ #[ cfg( feature=#feature) ]
294
+ } ) ;
295
+ }
296
+ r_debug_impl. extend ( quote ! {
297
+ impl core:: fmt:: Debug for R {
298
+ fn fmt( & self , f: & mut core:: fmt:: Formatter ) -> core:: fmt:: Result {
299
+ write!( f, "{}" , self . bits( ) )
300
+ }
301
+ }
302
+ } ) ;
303
+ if let Some ( feature) = & config. impl_debug_feature {
304
+ r_debug_impl. extend ( quote ! {
305
+ #[ cfg( feature=#feature) ]
306
+ } ) ;
307
+ }
308
+ r_debug_impl. extend ( quote ! {
309
+ impl core:: fmt:: Debug for crate :: generic:: Reg <#regspec_ident> {
310
+ fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
311
+ self . read( ) . fmt( f)
312
+ }
313
+ }
314
+ } ) ;
263
315
}
264
316
265
- let open = Punct :: new ( '{' , Spacing :: Alone ) ;
266
- let close = Punct :: new ( '}' , Spacing :: Alone ) ;
267
-
268
317
if can_read && !r_impl_items. is_empty ( ) {
269
318
mod_items. extend ( quote ! {
270
319
impl R #open #r_impl_items #close
271
320
} ) ;
272
321
}
322
+ if !r_debug_impl. is_empty ( ) {
323
+ mod_items. extend ( quote ! {
324
+ #r_debug_impl
325
+ } ) ;
326
+ }
273
327
274
328
if can_write {
275
329
mod_items. extend ( quote ! {
@@ -385,6 +439,95 @@ pub fn render_register_mod(
385
439
Ok ( mod_items)
386
440
}
387
441
442
+ fn render_register_mod_debug (
443
+ register : & Register ,
444
+ access : & Access ,
445
+ cur_fields : & [ & Field ] ,
446
+ config : & Config ,
447
+ ) -> Result < TokenStream > {
448
+ let name = util:: name_of ( register, config. ignore_groups ) ;
449
+ let span = Span :: call_site ( ) ;
450
+ let regspec_ident = format ! ( "{name}_SPEC" ) . to_constant_case_ident ( span) ;
451
+ let open = Punct :: new ( '{' , Spacing :: Alone ) ;
452
+ let close = Punct :: new ( '}' , Spacing :: Alone ) ;
453
+ let mut r_debug_impl = TokenStream :: new ( ) ;
454
+
455
+ // implement Debug for register readable fields that have no read side effects
456
+ if access. can_read ( ) && register. read_action . is_none ( ) {
457
+ if let Some ( feature) = & config. impl_debug_feature {
458
+ r_debug_impl. extend ( quote ! {
459
+ #[ cfg( feature=#feature) ]
460
+ } ) ;
461
+ }
462
+ r_debug_impl. extend ( quote ! {
463
+ impl core:: fmt:: Debug for R #open
464
+ fn fmt( & self , f: & mut core:: fmt:: Formatter ) -> core:: fmt:: Result #open
465
+ f. debug_struct( #name)
466
+ } ) ;
467
+ for & f in cur_fields. iter ( ) {
468
+ let field_access = match & f. access {
469
+ Some ( a) => a,
470
+ None => access,
471
+ } ;
472
+ let bit_or_bits = if f. bit_width ( ) > 1 { "bits" } else { "bit" } ;
473
+ let bit_or_bits = syn:: Ident :: new ( bit_or_bits, span) ;
474
+ log:: debug!( "register={} field={}" , name, f. name) ;
475
+ if field_access. can_read ( ) && f. read_action . is_none ( ) {
476
+ if let Field :: Array ( _, de) = & f {
477
+ for ( _, suffix) in de. indexes ( ) . enumerate ( ) {
478
+ let f_name_n = util:: replace_suffix ( & f. name , & suffix)
479
+ . to_snake_case_ident ( Span :: call_site ( ) ) ;
480
+ let f_name_n_s = format ! ( "{f_name_n}" ) ;
481
+ r_debug_impl. extend ( quote ! {
482
+ . field( #f_name_n_s, & format_args!( "{}" , self . #f_name_n( ) . #bit_or_bits( ) ) )
483
+ } ) ;
484
+ }
485
+ } else {
486
+ let f_name = util:: replace_suffix ( & f. name , "" ) ;
487
+ let f_name = f_name. to_snake_case_ident ( span) ;
488
+ let f_name_s = format ! ( "{f_name}" ) ;
489
+ r_debug_impl. extend ( quote ! {
490
+ . field( #f_name_s, & format_args!( "{}" , self . #f_name( ) . #bit_or_bits( ) ) )
491
+ } ) ;
492
+ }
493
+ }
494
+ }
495
+ r_debug_impl. extend ( quote ! {
496
+ . finish( )
497
+ #close
498
+ #close
499
+ } ) ;
500
+ if let Some ( feature) = & config. impl_debug_feature {
501
+ r_debug_impl. extend ( quote ! {
502
+ #[ cfg( feature=#feature) ]
503
+ } ) ;
504
+ }
505
+ r_debug_impl. extend ( quote ! {
506
+ impl core:: fmt:: Debug for crate :: generic:: Reg <#regspec_ident> {
507
+ fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
508
+ self . read( ) . fmt( f)
509
+ }
510
+ }
511
+ } ) ;
512
+ } else if !access. can_read ( ) || register. read_action . is_some ( ) {
513
+ if let Some ( feature) = & config. impl_debug_feature {
514
+ r_debug_impl. extend ( quote ! {
515
+ #[ cfg( feature=#feature) ]
516
+ } ) ;
517
+ }
518
+ r_debug_impl. extend ( quote ! {
519
+ impl core:: fmt:: Debug for crate :: generic:: Reg <#regspec_ident> {
520
+ fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
521
+ write!( f, "(not readable)" )
522
+ }
523
+ }
524
+ } ) ;
525
+ } else {
526
+ warn ! ( "not implementing debug for {name}" ) ;
527
+ }
528
+ Ok ( r_debug_impl)
529
+ }
530
+
388
531
#[ allow( clippy:: too_many_arguments) ]
389
532
pub fn fields (
390
533
mut fields : Vec < & Field > ,
0 commit comments