Skip to content

Commit ee4f659

Browse files
committed
ModifiedWriteValues for 1-bit fields
1 parent 9e9ea56 commit ee4f659

File tree

3 files changed

+153
-31
lines changed

3 files changed

+153
-31
lines changed

CHANGELOG.md

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

88
## [Unreleased]
99

10+
- Use modifiedWriteValues for 1-bitwise fields if present
1011
- Use generic `FieldWriter`, `FieldReader`, `BitWriter`, `BitReader`
1112
- Disable two clippy warnings in `array_proxy.rs`
1213
- Add comments in docs about `readAction`

src/generate/generic.rs

Lines changed: 121 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -352,16 +352,16 @@ where
352352
}
353353

354354
#[doc(hidden)]
355-
pub struct BitWriterRaw<'a, U, REG, FI, const O: u8>
355+
pub struct BitWriterRaw<'a, U, REG, FI, M, const O: u8>
356356
where
357357
REG: Writable + RegisterSpec<Ux = U>,
358358
FI: Into<bool>,
359359
{
360360
pub(crate) w: &'a mut REG::Writer,
361-
_field: marker::PhantomData<FI>,
361+
_field: marker::PhantomData<(FI, M)>,
362362
}
363363

364-
impl<'a, U, REG, FI, const O: u8> BitWriterRaw<'a, U, REG, FI, O>
364+
impl<'a, U, REG, FI, M, const O: u8> BitWriterRaw<'a, U, REG, FI, M, O>
365365
where
366366
REG: Writable + RegisterSpec<Ux = U>,
367367
FI: Into<bool>,
@@ -382,9 +382,6 @@ pub type FieldWriter<'a, U, REG, N, FI, const WI: u8, const O: u8> = FieldWriter
382382
/// Write field Proxy with safe `bits`
383383
pub type FieldWriterSafe<'a, U, REG, N, FI, const WI: u8, const O: u8> = FieldWriterRaw<'a, U, REG, N, FI, Safe, WI, O>;
384384

385-
/// Bit-wise write field proxy
386-
pub type BitWriter<'a, U, REG, FI, const O: u8> = BitWriterRaw<'a, U, REG, FI, O>;
387-
388385

389386
impl<'a, U, REG, N, FI, const WI: u8, const OF: u8> FieldWriter<'a, U, REG, N, FI, WI, OF>
390387
where
@@ -408,17 +405,57 @@ where
408405
pub const OFFSET: u8 = OF;
409406
}
410407

