@@ -23,7 +23,6 @@ struct ProtoFieldset {
2323#[ derive( Debug ) ]
2424struct ProtoEnum {
2525 name : Vec < String > ,
26- usage : Option < svd:: Usage > ,
2726 bit_size : u32 ,
2827 variants : Vec < svd:: EnumeratedValue > ,
2928}
@@ -58,26 +57,97 @@ pub fn convert_peripheral(ir: &mut IR, p: &svd::Peripheral) -> anyhow::Result<()
5857 } ) ;
5958
6059 for f in fields {
60+ info ! ( "field {}.{}" , r. name, f. name) ;
61+
6162 if f. derived_from . is_some ( ) {
6263 continue ;
6364 }
6465
65- let field_name = f. name . clone ( ) ;
66+ let mut enum_read = None ;
67+ let mut enum_write = None ;
68+ let mut enum_readwrite = None ;
6669
6770 for e in & f. enumerated_values {
6871 if e. derived_from . is_some ( ) {
72+ // TODO
73+ warn ! ( "ignoring enum with derivedFrom" ) ;
74+ continue ;
75+ }
76+
77+ let usage = e. usage . unwrap_or ( svd:: Usage :: ReadWrite ) ;
78+ let target = match usage {
79+ svd:: Usage :: Read => & mut enum_read,
80+ svd:: Usage :: Write => & mut enum_write,
81+ svd:: Usage :: ReadWrite => & mut enum_readwrite,
82+ } ;
83+
84+ if target. is_some ( ) {
85+ warn ! ( "ignoring enum with dup usage {:?}" , usage) ;
6986 continue ;
7087 }
7188
72- let mut enum_name = fieldset_name. clone ( ) ;
73- enum_name. push ( make_enum_name ( e, & f. enumerated_values , & field_name) ) ;
74- info ! ( "adding enum {:?}" , enum_name) ;
89+ * target = Some ( e)
90+ }
91+
92+ enum EnumSet < ' a > {
93+ Single ( & ' a svd:: EnumeratedValues ) ,
94+ ReadWrite ( & ' a svd:: EnumeratedValues , & ' a svd:: EnumeratedValues ) ,
95+ }
7596
97+ let set = match ( enum_read, enum_write, enum_readwrite) {
98+ ( None , None , None ) => None ,
99+ ( Some ( e) , None , None ) => Some ( EnumSet :: Single ( e) ) ,
100+ ( None , Some ( e) , None ) => Some ( EnumSet :: Single ( e) ) ,
101+ ( None , None , Some ( e) ) => Some ( EnumSet :: Single ( e) ) ,
102+ ( Some ( r) , Some ( w) , None ) => Some ( EnumSet :: ReadWrite ( r, w) ) ,
103+ ( Some ( r) , None , Some ( w) ) => Some ( EnumSet :: ReadWrite ( r, w) ) ,
104+ ( None , Some ( w) , Some ( r) ) => Some ( EnumSet :: ReadWrite ( r, w) ) ,
105+ ( Some ( _) , Some ( _) , Some ( _) ) => panic ! (
106+ "cannot have enumeratedvalues for read, write and readwrite!"
107+ ) ,
108+ } ;
109+
110+ if let Some ( set) = set {
111+ let variants = match set {
112+ EnumSet :: Single ( e) => e. values . clone ( ) ,
113+ EnumSet :: ReadWrite ( r, w) => {
114+ let r_values = r. values . iter ( ) . map ( |v| v. value . unwrap ( ) ) ;
115+ let w_values = w. values . iter ( ) . map ( |v| v. value . unwrap ( ) ) ;
116+ let values: HashSet < _ > = r_values. chain ( w_values) . collect ( ) ;
117+ let mut values: Vec < _ > = values. iter ( ) . collect ( ) ;
118+ values. sort ( ) ;
119+
120+ let r_values: HashMap < _ , _ > =
121+ r. values . iter ( ) . map ( |v| ( v. value . unwrap ( ) , v) ) . collect ( ) ;
122+ let w_values: HashMap < _ , _ > =
123+ w. values . iter ( ) . map ( |v| ( v. value . unwrap ( ) , v) ) . collect ( ) ;
124+
125+ values
126+ . into_iter ( )
127+ . map ( |& v| match ( r_values. get ( & v) , w_values. get ( & v) ) {
128+ ( None , None ) => unreachable ! ( ) ,
129+ ( Some ( & r) , None ) => r. clone ( ) ,
130+ ( None , Some ( & w) ) => w. clone ( ) ,
131+ ( Some ( & r) , Some ( & w) ) => {
132+ let mut m = r. clone ( ) ;
133+ if r. name != w. name {
134+ m. name = format ! ( "R_{}_W_{}" , r. name, w. name) ;
135+ }
136+ m
137+ }
138+ } )
139+ . collect ( )
140+ }
141+ } ;
142+
143+ info ! ( "adding enum {:?}" , fieldset_name) ;
144+
145+ let mut name = fieldset_name. clone ( ) ;
146+ name. push ( f. name . clone ( ) ) ;
76147 enums. push ( ProtoEnum {
77- name : enum_name,
78- usage : e. usage ,
148+ name,
79149 bit_size : f. bit_range . width ,
80- variants : e . values . clone ( ) ,
150+ variants,
81151 } ) ;
82152 }
83153 }
@@ -203,30 +273,17 @@ pub fn convert_peripheral(ir: &mut IR, p: &svd::Peripheral) -> anyhow::Result<()
203273 bit_offset : f. bit_range . offset ,
204274 bit_size : f. bit_range . width ,
205275 array : None ,
206- enum_read : None ,
207- enum_write : None ,
208- enum_readwrite : None ,
276+ enumm : None ,
209277 } ;
210278
211- for e in & f. enumerated_values {
279+ if ! f. enumerated_values . is_empty ( ) {
212280 let mut enum_name = proto. name . clone ( ) ;
213- enum_name. push (
214- e. derived_from
215- . clone ( )
216- . unwrap_or_else ( || make_enum_name ( e, & f. enumerated_values , & f. name ) ) ,
217- ) ;
281+ enum_name. push ( f. name . clone ( ) ) ;
282+
218283 info ! ( "finding enum {:?}" , enum_name) ;
219- let enumm = enums. iter ( ) . find ( |e| e. name == enum_name) . unwrap ( ) ;
220284 let enum_name = enum_names. get ( & enum_name) . unwrap ( ) . clone ( ) ;
221285 info ! ( "found {:?}" , enum_name) ;
222-
223- let usage = enumm. usage . unwrap_or ( svd:: Usage :: ReadWrite ) ;
224-
225- match usage {
226- svd:: Usage :: Read => field. enum_read = Some ( enum_name. clone ( ) ) ,
227- svd:: Usage :: Write => field. enum_write = Some ( enum_name. clone ( ) ) ,
228- svd:: Usage :: ReadWrite => field. enum_readwrite = Some ( enum_name. clone ( ) ) ,
229- }
286+ field. enumm = Some ( enum_name. clone ( ) )
230287 }
231288
232289 fieldset. fields . push ( field)
@@ -367,28 +424,6 @@ fn collect_blocks(
367424 }
368425}
369426
370- fn make_enum_name (
371- e : & svd:: EnumeratedValues ,
372- evs : & [ svd:: EnumeratedValues ] ,
373- field_name : & str ,
374- ) -> String {
375- if let Some ( name) = & e. name {
376- return name. clone ( ) ;
377- }
378-
379- let mut res = field_name. to_string ( ) ;
380- if evs. len ( ) > 1 {
381- let suffix = match e. usage {
382- None => "" ,
383- Some ( svd:: Usage :: Read ) => "_R" ,
384- Some ( svd:: Usage :: Write ) => "_W" ,
385- Some ( svd:: Usage :: ReadWrite ) => "_RW" ,
386- } ;
387- res. push_str ( suffix) ;
388- }
389- res
390- }
391-
392427fn unique_names ( names : Vec < Vec < String > > ) -> HashMap < Vec < String > , String > {
393428 let mut res = HashMap :: new ( ) ;
394429 let mut seen = HashSet :: new ( ) ;
0 commit comments