Skip to content

Commit 76762a2

Browse files
committed
Associated Reader/Writer
1 parent 1760b5e commit 76762a2

4 files changed

Lines changed: 110 additions & 91 deletions

File tree

src/generate/generic.rs

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,33 @@ pub trait FieldSpec: Sized {
120120
/// Marker for fields with fixed values
121121
pub trait IsEnum: FieldSpec {}
122122

123+
#[doc(hidden)]
124+
pub trait FromBits<U> {
125+
unsafe fn from_bits(b: U) -> Self;
126+
}
127+
128+
#[doc(hidden)]
129+
pub trait ToBits<U> {
130+
fn to_bits(&self) -> U;
131+
}
132+
123133
/// Trait implemented by readable registers to enable the `read` method.
124134
///
125135
/// Registers marked with `Writable` can be also be `modify`'ed.
126-
pub trait Readable: RegisterSpec {}
136+
pub trait Readable: RegisterSpec {
137+
/// Reader struct associated with register
138+
type Reader: FromBits<Self::Ux>;
139+
}
127140

128141
/// Trait implemented by writeable registers.
129142
///
130143
/// This enables the `write`, `write_with_zero` and `reset` methods.
131144
///
132145
/// Registers marked with `Readable` can be also be `modify`'ed.
133146
pub trait Writable: RegisterSpec {
147+
/// Writer struct associated with register
148+
type Writer: FromBits<Self::Ux> + ToBits<Self::Ux>;
149+
134150
/// Is it safe to write any bits to register
135151
type Safety;
136152

@@ -156,21 +172,59 @@ pub trait Resettable: RegisterSpec {
156172
}
157173
}
158174

175+
/// Marker for register/field writers which can take any value of specified width
176+
pub struct Safe;
177+
/// You should check that value is allowed to pass to register/field writer marked with this
178+
pub struct Unsafe;
179+
/// Marker for field writers are safe to write in specified inclusive range
180+
pub struct Range<const MIN: u64, const MAX: u64>;
181+
/// Marker for field writers are safe to write in specified inclusive range
182+
pub struct RangeFrom<const MIN: u64>;
183+
/// Marker for field writers are safe to write in specified inclusive range
184+
pub struct RangeTo<const MAX: u64>;
185+
159186
#[doc(hidden)]
160187
pub mod raw {
161-
use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
188+
use super::{marker, BitM, FieldSpec, FromBits, RegisterSpec, ToBits, Unsafe, Writable};
162189

163190
pub struct R<REG: RegisterSpec> {
164191
pub(crate) bits: REG::Ux,
165192
pub(super) _reg: marker::PhantomData<REG>,
166193
}
167194

195+
impl<REG: RegisterSpec> FromBits<REG::Ux> for R<REG> {
196+
#[inline(always)]
197+
unsafe fn from_bits(bits: REG::Ux) -> Self {
198+
Self {
199+
bits,
200+
_reg: marker::PhantomData,
201+
}
202+
}
203+
}
204+
168205
pub struct W<REG: RegisterSpec> {
169206
///Writable bits
170207
pub(crate) bits: REG::Ux,
171208
pub(super) _reg: marker::PhantomData<REG>,
172209
}
173210

211+
impl<REG: RegisterSpec> FromBits<REG::Ux> for W<REG> {
212+
#[inline(always)]
213+
unsafe fn from_bits(bits: REG::Ux) -> Self {
214+
Self {
215+
bits,
216+
_reg: marker::PhantomData,
217+
}
218+
}
219+
}
220+
221+
impl<REG: RegisterSpec> ToBits<REG::Ux> for W<REG> {
222+
#[inline(always)]
223+
fn to_bits(&self) -> REG::Ux {
224+
self.bits
225+
}
226+
}
227+
174228
pub struct FieldReader<FI = u8>
175229
where
176230
FI: FieldSpec,
@@ -387,17 +441,6 @@ impl<FI> core::fmt::Debug for BitReader<FI> {
387441
}
388442
}
389443

390-
/// Marker for register/field writers which can take any value of specified width
391-
pub struct Safe;
392-
/// You should check that value is allowed to pass to register/field writer marked with this
393-
pub struct Unsafe;
394-
/// Marker for field writers are safe to write in specified inclusive range
395-
pub struct Range<const MIN: u64, const MAX: u64>;
396-
/// Marker for field writers are safe to write in specified inclusive range
397-
pub struct RangeFrom<const MIN: u64>;
398-
/// Marker for field writers are safe to write in specified inclusive range
399-
pub struct RangeTo<const MAX: u64>;
400-
401444
/// Write field Proxy
402445
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
403446
raw::FieldWriter<'a, REG, WI, FI, Safety>;

src/generate/generic_atomic.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,9 @@ mod atomic {
5050
#[inline(always)]
5151
pub unsafe fn set_bits<F>(&self, f: F)
5252
where
53-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
53+
F: FnOnce(&mut REG::Writer) -> &mut REG::Writer,
5454
{
55-
let bits = f(&mut W {
56-
bits: REG::Ux::ZERO,
57-
_reg: marker::PhantomData,
58-
})
59-
.bits;
55+
let bits = f(&mut REG::Writer::from_bits(REG::Ux::ZERO)).to_bits();
6056
REG::Ux::atomic_or(self.register.as_ptr(), bits);
6157
}
6258

@@ -69,13 +65,9 @@ mod atomic {
6965
#[inline(always)]
7066
pub unsafe fn clear_bits<F>(&self, f: F)
7167
where
72-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
68+
F: FnOnce(&mut REG::Writer) -> &mut REG::Writer,
7369
{
74-
let bits = f(&mut W {
75-
bits: !REG::Ux::ZERO,
76-
_reg: marker::PhantomData,
77-
})
78-
.bits;
70+
let bits = f(&mut REG::Writer::from_bits(!REG::Ux::ZERO)).to_bits();
7971
REG::Ux::atomic_and(self.register.as_ptr(), bits);
8072
}
8173

@@ -88,13 +80,9 @@ mod atomic {
8880
#[inline(always)]
8981
pub unsafe fn toggle_bits<F>(&self, f: F)
9082
where
91-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
83+
F: FnOnce(&mut REG::Writer) -> &mut REG::Writer,
9284
{
93-
let bits = f(&mut W {
94-
bits: REG::Ux::ZERO,
95-
_reg: marker::PhantomData,
96-
})
97-
.bits;
85+
let bits = f(&mut REG::Writer::from_bits(REG::Ux::ZERO)).to_bits();
9886
REG::Ux::atomic_xor(self.register.as_ptr(), bits);
9987
}
10088
}

src/generate/generic_reg_vcell.rs

Lines changed: 44 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,8 @@ impl<REG: Readable> Reg<REG> {
3333
/// let flag = reader.field2().bit_is_set();
3434
/// ```
3535
#[inline(always)]
36-
pub fn read(&self) -> R<REG> {
37-
R {
38-
bits: self.register.get(),
39-
_reg: marker::PhantomData,
40-
}
36+
pub fn read(&self) -> REG::Reader {
37+
unsafe { REG::Reader::from_bits(self.register.get()) }
4138
}
4239
}
4340

@@ -76,14 +73,15 @@ impl<REG: Resettable + Writable> Reg<REG> {
7673
#[inline(always)]
7774
pub fn write<F>(&self, f: F) -> REG::Ux
7875
where
79-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
76+
F: FnOnce(&mut REG::Writer) -> &mut REG::Writer,
8077
{
81-
let value = f(&mut W {
82-
bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
83-
| REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
84-
_reg: marker::PhantomData,
85-
})
86-
.bits;
78+
let value = unsafe {
79+
f(&mut REG::Writer::from_bits(
80+
REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
81+
| REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
82+
))
83+
.to_bits()
84+
};
8785
self.register.set(value);
8886
value
8987
}
@@ -119,16 +117,17 @@ impl<REG: Resettable + Writable> Reg<REG> {
119117
#[inline(always)]
120118
pub fn from_write<F, T>(&self, f: F) -> T
121119
where
122-
F: FnOnce(&mut W<REG>) -> T,
120+
F: FnOnce(&mut REG::Writer) -> T,
123121
{
124-
let mut writer = W {
125-
bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
126-
| REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
127-
_reg: marker::PhantomData,
122+
let mut writer = unsafe {
123+
REG::Writer::from_bits(
124+
REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
125+
| REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
126+
)
128127
};
129128
let result = f(&mut writer);
130129

131-
self.register.set(writer.bits);
130+
self.register.set(writer.to_bits());
132131

133132
result
134133
}
@@ -145,13 +144,9 @@ impl<REG: Writable> Reg<REG> {
145144
#[inline(always)]
146145
pub unsafe fn write_with_zero<F>(&self, f: F) -> REG::Ux
147146
where
148-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
147+
F: FnOnce(&mut REG::Writer) -> &mut REG::Writer,
149148
{
150-
let value = f(&mut W {
151-
bits: REG::Ux::ZERO,
152-
_reg: marker::PhantomData,
153-
})
154-
.bits;
149+
let value = f(&mut REG::Writer::from_bits(REG::Ux::ZERO)).to_bits();
155150
self.register.set(value);
156151
value
157152
}
@@ -166,16 +161,13 @@ impl<REG: Writable> Reg<REG> {
166161
#[inline(always)]
167162
pub unsafe fn from_write_with_zero<F, T>(&self, f: F) -> T
168163
where
169-
F: FnOnce(&mut W<REG>) -> T,
164+
F: FnOnce(&mut REG::Writer) -> T,
170165
{
171-
let mut writer = W {
172-
bits: REG::Ux::ZERO,
173-
_reg: marker::PhantomData,
174-
};
166+
let mut writer = REG::Writer::from_bits(REG::Ux::ZERO);
175167

176168
let result = f(&mut writer);
177169

178-
self.register.set(writer.bits);
170+
self.register.set(writer.to_bits());
179171

180172
result
181173
}
@@ -210,20 +202,18 @@ impl<REG: Readable + Writable> Reg<REG> {
210202
#[inline(always)]
211203
pub fn modify<F>(&self, f: F) -> REG::Ux
212204
where
213-
for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
205+
for<'w> F: FnOnce(&REG::Reader, &'w mut REG::Writer) -> &'w mut REG::Writer,
214206
{
215207
let bits = self.register.get();
216-
let value = f(
217-
&R {
218-
bits,
219-
_reg: marker::PhantomData,
220-
},
221-
&mut W {
222-
bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
223-
_reg: marker::PhantomData,
224-
},
225-
)
226-
.bits;
208+
let value = unsafe {
209+
f(
210+
&REG::Reader::from_bits(bits),
211+
&mut REG::Writer::from_bits(
212+
bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
213+
),
214+
)
215+
.to_bits()
216+
};
227217
self.register.set(value);
228218
value
229219
}
@@ -262,32 +252,27 @@ impl<REG: Readable + Writable> Reg<REG> {
262252
#[inline(always)]
263253
pub fn from_modify<F, T>(&self, f: F) -> T
264254
where
265-
for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> T,
255+
for<'w> F: FnOnce(&REG::Reader, &'w mut REG::Writer) -> T,
266256
{
267-
let bits = self.register.get();
257+
unsafe {
258+
let bits = self.register.get();
268259

269-
let mut writer = W {
270-
bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
271-
_reg: marker::PhantomData,
272-
};
260+
let mut writer = REG::Writer::from_bits(
261+
bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
262+
);
273263

274-
let result = f(
275-
&R {
276-
bits,
277-
_reg: marker::PhantomData,
278-
},
279-
&mut writer,
280-
);
264+
let result = f(&REG::Reader::from_bits(bits), &mut writer);
281265

282-
self.register.set(writer.bits);
266+
self.register.set(writer.to_bits());
283267

284-
result
268+
result
269+
}
285270
}
286271
}
287272

288-
impl<REG: Readable> core::fmt::Debug for crate::generic::Reg<REG>
273+
impl<REG: Readable> core::fmt::Debug for Reg<REG>
289274
where
290-
R<REG>: core::fmt::Debug,
275+
REG::Reader: core::fmt::Debug,
291276
{
292277
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
293278
core::fmt::Debug::fmt(&self.read(), f)

src/generate/register.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,9 @@ pub fn render_register_mod(
388388
let doc = format!("`read()` method returns [`{mod_ty}::R`](R) reader structure",);
389389
mod_items.extend(quote! {
390390
#[doc = #doc]
391-
impl crate::Readable for #regspec_ty {}
391+
impl crate::Readable for #regspec_ty {
392+
type Reader = R;
393+
}
392394
});
393395
}
394396
if can_write {
@@ -423,6 +425,7 @@ pub fn render_register_mod(
423425
mod_items.extend(quote! {
424426
#[doc = #doc]
425427
impl crate::Writable for #regspec_ty {
428+
type Writer = W;
426429
type Safety = crate::#safe_ty;
427430
#zero_to_modify_fields_bitmap
428431
#one_to_modify_fields_bitmap

0 commit comments

Comments
 (0)