Skip to content

Commit ef2d9c2

Browse files
committed
Add comments, clean up remaining unwraps
1 parent 770fc3d commit ef2d9c2

File tree

2 files changed

+75
-19
lines changed

2 files changed

+75
-19
lines changed

src/generate/device.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pub fn render(d: &Device, target: &Target) -> Result<Vec<Tokens>> {
124124
continue;
125125
}
126126

127+
127128
out.extend(peripheral::render(p, &d.peripherals, &d.defaults)?);
128129

129130
if p.registers

src/generate/peripheral.rs

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::borrow::Cow;
22

33
use either::Either;
44
use quote::{ToTokens, Tokens};
5-
use svd::{Cluster, Defaults, Peripheral, Register};
5+
use svd::{Cluster, ClusterInfo, Defaults, Peripheral, Register};
66
use syn::{self, Ident};
77

88
use 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.
176183
fn 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
195241
fn 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`
307360
fn 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
433487
fn 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
556611
fn convert_svd_cluster(cluster: &Cluster) -> syn::Field {
557612
let name_to_ty = |name: &String| -> syn::Ty {
558613
syn::Ty::Path(

0 commit comments

Comments
 (0)