@@ -2,7 +2,7 @@ use std::borrow::Cow;
22
33use either:: Either ;
44use quote:: { ToTokens , Tokens } ;
5- use svd:: { Cluster , Defaults , Peripheral , Register } ;
5+ use svd:: { Cluster , ClusterInfo , Defaults , Peripheral , Register } ;
66use syn:: { self , Ident } ;
77
88use errors:: * ;
@@ -31,6 +31,7 @@ pub fn render(
3131 ( name_sc. clone ( ) , false )
3232 } ;
3333
34+ // Insert the peripheral structure
3435 out. push ( quote ! {
3536 #[ doc = #description]
3637 pub struct #name_pc { _marker: PhantomData <* const ( ) > }
@@ -53,6 +54,8 @@ pub fn render(
5354 }
5455 } ) ;
5556
57+ // Derived peripherals do not require re-implementation, and will instead
58+ // use a single definition of the non-derived version
5659 if derived {
5760 return Ok ( out) ;
5861 }
@@ -65,19 +68,21 @@ pub fn render(
6568
6669 // No `struct RegisterBlock` can be generated
6770 if registers. is_empty ( ) && clusters. is_empty ( ) {
68- // Drop the `#name_pc` definition of the peripheral
71+ // Drop the definition of the peripheral
6972 out. pop ( ) ;
7073 return Ok ( out) ;
7174 }
7275
76+ // Push any register or cluster blocks into the output
7377 let mut mod_items = vec ! [ ] ;
7478 mod_items. push ( register_or_cluster_block ( ercs, defaults, None ) ?) ;
7579
76- // Push all cluster related information into the peripheral module.
80+ // Push all cluster related information into the peripheral module
7781 for c in & clusters {
7882 mod_items. push ( cluster_block ( c, defaults, p, all_peripherals) ?) ;
7983 }
8084
85+ // Push all regsiter realted information into the peripheral module
8186 for reg in registers {
8287 mod_items. extend ( register:: render (
8388 reg,
@@ -126,9 +131,9 @@ fn register_or_cluster_block(
126131 pad
127132 } else {
128133 eprintln ! (
129- "WARNING {} overlaps with another register at offset {}. \
134+ "WARNING {:? } overlaps with another register block at offset {}. \
130135 Ignoring.",
131- reg_block_field. field. ident. unwrap ( ) ,
136+ reg_block_field. field. ident,
132137 reg_block_field. offset
133138 ) ;
134139 continue ;
@@ -173,6 +178,8 @@ fn register_or_cluster_block(
173178 } )
174179}
175180
181+ /// Expand a list of parsed `Register`s or `Cluster`s, and render them to
182+ /// `RegisterBlockField`s containing `Field`s.
176183fn expand (
177184 ercs : & [ Either < Register , Cluster > ] ,
178185 defs : & Defaults ,
@@ -192,21 +199,64 @@ fn expand(
192199 Ok ( ercs_expanded)
193200}
194201
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
195241fn expand_cluster ( cluster : & Cluster , defs : & Defaults ) -> Result < Vec < RegisterBlockField > > {
196242 let mut cluster_expanded = vec ! [ ] ;
197243
244+
198245 let cluster_size = cluster
199246 . 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) ) ?;
202250
203251 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+ } ,
210260 Cluster :: Array ( ref info, ref array_info) => {
211261 let sequential_addresses = cluster_size == array_info. dim_increment * BITS_PER_BYTE ;
212262
@@ -260,12 +310,14 @@ fn expand_register(
260310 . ok_or_else ( || format ! ( "Register {} has no `size` field" , register. name) ) ?;
261311
262312 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+ } ,
269321 Register :: Array ( ref info, ref array_info) => {
270322 let sequential_addresses = register_size == array_info. dim_increment * BITS_PER_BYTE ;
271323
@@ -304,6 +356,7 @@ fn expand_register(
304356 Ok ( register_expanded)
305357}
306358
359+ /// Render a Cluster Block into `Tokens`
307360fn cluster_block (
308361 c : & Cluster ,
309362 defaults : & Defaults ,
@@ -430,6 +483,7 @@ fn expand_svd_register(register: &Register, name: Option<&str>) -> Vec<syn::Fiel
430483 out
431484}
432485
486+ /// Convert a parsed `Register` into its `Field` equivalent
433487fn convert_svd_register ( register : & Register , name : Option < & str > ) -> syn:: Field {
434488 let name_to_ty = |name : & String , ns : Option < & str > | -> syn:: Ty {
435489 let ident = if let Some ( ns) = ns {
@@ -553,6 +607,7 @@ fn expand_svd_cluster(cluster: &Cluster) -> Vec<syn::Field> {
553607 out
554608}
555609
610+ /// Convert a parsed `Cluster` into its `Field` equivalent
556611fn convert_svd_cluster ( cluster : & Cluster ) -> syn:: Field {
557612 let name_to_ty = |name : & String | -> syn:: Ty {
558613 syn:: Ty :: Path (
0 commit comments