Skip to content

Commit cabb504

Browse files
committed
add WriteEnum & rm FieldWriterSafe, add set
1 parent 6f5479e commit cabb504

File tree

3 files changed

+36
-43
lines changed

3 files changed

+36
-43
lines changed

CHANGELOG.md

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

88
## [Unreleased]
99

10+
- Add `WriteEnum` constraint for `FieldWriter`s (fix `variant` safety)
11+
- Make field writer `bits` always `unsafe` add `set` for safe writing
1012
- Fix bit writer type for `ModifiedWriteValues::ZeroToSet`
1113

1214
## [v0.32.0] - 2024-02-26

src/generate/generic.rs

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ pub trait FieldSpec: Sized {
5656
type Ux: Copy + PartialEq + From<Self>;
5757
}
5858

59+
/// Marker for fields with fixed values
60+
pub trait IsEnum: FieldSpec {}
61+
5962
/// Trait implemented by readable registers to enable the `read` method.
6063
///
6164
/// Registers marked with `Writable` can be also be `modify`'ed.
@@ -474,16 +477,13 @@ pub struct Safe;
474477
/// You should check that value is allowed to pass to register/field writer marked with this
475478
pub struct Unsafe;
476479

477-
/// Write field Proxy with unsafe `bits`
478-
pub type FieldWriter<'a, REG, const WI: u8, FI = u8> = raw::FieldWriter<'a, REG, WI, FI, Unsafe>;
479-
/// Write field Proxy with safe `bits`
480-
pub type FieldWriterSafe<'a, REG, const WI: u8, FI = u8> = raw::FieldWriter<'a, REG, WI, FI, Safe>;
480+
/// Write field Proxy
481+
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> = raw::FieldWriter<'a, REG, WI, FI, Safety>;
481482

482-
impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI>
483+
impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
483484
where
484485
REG: Writable + RegisterSpec,
485486
FI: FieldSpec,
486-
REG::Ux: From<FI::Ux>,
487487
{
488488
/// Field width
489489
pub const WIDTH: u8 = WI;
@@ -499,7 +499,14 @@ where
499499
pub const fn offset(&self) -> u8 {
500500
self.o
501501
}
502+
}
502503

504+
impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
505+
where
506+
REG: Writable + RegisterSpec,
507+
FI: FieldSpec,
508+
REG::Ux: From<FI::Ux>,
509+
{
503510
/// Writes raw bits to the field
504511
///
505512
/// # Safety
@@ -511,45 +518,31 @@ where
511518
self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << self.o;
512519
self.w
513520
}
514-
/// Writes `variant` to the field
515-
#[inline(always)]
516-
pub fn variant(self, variant: FI) -> &'a mut W<REG> {
517-
unsafe { self.bits(FI::Ux::from(variant)) }
518-
}
519521
}
520522

521-
impl<'a, REG, const WI: u8, FI> FieldWriterSafe<'a, REG, WI, FI>
523+
impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI, Safe>
522524
where
523525
REG: Writable + RegisterSpec,
524526
FI: FieldSpec,
525527
REG::Ux: From<FI::Ux>,
526528
{
527-
/// Field width
528-
pub const WIDTH: u8 = WI;
529-
530-
/// Field width
531-
#[inline(always)]
532-
pub const fn width(&self) -> u8 {
533-
WI
534-
}
535-
536-
/// Field offset
537-
#[inline(always)]
538-
pub const fn offset(&self) -> u8 {
539-
self.o
540-
}
541-
542529
/// Writes raw bits to the field
543530
#[inline(always)]
544-
pub fn bits(self, value: FI::Ux) -> &'a mut W<REG> {
545-
self.w.bits &= !(REG::Ux::mask::<WI>() << self.o);
546-
self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << self.o;
547-
self.w
531+
pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
532+
unsafe { self.bits(value) }
548533
}
534+
}
535+
536+
impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
537+
where
538+
REG: Writable + RegisterSpec,
539+
FI: IsEnum,
540+
REG::Ux: From<FI::Ux>,
541+
{
549542
/// Writes `variant` to the field
550543
#[inline(always)]
551544
pub fn variant(self, variant: FI) -> &'a mut W<REG> {
552-
self.bits(FI::Ux::from(variant))
545+
unsafe { self.bits(FI::Ux::from(variant)) }
553546
}
554547
}
555548

src/generate/register.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,19 +1235,16 @@ pub fn fields(
12351235
quote! { crate::#wproxy<'a, REG, #value_write_ty> }
12361236
}
12371237
} else {
1238-
let wproxy = Ident::new(
1239-
if unsafety {
1240-
"FieldWriter"
1241-
} else {
1242-
"FieldWriterSafe"
1243-
},
1244-
span,
1245-
);
1238+
let wproxy = Ident::new("FieldWriter", span);
12461239
let width = &unsuffixed(width);
1247-
if value_write_ty == "u8" {
1240+
if value_write_ty == "u8" && unsafety {
12481241
quote! { crate::#wproxy<'a, REG, #width> }
1249-
} else {
1242+
} else if unsafety {
12501243
quote! { crate::#wproxy<'a, REG, #width, #value_write_ty> }
1244+
} else {
1245+
let safe_ty =
1246+
Ident::new(if unsafety { "Unsafe" } else { "Safe" }, span);
1247+
quote! { crate::#wproxy<'a, REG, #width, #value_write_ty, crate::#safe_ty> }
12511248
}
12521249
};
12531250
mod_items.extend(quote! {
@@ -1425,7 +1422,7 @@ impl Variant {
14251422
span,
14261423
);
14271424
let sc = case.sanitize(&ev.name);
1428-
const INTERNALS: [&str; 4] = ["set_bit", "clear_bit", "bit", "bits"];
1425+
const INTERNALS: [&str; 6] = ["bit", "bits", "clear_bit", "set", "set_bit", "variant"];
14291426
let sc = Ident::new(
14301427
&(if INTERNALS.contains(&sc.as_ref()) {
14311428
sc + "_"
@@ -1552,6 +1549,7 @@ fn add_from_variants<'a>(
15521549
impl crate::FieldSpec for #pc {
15531550
type Ux = #fty;
15541551
}
1552+
impl crate::IsEnum for #pc {}
15551553
});
15561554
}
15571555
}

0 commit comments

Comments
 (0)