@@ -230,10 +230,14 @@ pub fn render_register_mod(
230230 }
231231
232232 let mut r_impl_items = TokenStream :: new ( ) ;
233+ let mut r_debug_impl = TokenStream :: new ( ) ;
233234 let mut w_impl_items = TokenStream :: new ( ) ;
234235 let mut zero_to_modify_fields_bitmap = 0 ;
235236 let mut one_to_modify_fields_bitmap = 0 ;
236237
238+ let open = Punct :: new ( '{' , Spacing :: Alone ) ;
239+ let close = Punct :: new ( '}' , Spacing :: Alone ) ;
240+
237241 if let Some ( cur_fields) = register. fields . as_ref ( ) {
238242 // filter out all reserved fields, as we should not generate code for
239243 // them
@@ -243,6 +247,15 @@ pub fn render_register_mod(
243247 . collect ( ) ;
244248
245249 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+
246259 (
247260 r_impl_items,
248261 w_impl_items,
@@ -261,16 +274,57 @@ pub fn render_register_mod(
261274 config,
262275 ) ?;
263276 }
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+ } ) ;
264316 }
265317
266- let open = Punct :: new ( '{' , Spacing :: Alone ) ;
267- let close = Punct :: new ( '}' , Spacing :: Alone ) ;
268-
269318 if can_read && !r_impl_items. is_empty ( ) {
270319 mod_items. extend ( quote ! {
271320 impl R #open #r_impl_items #close
272321 } ) ;
273322 }
323+ if !r_debug_impl. is_empty ( ) {
324+ mod_items. extend ( quote ! {
325+ #r_debug_impl
326+ } ) ;
327+ }
274328
275329 if can_write {
276330 mod_items. extend ( quote ! {
@@ -386,6 +440,95 @@ pub fn render_register_mod(
386440 Ok ( mod_items)
387441}
388442
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+
389532#[ allow( clippy:: too_many_arguments) ]
390533pub fn fields (
391534 mut fields : Vec < & Field > ,
0 commit comments