Skip to content

Commit bcae397

Browse files
bors[bot]burrbull
andcommitted
Merge #341
341: sizes, 64bit r=therealprof a=burrbull r? @therealprof Right use of cluster.size + better support of 64bit registers. See #299 , partially closed in #325 . Not tested yet. Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 2e7bf87 + b27ec4d commit bcae397

File tree

4 files changed

+30
-13
lines changed

4 files changed

+30
-13
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
- Correct handling of cluster size tag
11+
12+
- Support of 64-bit fields
13+
1014
## [v0.15.0] - 2019-07-25
1115

1216
- Logging system was introduced by `log` crate.

src/generate/peripheral.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn render(
3434
}
3535

3636
let name_pc = Ident::from(&*p.name.to_sanitized_upper_case());
37-
let address = util::hex(p.base_address);
37+
let address = util::hex(p.base_address as u64);
3838
let description = util::respace(p.description.as_ref().unwrap_or(&p.name));
3939
let derive_regs = p_derivedfrom.is_some() && p_original.registers.is_none();
4040

@@ -600,7 +600,11 @@ fn cluster_size_in_bits(info: &ClusterInfo, defs: &Defaults) -> Result<u32> {
600600
fn expand_cluster(cluster: &Cluster, defs: &Defaults) -> Result<Vec<RegisterBlockField>> {
601601
let mut cluster_expanded = vec![];
602602

603-
let cluster_size = cluster_size_in_bits(cluster, defs)
603+
let reg_size = cluster.size.or(defs.size);
604+
let mut defs = defs.clone();
605+
defs.size = reg_size;
606+
607+
let cluster_size = cluster_size_in_bits(cluster, &defs)
604608
.chain_err(|| format!("Cluster {} has no determinable `size` field", cluster.name))?;
605609

606610
match cluster {
@@ -724,7 +728,12 @@ fn cluster_block(
724728
.replace("[%s]", "")
725729
.replace("%s", "");
726730
let name_sc = Ident::from(&*mod_name.to_sanitized_snake_case());
727-
let reg_block = register_or_cluster_block(&c.children, defaults, Some(&mod_name), nightly)?;
731+
732+
let reg_size = c.size.or(defaults.size);
733+
let mut defaults = defaults.clone();
734+
defaults.size = reg_size;
735+
736+
let reg_block = register_or_cluster_block(&c.children, &defaults, Some(&mod_name), nightly)?;
728737

729738
// Generate definition for each of the registers.
730739
let registers = util::only_registers(&c.children);
@@ -734,14 +743,14 @@ fn cluster_block(
734743
&registers,
735744
p,
736745
all_peripherals,
737-
defaults,
746+
&defaults,
738747
)?);
739748
}
740749

741750
// Generate the sub-cluster blocks.
742751
let clusters = util::only_clusters(&c.children);
743752
for c in &clusters {
744-
mod_items.push(cluster_block(c, defaults, p, all_peripherals, nightly)?);
753+
mod_items.push(cluster_block(c, &defaults, p, all_peripherals, nightly)?);
745754
}
746755

747756
Ok(quote! {

src/generate/register.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub fn render(
103103
let rv = register
104104
.reset_value
105105
.or(defs.reset_value)
106-
.map(util::hex)
106+
.map(|v| util::hex(v as u64))
107107
.ok_or_else(|| format!("Register {} has no reset value", register.name))?;
108108

109109
reg_impl_items.push(quote! {
@@ -257,7 +257,7 @@ pub fn fields(
257257
access: f.access,
258258
evs: &f.enumerated_values,
259259
sc: Ident::from(&*sc),
260-
mask: util::hex((((1 as u64) << width) - 1) as u32),
260+
mask: util::hex(1u64.wrapping_neg() >> (64-width)),
261261
name: &f.name,
262262
offset: util::unsuffixed(u64::from(f.bit_range.offset)),
263263
ty: width.to_ty()?,
@@ -378,7 +378,7 @@ pub fn fields(
378378
let mut arms = variants
379379
.iter()
380380
.map(|v| {
381-
let value = util::hex_or_bool(v.value as u32, f.width);
381+
let value = util::hex_or_bool(v.value as u64, f.width);
382382
let pc = &v.pc;
383383

384384
quote! {
@@ -714,7 +714,7 @@ pub fn fields(
714714
fn unsafety(write_constraint: Option<&WriteConstraint>, width: u32) -> Option<Ident> {
715715
match &write_constraint {
716716
Some(&WriteConstraint::Range(range))
717-
if u64::from(range.min) == 0 && u64::from(range.max) == (1u64 << width) - 1 =>
717+
if u64::from(range.min) == 0 && u64::from(range.max) == 1u64.wrapping_neg() >> (64-width) =>
718718
{
719719
// the SVD has acknowledged that it's safe to write
720720
// any value that can fit in the field

src/util.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,14 @@ pub fn access_of(register: &Register) -> Access {
216216
}
217217

218218
/// Turns `n` into an unsuffixed separated hex token
219-
pub fn hex(n: u32) -> Tokens {
219+
pub fn hex(n: u64) -> Tokens {
220220
let mut t = Tokens::new();
221-
let (h2, h1) = ((n >> 16) & 0xffff, n & 0xffff);
222-
t.append(if h2 != 0 {
221+
let (h4, h3, h2, h1) = ((n >> 48) & 0xffff, (n >> 32) & 0xffff, (n >> 16) & 0xffff, n & 0xffff);
222+
t.append(if h4 != 0 {
223+
Ident::from(format!("0x{:04x}_{:04x}_{:04x}_{:04x}", h4, h3, h2, h1))
224+
} else if h3 != 0 {
225+
Ident::from(format!("0x{:04x}_{:04x}_{:04x}", h3, h2, h1))
226+
} else if h2 != 0 {
223227
Ident::from(format!("0x{:04x}_{:04x}", h2, h1))
224228
} else if h1 & 0xff00 != 0 {
225229
Ident::from(format!("0x{:04x}", h1))
@@ -231,7 +235,7 @@ pub fn hex(n: u32) -> Tokens {
231235
t
232236
}
233237

234-
pub fn hex_or_bool(n: u32, width: u32) -> Tokens {
238+
pub fn hex_or_bool(n: u64, width: u32) -> Tokens {
235239
if width == 1 {
236240
let mut t = Tokens::new();
237241
t.append(Ident::from(if n == 0 { "false" } else { "true" }));

0 commit comments

Comments
 (0)