Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OFFSET & WIDTH constanst #583

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

- Constant values of field offsets and width
- added `dyn` keyword to sanatizer.

### Changed

- Generate Rust arrays for all register & cluster arrays with sequential_addresses.
Expand Down
51 changes: 41 additions & 10 deletions src/generate/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ pub fn fields(
let can_write = can_write && (f.access != Some(Access::ReadOnly));

let mask = u64::MAX >> (64 - width);
let hexmask = &util::hex(mask);
let hexmask = &util::digit_or_hex(mask);
let offset = u64::from(offset);
let rv = properties.reset_value.map(|rv| (rv >> offset) & mask);
let fty = width.to_ty()?;
Expand Down Expand Up @@ -347,8 +347,8 @@ pub fn fields(
let mut evs_r = None;

let field_dim = match f {
Field::Array(_, de) => {
let (first, index) = if let Some(dim_index) = &de.dim_index {
Field::Array(info, de) => {
let first = if let Some(dim_index) = &de.dim_index {
if let Ok(first) = dim_index[0].parse::<u32>() {
let sequential_indexes = dim_index
.iter()
Expand All @@ -357,24 +357,42 @@ pub fn fields(
if !sequential_indexes {
return Err(anyhow!("unsupported array indexes in {}", f.name));
}
(first, None)
first
} else {
(0, de.dim_index.clone())
0
}
} else {
(0, None)
};
let suffixes: Vec<_> = match index {
Some(ix) => ix,
None => (0..de.dim).map(|i| (first + i).to_string()).collect(),
0
};
let suffixes: Vec<_> = de.indexes().collect();
let suffixes_str = format!("({}-{})", first, first + de.dim - 1);
for (name, offset) in
crate::svd::array::names(info, de).zip(svd_rs::field::bit_offsets(info, de))
{
let offset_name = Ident::new(
&(name.clone() + "_OFFSET").to_sanitized_upper_case(),
Span::call_site(),
);
let doc = format!("`{}` field offset", name);
let offset = &util::unsuffixed(offset as _);
mod_items.extend(quote! {
#[doc = #doc]
pub const #offset_name: u8 = #offset;
});
}
Some((first, de.dim, de.dim_increment, suffixes, suffixes_str))
}
Field::Single(_) => {
if f.name.contains("%s") {
return Err(anyhow!("incorrect field {}", f.name));
}
let doc = format!("`{}` field offset", f.name);
let offset_name = Ident::new(&(name_pc.clone() + "_OFFSET"), span);
let offset = &util::unsuffixed(offset);
mod_items.extend(quote! {
#[doc = #doc]
pub const #offset_name: u8 = #offset;
});
None
}
};
Expand Down Expand Up @@ -558,11 +576,14 @@ pub fn fields(
}
}

let unwidth = crate::util::unsuffixed(width as _);
mod_items.extend(quote! {
#[doc = #readerdoc]
pub struct #name_pc_r(crate::FieldReader<#fty, #name_pc_a>);

impl #name_pc_r {
#[doc = "Field width"]
pub const WIDTH: u8 = #unwidth;
#[inline(always)]
pub(crate) fn new(bits: #fty) -> Self {
#name_pc_r(crate::FieldReader::new(bits))
Expand All @@ -581,11 +602,14 @@ pub fn fields(
});
}
} else {
let unwidth = crate::util::unsuffixed(width as _);
mod_items.extend(quote! {
#[doc = #readerdoc]
pub struct #name_pc_r(crate::FieldReader<#fty, #fty>);

impl #name_pc_r {
#[doc = "Field width"]
pub const WIDTH: u8 = #unwidth;
#[inline(always)]
pub(crate) fn new(bits: #fty) -> Self {
#name_pc_r(crate::FieldReader::new(bits))
Expand All @@ -610,6 +634,13 @@ pub fn fields(
let name_pc_cgw = Ident::new(&(name_pc.clone() + "_CGW"), span);

let mut proxy_items = TokenStream::new();

let unwidth = crate::util::unsuffixed(width as _);
proxy_items.extend(quote! {
#[doc = "Field width"]
pub const WIDTH: u8 = #unwidth;
});

let mut unsafety = unsafety(f.write_constraint.as_ref(), width);

if let Some((evs, base)) = lookup_filter(&lookup_results, Usage::Write) {
Expand Down
8 changes: 8 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,14 @@ pub fn access_of(properties: &RegisterProperties, fields: Option<&[Field]>) -> A
})
}

pub fn digit_or_hex(n: u64) -> TokenStream {
if n < 10 {
unsuffixed(n)
} else {
hex(n)
}
}

/// Turns `n` into an unsuffixed separated hex token
pub fn hex(n: u64) -> TokenStream {
let (h4, h3, h2, h1) = (
Expand Down