@@ -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,
@@ -260,16 +273,57 @@ pub fn render_register_mod(
260273 config,
261274 ) ?;
262275 }
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+ } ) ;
263315 }
264316
265- let open = Punct :: new ( '{' , Spacing :: Alone ) ;
266- let close = Punct :: new ( '}' , Spacing :: Alone ) ;
267-
268317 if can_read && !r_impl_items. is_empty ( ) {
269318 mod_items. extend ( quote ! {
270319 impl R #open #r_impl_items #close
271320 } ) ;
272321 }
322+ if !r_debug_impl. is_empty ( ) {
323+ mod_items. extend ( quote ! {
324+ #r_debug_impl
325+ } ) ;
326+ }
273327
274328 if can_write {
275329 mod_items. extend ( quote ! {
@@ -385,6 +439,95 @@ pub fn render_register_mod(
385439 Ok ( mod_items)
386440}
387441
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+
388531#[ allow( clippy:: too_many_arguments) ]
389532pub fn fields (
390533 mut fields : Vec < & Field > ,
0 commit comments