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