@@ -23,7 +23,6 @@ struct ProtoFieldset {
23
23
#[ derive( Debug ) ]
24
24
struct ProtoEnum {
25
25
name : Vec < String > ,
26
- usage : Option < svd:: Usage > ,
27
26
bit_size : u32 ,
28
27
variants : Vec < svd:: EnumeratedValue > ,
29
28
}
@@ -58,26 +57,97 @@ pub fn convert_peripheral(ir: &mut IR, p: &svd::Peripheral) -> anyhow::Result<()
58
57
} ) ;
59
58
60
59
for f in fields {
60
+ info ! ( "field {}.{}" , r. name, f. name) ;
61
+
61
62
if f. derived_from . is_some ( ) {
62
63
continue ;
63
64
}
64
65
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 ;
66
69
67
70
for e in & f. enumerated_values {
68
71
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) ;
69
86
continue ;
70
87
}
71
88
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
+ }
75
96
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 ( ) ) ;
76
147
enums. push ( ProtoEnum {
77
- name : enum_name,
78
- usage : e. usage ,
148
+ name,
79
149
bit_size : f. bit_range . width ,
80
- variants : e . values . clone ( ) ,
150
+ variants,
81
151
} ) ;
82
152
}
83
153
}
@@ -203,30 +273,17 @@ pub fn convert_peripheral(ir: &mut IR, p: &svd::Peripheral) -> anyhow::Result<()
203
273
bit_offset : f. bit_range . offset ,
204
274
bit_size : f. bit_range . width ,
205
275
array : None ,
206
- enum_read : None ,
207
- enum_write : None ,
208
- enum_readwrite : None ,
276
+ enumm : None ,
209
277
} ;
210
278
211
- for e in & f. enumerated_values {
279
+ if ! f. enumerated_values . is_empty ( ) {
212
280
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
+
218
283
info ! ( "finding enum {:?}" , enum_name) ;
219
- let enumm = enums. iter ( ) . find ( |e| e. name == enum_name) . unwrap ( ) ;
220
284
let enum_name = enum_names. get ( & enum_name) . unwrap ( ) . clone ( ) ;
221
285
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 ( ) )
230
287
}
231
288
232
289
fieldset. fields . push ( field)
@@ -367,28 +424,6 @@ fn collect_blocks(
367
424
}
368
425
}
369
426
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
-
392
427
fn unique_names ( names : Vec < Vec < String > > ) -> HashMap < Vec < String > , String > {
393
428
let mut res = HashMap :: new ( ) ;
394
429
let mut seen = HashSet :: new ( ) ;
0 commit comments