411-
impl<'a, U, REG, FI, const OF: u8> BitWriter<'a, U, REG, FI, OF>
412-
where
413-
REG: Writable + RegisterSpec<Ux = U>,
414-
FI: Into<bool>,
415-
{
416-
/// Field width
417-
pub const WIDTH: u8 = 1;
418-
/// Field offset
419-
pub const OFFSET: u8 = OF;
408+
macro_rules! bit_proxy {
409+
($writer:ident, $mwv:ident) => {
410+
#[doc(hidden)]
411+
pub struct $mwv;
412+
413+
/// Bit-wise write field proxy
414+
pub type $writer<'a, U, REG, FI, const O: u8> = BitWriterRaw<'a, U, REG, FI, $mwv, O>;
415+
416+
impl<'a, U, REG, FI, const OF: u8> $writer<'a, U, REG, FI, OF>
417+
where
418+
REG: Writable + RegisterSpec<Ux = U>,
419+
FI: Into<bool>,
420+
{
421+
/// Field width
422+
pub const WIDTH: u8 = 1;
423+
/// Field offset
424+
pub const OFFSET: u8 = OF;
425+
}
426+
}
420427
}
421428

429+
macro_rules! impl_bit_proxy {
430+
($writer:ident, $U:ty) => {
431+
impl<'a, REG, FI, const OF: u8> $writer<'a, $U, REG, FI, OF>
432+
where
433+
REG: Writable + RegisterSpec<Ux = $U>,
434+
FI: Into<bool>,
435+
{
436+
/// Writes bit to the field
437+
#[inline(always)]
438+
pub fn bit(self, value: bool) -> &'a mut REG::Writer {
439+
self.w.bits = (self.w.bits & !(1 << { OF })) | ((<$U>::from(value) & 1) << { OF });
440+
self.w
441+
}
442+
/// Writes `variant` to the field
443+
#[inline(always)]
444+
pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
445+
self.bit(variant.into())
446+
}
447+
}
448+
}
449+
}
450+
451+
bit_proxy!(BitWriter, BitM);
452+
bit_proxy!(BitWriter1S, Bit1S);
453+
bit_proxy!(BitWriter0C, Bit0C);
454+
bit_proxy!(BitWriter1C, Bit1C);
455+
bit_proxy!(BitWriter0S, Bit0S);
456+
bit_proxy!(BitWriter1T, Bit1T);
457+
bit_proxy!(BitWriter0T, Bit0T);
458+
422459
macro_rules! impl_proxy {
423460
($U:ty) => {
424461
impl<'a, REG, N, FI, const WI: u8, const OF: u8> FieldWriter<'a, $U, REG, N, FI, WI, OF>
@@ -465,32 +502,94 @@ macro_rules! impl_proxy {
465502
self.bits(variant.into())
466503
}
467504
}
505+
impl_bit_proxy!(BitWriter, $U);
506+
impl_bit_proxy!(BitWriter1S, $U);
507+
impl_bit_proxy!(BitWriter0C, $U);
508+
impl_bit_proxy!(BitWriter1C, $U);
509+
impl_bit_proxy!(BitWriter0S, $U);
510+
impl_bit_proxy!(BitWriter1T, $U);
511+
impl_bit_proxy!(BitWriter0T, $U);
468512
impl<'a, REG, FI, const OF: u8> BitWriter<'a, $U, REG, FI, OF>
469513
where
470514
REG: Writable + RegisterSpec<Ux = $U>,
471515
FI: Into<bool>,
472516
{
473-
/// Writes bit to the field
517+
/// Sets the field bit
474518
#[inline(always)]
475-
pub fn bit(self, value: bool) -> &'a mut REG::Writer {
476-
self.w.bits = (self.w.bits & !(1 << { OF })) | ((<$U>::from(value) & 1) << { OF });
477-
self.w
519+
pub fn set_bit(self) -> &'a mut REG::Writer {
520+
self.bit(true)
478521
}
479-
/// Writes `variant` to the field
522+
/// Clears the field bit
480523
#[inline(always)]
481-
pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
482-
self.bit(variant.into())
524+
pub fn clear_bit(self) -> &'a mut REG::Writer {
525+
self.bit(false)
483526
}
527+
}
528+
impl<'a, REG, FI, const OF: u8> BitWriter1S<'a, $U, REG, FI, OF>
529+
where
530+
REG: Writable + RegisterSpec<Ux = $U>,
531+
FI: Into<bool>,
532+
{
484533
/// Sets the field bit
485534
#[inline(always)]
486535
pub fn set_bit(self) -> &'a mut REG::Writer {
487536
self.bit(true)
488537
}
538+
}
539+
impl<'a, REG, FI, const OF: u8> BitWriter0C<'a, $U, REG, FI, OF>
540+
where
541+
REG: Writable + RegisterSpec<Ux = $U>,
542+
FI: Into<bool>,
543+
{
489544
/// Clears the field bit
490545
#[inline(always)]
491546
pub fn clear_bit(self) -> &'a mut REG::Writer {
492547
self.bit(false)
493548
}
494549
}
550+
impl<'a, REG, FI, const OF: u8> BitWriter1C<'a, $U, REG, FI, OF>
551+
where
552+
REG: Writable + RegisterSpec<Ux = $U>,
553+
FI: Into<bool>,
554+
{
555+
///Clears the field bit by passing one
556+
#[inline(always)]
557+
pub fn clear_bit_by_one(self) -> &'a mut REG::Writer {
558+
self.bit(true)
559+
}
560+
}
561+
impl<'a, REG, FI, const OF: u8> BitWriter0S<'a, $U, REG, FI, OF>
562+
where
563+
REG: Writable + RegisterSpec<Ux = $U>,
564+
FI: Into<bool>,
565+
{
566+
///Sets the field bit by passing zero
567+
#[inline(always)]
568+
pub fn set_bit_by_zero(self) -> &'a mut REG::Writer {
569+
self.bit(false)
570+
}
571+
}
572+
impl<'a, REG, FI, const OF: u8> BitWriter1T<'a, $U, REG, FI, OF>
573+
where
574+
REG: Writable + RegisterSpec<Ux = $U>,
575+
FI: Into<bool>,
576+
{
577+
///Toggle the field bit by passing one
578+
#[inline(always)]
579+
pub fn toggle_bit(self) -> &'a mut REG::Writer {
580+
self.bit(true)
581+
}
582+
}
583+
impl<'a, REG, FI, const OF: u8> BitWriter0T<'a, $U, REG, FI, OF>
584+
where
585+
REG: Writable + RegisterSpec<Ux = $U>,
586+
FI: Into<bool>,
587+
{
588+
///Toggle the field bit by passing zero
589+
#[inline(always)]
590+
pub fn toggle_bit(self) -> &'a mut REG::Writer {
591+
self.bit(false)
592+
}
593+
}
495594
}
496595
}

