@@ -15,6 +15,7 @@ pub fn render(
1515 p : & Peripheral ,
1616 all_peripherals : & [ Peripheral ] ,
1717 defaults : & Defaults ,
18+ nightly : bool ,
1819) -> Result < Vec < Tokens > > {
1920 let mut out = vec ! [ ] ;
2021
@@ -76,11 +77,11 @@ pub fn render(
7677
7778 // Push any register or cluster blocks into the output
7879 let mut mod_items = vec ! [ ] ;
79- mod_items. push ( register_or_cluster_block ( ercs, defaults, None ) ?) ;
80+ mod_items. push ( register_or_cluster_block ( ercs, defaults, None , nightly ) ?) ;
8081
8182 // Push all cluster related information into the peripheral module
8283 for c in & clusters {
83- mod_items. push ( cluster_block ( c, defaults, p, all_peripherals) ?) ;
84+ mod_items. push ( cluster_block ( c, defaults, p, all_peripherals, nightly ) ?) ;
8485 }
8586
8687 // Push all regsiter realted information into the peripheral module
@@ -348,6 +349,84 @@ fn register_or_cluster_block(
348349 ercs : & [ Either < Register , Cluster > ] ,
349350 defs : & Defaults ,
350351 name : Option < & str > ,
352+ nightly : bool ,
353+ ) -> Result < Tokens > {
354+ if nightly {
355+ register_or_cluster_block_nightly ( ercs, defs, name)
356+ } else {
357+ register_or_cluster_block_stable ( ercs, defs, name)
358+ }
359+ }
360+
361+ fn register_or_cluster_block_stable (
362+ ercs : & [ Either < Register , Cluster > ] ,
363+ defs : & Defaults ,
364+ name : Option < & str > ,
365+ ) -> Result < Tokens > {
366+ let mut fields = Tokens :: new ( ) ;
367+ // enumeration of reserved fields
368+ let mut i = 0 ;
369+ // offset from the base address, in bytes
370+ let mut offset = 0 ;
371+
372+ let ercs_expanded = expand ( ercs, defs, name) ?;
373+
374+ for reg_block_field in ercs_expanded {
375+ let pad = if let Some ( pad) = reg_block_field. offset . checked_sub ( offset) {
376+ pad
377+ } else {
378+ eprintln ! (
379+ "WARNING {:?} overlaps with another register block at offset {}. \
380+ Ignoring.",
381+ reg_block_field. field. ident,
382+ reg_block_field. offset
383+ ) ;
384+ continue ;
385+ } ;
386+
387+ if pad != 0 {
388+ let name = Ident :: new ( format ! ( "_reserved{}" , i) ) ;
389+ let pad = pad as usize ;
390+ fields. append ( quote ! {
391+ #name : [ u8 ; #pad] ,
392+ } ) ;
393+ i += 1 ;
394+ }
395+
396+ let comment = & format ! (
397+ "0x{:02x} - {}" ,
398+ reg_block_field. offset,
399+ util:: respace( & reg_block_field. description) ,
400+ ) [ ..] ;
401+
402+ fields. append ( quote ! {
403+ #[ doc = #comment]
404+ } ) ;
405+
406+ reg_block_field. field . to_tokens ( & mut fields) ;
407+ Ident :: new ( "," ) . to_tokens ( & mut fields) ;
408+
409+ offset = reg_block_field. offset + reg_block_field. size / BITS_PER_BYTE ;
410+ }
411+
412+ let name = Ident :: new ( match name {
413+ Some ( name) => name. to_sanitized_upper_case ( ) ,
414+ None => "RegisterBlock" . into ( ) ,
415+ } ) ;
416+
417+ Ok ( quote ! {
418+ /// Register block
419+ #[ repr( C ) ]
420+ pub struct #name {
421+ #fields
422+ }
423+ } )
424+ }
425+
426+ fn register_or_cluster_block_nightly (
427+ ercs : & [ Either < Register , Cluster > ] ,
428+ defs : & Defaults ,
429+ name : Option < & str > ,
351430) -> Result < Tokens > {
352431 let mut fields = Tokens :: new ( ) ;
353432 let mut helper_types = Tokens :: new ( ) ;
@@ -636,6 +715,7 @@ fn cluster_block(
636715 defaults : & Defaults ,
637716 p : & Peripheral ,
638717 all_peripherals : & [ Peripheral ] ,
718+ nightly : bool ,
639719) -> Result < Tokens > {
640720 let mut mod_items: Vec < Tokens > = vec ! [ ] ;
641721
@@ -649,7 +729,7 @@ fn cluster_block(
649729 } . replace ( "[%s]" , "" )
650730 . replace ( "%s" , "" ) ;
651731 let name_sc = Ident :: new ( & * mod_name. to_sanitized_snake_case ( ) ) ;
652- let reg_block = register_or_cluster_block ( & c. children , defaults, Some ( & mod_name) ) ?;
732+ let reg_block = register_or_cluster_block ( & c. children , defaults, Some ( & mod_name) , nightly ) ?;
653733
654734 // Generate definition for each of the registers.
655735 let registers = util:: only_registers ( & c. children ) ;
@@ -666,7 +746,7 @@ fn cluster_block(
666746 // Generate the sub-cluster blocks.
667747 let clusters = util:: only_clusters ( & c. children ) ;
668748 for c in & clusters {
669- mod_items. push ( cluster_block ( c, defaults, p, all_peripherals) ?) ;
749+ mod_items. push ( cluster_block ( c, defaults, p, all_peripherals, nightly ) ?) ;
670750 }
671751
672752 Ok ( quote ! {
0 commit comments