Skip to content

Commit e65289c

Browse files
committed
Associated Reader/Writer
1 parent 939f38b commit e65289c

File tree

4 files changed

+110
-91
lines changed

4 files changed

+110
-91
lines changed

src/generate/generic.rs

+56-13
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,33 @@ pub trait FieldSpec: Sized {
104104
/// Marker for fields with fixed values
105105
pub trait IsEnum: FieldSpec {}
106106

107+
#[doc(hidden)]
108+
pub trait FromBits<U> {
109+
unsafe fn from_bits(b: U) -> Self;
110+
}
111+
112+
#[doc(hidden)]
113+
pub trait ToBits<U> {
114+
fn to_bits(&self) -> U;
115+
}
116+
107117
/// Trait implemented by readable registers to enable the `read` method.
108118
///
109119
/// Registers marked with `Writable` can be also be `modify`'ed.
110-
pub trait Readable: RegisterSpec {}
120+
pub trait Readable: RegisterSpec {
121+
/// Reader struct associated with register
122+
type Reader: FromBits<Self::Ux>;
123+
}
111124

112125
/// Trait implemented by writeable registers.
113126
///
114127
/// This enables the `write`, `write_with_zero` and `reset` methods.
115128
///
116129
/// Registers marked with `Readable` can be also be `modify`'ed.
117130
pub trait Writable: RegisterSpec {
131+
/// Writer struct associated with register
132+
type Writer: FromBits<Self::Ux> + ToBits<Self::Ux>;
133+
118134
/// Is it safe to write any bits to register
119135
type Safety;
120136

@@ -140,21 +156,59 @@ pub trait Resettable: RegisterSpec {
140156
}
141157
}
142158

159+
/// Marker for register/field writers which can take any value of specified width
160+
pub struct Safe;
161+
/// You should check that value is allowed to pass to register/field writer marked with this
162+
pub struct Unsafe;
163+
/// Marker for field writers are safe to write in specified inclusive range
164+
pub struct Range<const MIN: u64, const MAX: u64>;
165+
/// Marker for field writers are safe to write in specified inclusive range
166+
pub struct RangeFrom<const MIN: u64>;
167+
/// Marker for field writers are safe to write in specified inclusive range
168+
pub struct RangeTo<const MAX: u64>;
169+
143170
#[doc(hidden)]
144171
pub mod raw {
145-
use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
172+
use super::{marker, BitM, FieldSpec, FromBits, RegisterSpec, ToBits, Unsafe, Writable};
146173

147174
pub struct R<REG: RegisterSpec> {
148175
pub(crate) bits: REG::Ux,
149176
pub(super) _reg: marker::PhantomData<REG>,
150177
}
151178

179+
impl<REG: RegisterSpec> FromBits<REG::Ux> for R<REG> {
180+
#[inline(always)]
181+
unsafe fn from_bits(bits: REG::Ux) -> Self {
182+
Self {
183+
bits,
184+
_reg: marker::PhantomData,
185+
}
186+
}
187+
}
188+
152189
pub struct W<REG: RegisterSpec> {
153190
///Writable bits
154191
pub(crate) bits: REG::Ux,
155192
pub(super) _reg: marker::PhantomData<REG>,
156193
}
157194

195+
impl<REG: RegisterSpec> FromBits<REG::Ux> for W<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+
205+
impl<REG: RegisterSpec> ToBits<REG::Ux> for W<REG> {
206+
#[inline(always)]
207+
fn to_bits(&self) -> REG::Ux {
208+
self.bits
209+
}
210+
}
211+
158212
pub struct FieldReader<FI = u8>
159213
where
160214
FI: FieldSpec,
@@ -371,17 +425,6 @@ impl<FI> core::fmt::Debug for BitReader<FI> {
371425
}
372426
}
373427

374-
/// Marker for register/field writers which can take any value of specified width
375-
pub struct Safe;
376-
/// You should check that value is allowed to pass to register/field writer marked with this
377-
pub struct Unsafe;
378-
/// Marker for field writers are safe to write in specified inclusive range
379-
pub struct Range<const MIN: u64, const MAX: u64>;
380-
/// Marker for field writers are safe to write in specified inclusive range
381-
pub struct RangeFrom<const MIN: u64>;
382-
/// Marker for field writers are safe to write in specified inclusive range
383-
pub struct RangeTo<const MAX: u64>;
384-
385428
/// Write field Proxy
386429
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
387430
raw::FieldWriter<'a, REG, WI, FI, Safety>;

src/generate/generic_atomic.rs

+6-18
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

+44-59
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

+4-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,9 @@ pub fn render_register_mod(
386386
let doc = format!("`read()` method returns [`{mod_ty}::R`](R) reader structure",);
387387
mod_items.extend(quote! {
388388
#[doc = #doc]
389-
impl crate::Readable for #regspec_ty {}
389+
impl crate::Readable for #regspec_ty {
390+
type Reader = R;
391+
}
390392
});
391393
}
392394
if can_write {
@@ -421,6 +423,7 @@ pub fn render_register_mod(
421423
mod_items.extend(quote! {
422424
#[doc = #doc]
423425
impl crate::Writable for #regspec_ty {
426+
type Writer = W;
424427
type Safety = crate::#safe_ty;
425428
#zero_to_modify_fields_bitmap
426429
#one_to_modify_fields_bitmap

0 commit comments

Comments
 (0)