src/generate/register.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::svd::{
2-
Access, BitRange, DeriveFrom, EnumeratedValues, Field, Peripheral, ReadAction, Register,
3-
RegisterProperties, Usage, WriteConstraint,
2+
Access, BitRange, DeriveFrom, EnumeratedValues, Field, ModifiedWriteValues, Peripheral,
3+
ReadAction, Register, RegisterProperties, Usage, WriteConstraint,
44
};
55
use cast::u64;
66
use core::u64;
@@ -604,6 +604,10 @@ pub fn fields(
604604
}
605605

606606
if can_write {
607+
let mwv = f
608+
.modified_write_values
609+
.or(register.modified_write_values)
610+
.unwrap_or_default();
607611
let writerdoc = if let Some((_, _, _, _, suffixes_str)) = &field_dim {
608612
format!(
609613
"Fields `{}` writer - {}",
@@ -673,20 +677,38 @@ pub fn fields(
673677
}
674678

675679
if !derived {
676-
let wproxy = if unsafety {
677-
Ident::new("FieldWriter", span)
678-
} else {
679-
Ident::new("FieldWriterSafe", span)
680-
};
681-
682680
let (offset, gen_offset) = if field_dim.is_some() {
683681
(quote! { O }, quote! {, const O: u8 })
684682
} else {
685683
(util::unsuffixed(offset as u64), quote! {})
686684
};
687685
let proxy = if width == 1 {
688-
quote! { crate::BitWriter<'a, #rty, #name_uc_spec, #name_pc_aw, #offset> }
686+
let wproxy = Ident::new(
687+
match mwv {
688+
ModifiedWriteValues::Modify => "BitWriter",
689+
ModifiedWriteValues::OneToSet | ModifiedWriteValues::Set => {
690+
"BitWriter1S"
691+
}
692+
ModifiedWriteValues::ZeroToClear | ModifiedWriteValues::Clear => {
693+
"BitWriter0C"
694+
}
695+
ModifiedWriteValues::OneToClear => "BitWriter1C",
696+
ModifiedWriteValues::ZeroToSet => "BitWriter0C",
697+
ModifiedWriteValues::OneToToggle => "BitWriter1T",
698+
ModifiedWriteValues::ZeroToToggle => "BitWriter0T",
699+
},
700+
span,
701+
);
702+
quote! { crate::#wproxy<'a, #rty, #name_uc_spec, #name_pc_aw, #offset> }
689703
} else {
704+
let wproxy = Ident::new(
705+
if unsafety {
706+
"FieldWriter"
707+
} else {
708+
"FieldWriterSafe"
709+
},
710+
span,
711+
);
690712
let width = &util::unsuffixed(width as _);
691713
quote! { crate::#wproxy<'a, #rty, #name_uc_spec, #fty, #name_pc_aw, #width, #offset> }
692714
};

0 commit comments

Comments
 (0)