Skip to content

Commit c758eb7

Browse files
committed
Recognize <writeConstraint> in <register>.
This is useful in cases where the entire register is safely writable and is a uniform collection of bits, e.g. GPIO direction or data registers.
1 parent abbd6b1 commit c758eb7

File tree

3 files changed

+27
-25
lines changed

3 files changed

+27
-25
lines changed

Cargo.lock

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ either = "1.0.3"
1616
error-chain = "0.10.0"
1717
inflections = "1.0.0"
1818
quote = "0.3.15"
19-
svd-parser = "0.5.0"
20-
syn = "0.11.9"
19+
svd-parser = "0.5.1"
20+
syn = "0.11.9"

src/generate.rs

+22-20
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,18 @@ fn register_block(registers: &[Register], defs: &Defaults) -> Result<Tokens> {
392392
)
393393
}
394394

395+
fn unsafety(write_constraint: Option<&WriteConstraint>, width: u32) -> Option<Ident> {
396+
match write_constraint {
397+
Some(&WriteConstraint::Range(ref range))
398+
if range.min as u64 == 0 && range.max as u64 == (1u64 << width) - 1 => {
399+
// the SVD has acknowledged that it's safe to write
400+
// any value that can fit in the field
401+
None
402+
}
403+
_ => Some(Ident::new("unsafe"))
404+
}
405+
}
406+
395407
pub fn register(
396408
register: &Register,
397409
all_registers: &[Register],
@@ -403,15 +415,17 @@ pub fn register(
403415
let name = util::name_of(register);
404416
let name_pc = Ident::new(&*name.to_sanitized_pascal_case());
405417
let name_sc = Ident::new(&*name.to_sanitized_snake_case());
406-
let rty = register.size
418+
let rsize = register.size
407419
.or(defs.size)
408420
.ok_or_else(|| {
409421
format!("Register {} has no `size` field",
410422
register.name)
411-
})?
412-
.to_ty()?;
423+
})?;
424+
let rty = rsize.to_ty()?;
413425
let description = util::respace(&register.description);
414426

427+
let unsafety = unsafety(register.write_constraint.as_ref(), rsize);
428+
415429
let mut mod_items = vec![];
416430
let mut reg_impl_items = vec![];
417431
let mut r_impl_items = vec![];
@@ -510,7 +524,7 @@ pub fn register(
510524

511525
/// Writes raw bits to the register
512526
#[inline(always)]
513-
pub unsafe fn bits(&mut self, bits: #rty) -> &mut Self {
527+
pub #unsafety fn bits(&mut self, bits: #rty) -> &mut Self {
514528
self.bits = bits;
515529
self
516530
}
@@ -944,19 +958,7 @@ pub fn fields(
944958

945959
let mut proxy_items = vec![];
946960

947-
let mut safety = Some(Ident::new("unsafe"));
948-
if let Some(write_constraint) = f.write_constraint {
949-
match *write_constraint {
950-
WriteConstraint::Range(ref range) => {
951-
if range.min as u64 == 0 && range.max as u64 == (1u64 << f.width) - 1 {
952-
// the SVD has acknowledged that it's safe to write
953-
// any value that can fit in the bitfield
954-
safety = None;
955-
}
956-
}
957-
_ => {}
958-
}
959-
}
961+
let mut unsafety = unsafety(f.write_constraint, f.width);
960962
let fty = &f.ty;
961963
let offset = &f.offset;
962964
let mask = &f.mask;
@@ -1044,7 +1046,7 @@ pub fn fields(
10441046
.collect::<Result<Vec<_>>>()?;
10451047

10461048
if variants.len() == 1 << f.width {
1047-
safety = None;
1049+
unsafety = None;
10481050
}
10491051

10501052
if base.is_none() {
@@ -1095,7 +1097,7 @@ pub fn fields(
10951097
/// Writes `variant` to the field
10961098
#[inline(always)]
10971099
pub fn variant(self, variant: #pc_w) -> &'a mut W {
1098-
#safety {
1100+
#unsafety {
10991101
self.bits(variant._bits())
11001102
}
11011103
}
@@ -1135,7 +1137,7 @@ pub fn fields(
11351137
quote! {
11361138
/// Writes raw bits to the field
11371139
#[inline(always)]
1138-
pub #safety fn bits(self, bits: #fty) -> &'a mut W {
1140+
pub #unsafety fn bits(self, bits: #fty) -> &'a mut W {
11391141
const MASK: #fty = #mask;
11401142
const OFFSET: u8 = #offset;
11411143

0 commit comments

Comments
 (0)