@@ -2,7 +2,7 @@ use std::borrow::Cow;
2
2
3
3
use either:: Either ;
4
4
use quote:: { ToTokens , Tokens } ;
5
- use svd:: { Cluster , Defaults , Peripheral , Register } ;
5
+ use svd:: { Cluster , ClusterInfo , Defaults , Peripheral , Register } ;
6
6
use syn:: { self , Ident } ;
7
7
8
8
use errors:: * ;
@@ -31,6 +31,7 @@ pub fn render(
31
31
( name_sc. clone ( ) , false )
32
32
} ;
33
33
34
+ // Insert the peripheral structure
34
35
out. push ( quote ! {
35
36
#[ doc = #description]
36
37
pub struct #name_pc { _marker: PhantomData <* const ( ) > }
@@ -53,6 +54,8 @@ pub fn render(
53
54
}
54
55
} ) ;
55
56
57
+ // Derived peripherals do not require re-implementation, and will instead
58
+ // use a single definition of the non-derived version
56
59
if derived {
57
60
return Ok ( out) ;
58
61
}
@@ -65,19 +68,21 @@ pub fn render(
65
68
66
69
// No `struct RegisterBlock` can be generated
67
70
if registers. is_empty ( ) && clusters. is_empty ( ) {
68
- // Drop the `#name_pc` definition of the peripheral
71
+ // Drop the definition of the peripheral
69
72
out. pop ( ) ;
70
73
return Ok ( out) ;
71
74
}
72
75
76
+ // Push any register or cluster blocks into the output
73
77
let mut mod_items = vec ! [ ] ;
74
78
mod_items. push ( register_or_cluster_block ( ercs, defaults, None ) ?) ;
75
79
76
- // Push all cluster related information into the peripheral module.
80
+ // Push all cluster related information into the peripheral module
77
81
for c in & clusters {
78
82
mod_items. push ( cluster_block ( c, defaults, p, all_peripherals) ?) ;
79
83
}
80
84
85
+ // Push all regsiter realted information into the peripheral module
81
86
for reg in registers {
82
87
mod_items. extend ( register:: render (
83
88
reg,
@@ -126,9 +131,9 @@ fn register_or_cluster_block(
126
131
pad
127
132
} else {
128
133
eprintln ! (
129
- "WARNING {} overlaps with another register at offset {}. \
134
+ "WARNING {:? } overlaps with another register block at offset {}. \
130
135
Ignoring.",
131
- reg_block_field. field. ident. unwrap ( ) ,
136
+ reg_block_field. field. ident,
132
137
reg_block_field. offset
133
138
) ;
134
139
continue ;
@@ -173,6 +178,8 @@ fn register_or_cluster_block(
173
178
} )
174
179
}
175
180
181
+ /// Expand a list of parsed `Register`s or `Cluster`s, and render them to
182
+ /// `RegisterBlockField`s containing `Field`s.
176
183
fn expand (
177
184
ercs : & [ Either < Register , Cluster > ] ,
178
185
defs : & Defaults ,
@@ -192,21 +199,64 @@ fn expand(
192
199
Ok ( ercs_expanded)
193
200
}
194
201
202
+ /// Recursively calculate the size of a cluster. A cluster's size is the sum of
203
+ /// all of its children clusters and registers
204
+ fn cluster_size_in_bits ( info : & ClusterInfo , defs : & Defaults ) -> Result < u32 > {
205
+ // Cluster size is the summation of the size of each of the cluster's children.
206
+ let mut offset = 0 ;
207
+ let mut size = 0 ;
208
+
209
+ for c in & info. children {
210
+ size += match * c {
211
+ Either :: Left ( ref reg) => {
212
+ let pad = reg. address_offset . checked_sub ( offset)
213
+ . ok_or_else ( ||
214
+ format ! ( "Warning! overlap while calculating Register Size within a Cluster! Cluster contents may be incorrectly aligned!" ) ) ?
215
+ * BITS_PER_BYTE ;
216
+
217
+
218
+ let reg_size: u32 = expand_register ( reg, defs, None ) ?
219
+ . iter ( )
220
+ . map ( |rbf| rbf. size )
221
+ . sum ( ) ;
222
+
223
+ pad + reg_size
224
+ }
225
+ Either :: Right ( ref clust) => {
226
+ let pad = clust. address_offset . checked_sub ( offset)
227
+ . ok_or_else ( ||
228
+ format ! ( "Warning! overlap while calculating Cluster Size within a Cluster! Cluster contents may be incorrectly aligned!" ) ) ?
229
+ * BITS_PER_BYTE ;
230
+
231
+ pad + cluster_size_in_bits ( clust, defs) ?
232
+ }
233
+ } ;
234
+
235
+ offset = size / BITS_PER_BYTE ;
236
+ }
237
+ Ok ( size)
238
+ }
239
+
240
+ /// Render a given cluster (and any children) into `RegisterBlockField`s
195
241
fn expand_cluster ( cluster : & Cluster , defs : & Defaults ) -> Result < Vec < RegisterBlockField > > {
196
242
let mut cluster_expanded = vec ! [ ] ;
197
243
244
+
198
245
let cluster_size = cluster
199
246
. size
200
- . or ( defs. size )
201
- . ok_or_else ( || format ! ( "Cluster {} has no `size` field" , cluster. name) ) ?;
247
+ . ok_or_else ( || format ! ( "Cluster {} has no explictly defined size" , cluster. name) )
248
+ . or_else ( |_e| cluster_size_in_bits ( cluster, defs) )
249
+ . chain_err ( || format ! ( "Cluster {} has no determinable `size` field" , cluster. name) ) ?;
202
250
203
251
match * cluster {
204
- Cluster :: Single ( ref info) => cluster_expanded. push ( RegisterBlockField {
205
- field : convert_svd_cluster ( cluster) ,
206
- description : info. description . clone ( ) ,
207
- offset : info. address_offset ,
208
- size : cluster_size,
209
- } ) ,
252
+ Cluster :: Single ( ref info) => {
253
+ cluster_expanded. push ( RegisterBlockField {
254
+ field : convert_svd_cluster ( cluster) ,
255
+ description : info. description . clone ( ) ,
256
+ offset : info. address_offset ,
257
+ size : cluster_size,
258
+ } )
259
+ } ,
210
260
Cluster :: Array ( ref info, ref array_info) => {
211
261
let sequential_addresses = cluster_size == array_info. dim_increment * BITS_PER_BYTE ;
212
262
@@ -260,12 +310,14 @@ fn expand_register(
260
310
. ok_or_else ( || format ! ( "Register {} has no `size` field" , register. name) ) ?;
261
311
262
312
match * register {
263
- Register :: Single ( ref info) => register_expanded. push ( RegisterBlockField {
264
- field : convert_svd_register ( register, name) ,
265
- description : info. description . clone ( ) ,
266
- offset : info. address_offset ,
267
- size : register_size,
268
- } ) ,
313
+ Register :: Single ( ref info) => {
314
+ register_expanded. push ( RegisterBlockField {
315
+ field : convert_svd_register ( register, name) ,
316
+ description : info. description . clone ( ) ,
317
+ offset : info. address_offset ,
318
+ size : register_size,
319
+ } )
320
+ } ,
269
321
Register :: Array ( ref info, ref array_info) => {
270
322
let sequential_addresses = register_size == array_info. dim_increment * BITS_PER_BYTE ;
271
323
@@ -304,6 +356,7 @@ fn expand_register(
304
356
Ok ( register_expanded)
305
357
}
306
358
359
+ /// Render a Cluster Block into `Tokens`
307
360
fn cluster_block (
308
361
c : & Cluster ,
309
362
defaults : & Defaults ,
@@ -430,6 +483,7 @@ fn expand_svd_register(register: &Register, name: Option<&str>) -> Vec<syn::Fiel
430
483
out
431
484
}
432
485
486
+ /// Convert a parsed `Register` into its `Field` equivalent
433
487
fn convert_svd_register ( register : & Register , name : Option < & str > ) -> syn:: Field {
434
488
let name_to_ty = |name : & String , ns : Option < & str > | -> syn:: Ty {
435
489
let ident = if let Some ( ns) = ns {
@@ -553,6 +607,7 @@ fn expand_svd_cluster(cluster: &Cluster) -> Vec<syn::Field> {
553
607
out
554
608
}
555
609
610
+ /// Convert a parsed `Cluster` into its `Field` equivalent
556
611
fn convert_svd_cluster ( cluster : & Cluster ) -> syn:: Field {
557
612
let name_to_ty = |name : & String | -> syn:: Ty {
558
613
syn:: Ty :: Path (
0 commit comments