Skip to content

Commit 1131083

Browse files
bors[bot]burrbull
andauthored
Merge #673
673: initial_write_value for registers with modifiedWriteValues r=therealprof a=burrbull Related to #540 Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 778087b + 6de189f commit 1131083

File tree

3 files changed

+56
-27
lines changed

3 files changed

+56
-27
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+
- Change initial write value for registers with modifiedWriteValues
1011
- Update `clap` to 4.0, use `irx-config` instead of `clap_conf`
1112
- Add #[must_use] to prevent hanging field writers
1213
- Remove explicit deref in `generic.rs` since it's done by auto-deref

src/generate/generic.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::marker;
33
/// Raw register type
44
pub trait RegisterSpec {
55
/// Raw register type (`u8`, `u16`, `u32`, ...).
6-
type Ux: Copy;
6+
type Ux: Copy + Default + core::ops::BitOr<Output=Self::Ux> + core::ops::BitAnd<Output=Self::Ux> + core::ops::Not<Output=Self::Ux>;
77
}
88

99
/// Trait implemented by readable registers to enable the `read` method.
@@ -22,6 +22,12 @@ pub trait Readable: RegisterSpec {
2222
pub trait Writable: RegisterSpec {
2323
/// Writer type argument to `write`, et al.
2424
type Writer: From<W<Self>> + core::ops::DerefMut<Target = W<Self>>;
25+
26+
/// Specifies the register bits that are not changed if you pass `1` and are changed if you pass `0`
27+
const ZERO_TO_MODIFY_FIELDS_BITMAP: Self::Ux;
28+
29+
/// Specifies the register bits that are not changed if you pass `0` and are changed if you pass `1`
30+
const ONE_TO_MODIFY_FIELDS_BITMAP: Self::Ux;
2531
}
2632

2733
/// Reset value of the register.
@@ -30,7 +36,13 @@ pub trait Writable: RegisterSpec {
3036
/// register by using the `reset` method.
3137
pub trait Resettable: RegisterSpec {
3238
/// Reset value of the register.
33-
fn reset_value() -> Self::Ux;
39+
const RESET_VALUE: Self::Ux;
40+
41+
/// Reset value of the register.
42+
#[inline(always)]
43+
fn reset_value() -> Self::Ux {
44+
Self::RESET_VALUE
45+
}
3446
}
3547

3648
/// This structure provides volatile access to registers.
@@ -82,7 +94,7 @@ impl<REG: Resettable + Writable> Reg<REG> {
8294
/// Resets the register to its initial state.
8395
#[inline(always)]
8496
pub fn reset(&self) {
85-
self.register.set(REG::reset_value())
97+
self.register.set(REG::RESET_VALUE)
8698
}
8799

88100
/// Writes bits to a `Writable` register.
@@ -115,24 +127,21 @@ impl<REG: Resettable + Writable> Reg<REG> {
115127
{
116128
self.register.set(
117129
f(&mut REG::Writer::from(W {
118-
bits: REG::reset_value(),
130+
bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
119131
_reg: marker::PhantomData,
120132
}))
121133
.bits,
122134
);
123135
}
124136
}
125137

126-
impl<REG: Writable> Reg<REG>
127-
where
128-
REG::Ux: Default,
129-
{
138+
impl<REG: Writable> Reg<REG> {
130139
/// Writes 0 to a `Writable` register.
131140
///
132141
/// Similar to `write`, but unused bits will contain 0.
133-
///
142+
///
134143
/// # Safety
135-
///
144+
///
136145
/// Unsafe to use with registers which don't allow to write 0.
137146
#[inline(always)]
138147
pub unsafe fn write_with_zero<F>(&self, f: F)
@@ -188,7 +197,7 @@ impl<REG: Readable + Writable> Reg<REG> {
188197
_reg: marker::PhantomData,
189198
}),
190199
&mut REG::Writer::from(W {
191-
bits,
200+
bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
192201
_reg: marker::PhantomData,
193202
}),
194203
)
@@ -236,9 +245,9 @@ pub struct W<REG: RegisterSpec + ?Sized> {
236245

237246
impl<REG: RegisterSpec> W<REG> {
238247
/// Writes raw bits to the register.
239-
///
248+
///
240249
/// # Safety
241-
///
250+
///
242251
/// Read datasheet or reference manual to find what values are allowed to pass.
243252
#[inline(always)]
244253
pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {

src/generate/register.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ pub fn render_register_mod(
219219
methods.push("modify");
220220
}
221221

222+
let mut zero_to_modify_fields_bitmap: u64 = 0;
223+
let mut one_to_modify_fields_bitmap: u64 = 0;
224+
222225
if let Some(cur_fields) = register.fields.as_ref() {
223226
// filter out all reserved fields, as we should not generate code for
224227
// them
@@ -240,6 +243,8 @@ pub fn render_register_mod(
240243
&mut mod_items,
241244
&mut r_impl_items,
242245
&mut w_impl_items,
246+
&mut zero_to_modify_fields_bitmap,
247+
&mut one_to_modify_fields_bitmap,
243248
config,
244249
)?;
245250
}
@@ -343,21 +348,25 @@ pub fn render_register_mod(
343348
if can_write {
344349
let doc =
345350
format!("`write(|w| ..)` method takes [{name_snake_case}::W](W) writer structure",);
351+
352+
let zero_to_modify_fields_bitmap = util::hex(zero_to_modify_fields_bitmap);
353+
let one_to_modify_fields_bitmap = util::hex(one_to_modify_fields_bitmap);
354+
346355
mod_items.extend(quote! {
347356
#[doc = #doc]
348357
impl crate::Writable for #name_constant_case_spec {
349358
type Writer = W;
359+
const ZERO_TO_MODIFY_FIELDS_BITMAP: Self::Ux = #zero_to_modify_fields_bitmap;
360+
const ONE_TO_MODIFY_FIELDS_BITMAP: Self::Ux = #one_to_modify_fields_bitmap;
350361
}
351362
});
352363
}
353364
if let Some(rv) = properties.reset_value.map(util::hex) {
354-
let rv = rv.into_token_stream();
355365
let doc = format!("`reset()` method sets {} to value {rv}", register.name);
356366
mod_items.extend(quote! {
357367
#[doc = #doc]
358368
impl crate::Resettable for #name_constant_case_spec {
359-
#[inline(always)]
360-
fn reset_value() -> Self::Ux { #rv }
369+
const RESET_VALUE: Self::Ux = #rv;
361370
}
362371
});
363372
}
@@ -377,6 +386,8 @@ pub fn fields(
377386
mod_items: &mut TokenStream,
378387
r_impl_items: &mut TokenStream,
379388
w_impl_items: &mut TokenStream,
389+
zero_to_modify_fields_bitmap: &mut u64,
390+
one_to_modify_fields_bitmap: &mut u64,
380391
config: &Config,
381392
) -> Result<()> {
382393
let span = Span::call_site();
@@ -837,19 +848,16 @@ pub fn fields(
837848
// derive writer structure by type alias to generic write proxy structure.
838849
if should_derive_writer {
839850
let proxy = if width == 1 {
851+
use ModifiedWriteValues::*;
840852
let wproxy = Ident::new(
841853
match mwv {
842-
ModifiedWriteValues::Modify => "BitWriter",
843-
ModifiedWriteValues::OneToSet | ModifiedWriteValues::Set => {
844-
"BitWriter1S"
845-
}
846-
ModifiedWriteValues::ZeroToClear | ModifiedWriteValues::Clear => {
847-
"BitWriter0C"
848-
}
849-
ModifiedWriteValues::OneToClear => "BitWriter1C",
850-
ModifiedWriteValues::ZeroToSet => "BitWriter0C",
851-
ModifiedWriteValues::OneToToggle => "BitWriter1T",
852-
ModifiedWriteValues::ZeroToToggle => "BitWriter0T",
854+
Modify | Set | Clear => "BitWriter",
855+
OneToSet => "BitWriter1S",
856+
ZeroToClear => "BitWriter0C",
857+
OneToClear => "BitWriter1C",
858+
ZeroToSet => "BitWriter0C",
859+
OneToToggle => "BitWriter1T",
860+
ZeroToToggle => "BitWriter0T",
853861
},
854862
span,
855863
);
@@ -965,6 +973,17 @@ pub fn fields(
965973
}
966974
});
967975
}
976+
let bitmask = (u64::MAX >> (64 - width)) << offset;
977+
use ModifiedWriteValues::*;
978+
match mwv {
979+
Modify | Set | Clear => {}
980+
OneToSet | OneToClear | OneToToggle => {
981+
*one_to_modify_fields_bitmap |= bitmask;
982+
}
983+
ZeroToClear | ZeroToSet | ZeroToToggle => {
984+
*zero_to_modify_fields_bitmap |= bitmask;
985+
}
986+
}
968987
}
969988
}
970989

0 commit comments

Comments
 (0)