11use crate :: svd:: {
22 self , Access , BitRange , DimElement , EnumeratedValue , EnumeratedValues , Field , MaybeArray ,
33 ModifiedWriteValues , ReadAction , Register , RegisterProperties , Usage , WriteConstraint ,
4+ WriteConstraintRange ,
45} ;
56use core:: u64;
67use log:: warn;
@@ -408,7 +409,7 @@ pub fn render_register_mod(
408409 } else {
409410 Safety :: Unsafe
410411 } ;
411- let safe_ty = safe_ty. ident ( span ) ;
412+ let safe_ty = safe_ty. ident ( rsize ) ;
412413
413414 let doc = format ! ( "`write(|w| ..)` method takes [`{mod_ty}::W`](W) writer structure" , ) ;
414415
@@ -1138,17 +1139,14 @@ pub fn fields(
11381139 . map ( |v| Variant :: from_value ( v, def, config) )
11391140 } )
11401141 . transpose ( ) ?;
1142+ // if the write structure is finite, it can be safely written.
11411143 if variants. len ( ) == 1 << width {
1144+ safety = Safety :: Safe ;
11421145 } else if let Some ( def) = def. take ( ) {
11431146 variants. push ( def) ;
11441147 safety = Safety :: Safe ;
11451148 }
11461149
1147- // if the write structure is finite, it can be safely written.
1148- if variants. len ( ) == 1 << width {
1149- safety = Safety :: Safe ;
1150- }
1151-
11521150 // generate write value structure and From conversation if we can't reuse read value structure.
11531151 if rwenum. generate_write_enum ( ) {
11541152 if variants. is_empty ( ) {
@@ -1241,14 +1239,14 @@ pub fn fields(
12411239 }
12421240 } else {
12431241 let wproxy = Ident :: new ( "FieldWriter" , span) ;
1244- let width = & unsuffixed ( width) ;
1242+ let uwidth = & unsuffixed ( width) ;
12451243 if value_write_ty == "u8" && safety != Safety :: Safe {
1246- quote ! { crate :: #wproxy<' a, REG , #width > }
1244+ quote ! { crate :: #wproxy<' a, REG , #uwidth > }
12471245 } else if safety != Safety :: Safe {
1248- quote ! { crate :: #wproxy<' a, REG , #width , #value_write_ty> }
1246+ quote ! { crate :: #wproxy<' a, REG , #uwidth , #value_write_ty> }
12491247 } else {
1250- let safe_ty = safety. ident ( span ) ;
1251- quote ! { crate :: #wproxy<' a, REG , #width , #value_write_ty, crate :: #safe_ty> }
1248+ let safe_ty = safety. ident ( width ) ;
1249+ quote ! { crate :: #wproxy<' a, REG , #uwidth , #value_write_ty, crate :: #safe_ty> }
12521250 }
12531251 } ;
12541252 mod_items. extend ( quote ! {
@@ -1371,9 +1369,10 @@ pub fn fields(
13711369 ) )
13721370}
13731371
1374- #[ derive( Clone , Debug , PartialEq , Eq ) ]
1372+ #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
13751373enum Safety {
13761374 Unsafe ,
1375+ Range ( WriteConstraintRange ) ,
13771376 Safe ,
13781377}
13791378
@@ -1393,18 +1392,26 @@ impl Safety {
13931392 // if a writeConstraint exists then respect it
13941393 Self :: Safe
13951394 }
1395+ Some ( & WriteConstraint :: Range ( range) ) => Self :: Range ( range) ,
13961396 _ => Self :: Unsafe ,
13971397 }
13981398 }
1399- fn ident ( & self , span : Span ) -> Ident {
1400- Ident :: new (
1401- if let Self :: Safe = self {
1402- "Safe"
1403- } else {
1404- "Unsafe"
1405- } ,
1406- span,
1407- )
1399+ fn ident ( & self , width : u32 ) -> TokenStream {
1400+ match self {
1401+ Self :: Safe => quote ! ( Safe ) ,
1402+ Self :: Unsafe => quote ! ( Unsafe ) ,
1403+ Self :: Range ( range) => {
1404+ let min = unsuffixed ( range. min ) ;
1405+ let max = unsuffixed ( range. max ) ;
1406+ if range. min == 0 {
1407+ quote ! ( RangeTo <#max>)
1408+ } else if range. max == u64:: MAX >> ( 64 - width) {
1409+ quote ! ( RangeFrom <#min>)
1410+ } else {
1411+ quote ! ( Range <#min, #max>)
1412+ }
1413+ }
1414+ }
14081415 }
14091416}
14101417
0 commit comments