Skip to content

Commit 5cc5972

Browse files
committed
generic register rebase on master
1 parent c166d12 commit 5cc5972

File tree

3 files changed

+169
-111
lines changed

3 files changed

+169
-111
lines changed

CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- `variant()` method for field reader and `Variant` enum for fields with reserved values
1313

14-
- Field readers and writers use one enum where it is possible
14+
### Changed
15+
16+
- Field readers and writers use one enum where it is possible
17+
18+
- Replace register and its reader/writer by generic types
1519

1620
## [v0.15.2] - 2019-07-29
1721

src/generate/generic.rs

+132-13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ pub fn render() -> Result<Vec<Tokens>> {
1010
generic_items.push(quote! {
1111
use core::marker;
1212

13+
///Marker trait for readable register/field
14+
pub trait Readable {}
15+
16+
///Marker trait for writable register/field
17+
pub trait Writable {}
18+
19+
///Reset value of the register
20+
pub trait ResetValue<U> {
21+
///Reset value of the register
22+
fn reset_value() -> U;
23+
}
24+
1325
///Converting enumerated values to bits
1426
pub trait ToBits<N> {
1527
///Conversion method
@@ -18,23 +30,97 @@ pub fn render() -> Result<Vec<Tokens>> {
1830
});
1931

2032
generic_items.push(quote! {
21-
///Value read from the register
22-
pub struct FR<U, T> {
23-
pub(crate) bits: U,
24-
_reg: marker::PhantomData<T>,
33+
///Wrapper for registers
34+
pub struct Reg<U, REG> {
35+
register: vcell::VolatileCell<U>,
36+
_marker: marker::PhantomData<REG>,
2537
}
2638

27-
impl<U, T, FI> PartialEq<FI> for FR<U, T>
39+
impl<U, REG> Reg<U, REG>
2840
where
29-
U: PartialEq,
30-
FI: ToBits<U>
41+
Self: Readable,
42+
U: Copy
3143
{
32-
fn eq(&self, other: &FI) -> bool {
33-
self.bits.eq(&other._bits())
44+
///Reads the contents of the register
45+
#[inline(always)]
46+
pub fn read(&self) -> R<U, Self> {
47+
R {bits: self.register.get(), _reg: marker::PhantomData}
48+
}
49+
}
50+
51+
impl<U, REG> Reg<U, REG>
52+
where
53+
Self: ResetValue<U> + Writable,
54+
U: Copy,
55+
{
56+
///Writes the reset value to the register
57+
#[inline(always)]
58+
pub fn reset(&self) {
59+
self.register.set(Self::reset_value())
3460
}
3561
}
62+
});
3663

37-
impl<U, T> FR<U, T>
64+
generic_items.push(quote! {
65+
impl<U, REG> Reg<U, REG>
66+
where
67+
Self: ResetValue<U> + Writable,
68+
U: Copy
69+
{
70+
///Writes to the register
71+
#[inline(always)]
72+
pub fn write<F>(&self, f: F)
73+
where
74+
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
75+
{
76+
self.register.set(f(&mut W {bits: Self::reset_value(), _reg: marker::PhantomData}).bits);
77+
}
78+
}
79+
});
80+
81+
generic_items.push(quote! {
82+
impl<U, REG> Reg<U, REG>
83+
where
84+
Self: Writable,
85+
U: Copy + Default
86+
{
87+
///Writes Zero to the register
88+
#[inline(always)]
89+
pub fn write_with_zero<F>(&self, f: F)
90+
where
91+
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
92+
{
93+
self.register.set(f(&mut W {bits: U::default(), _reg: marker::PhantomData }).bits);
94+
}
95+
}
96+
});
97+
98+
generic_items.push(quote! {
99+
impl<U, REG> Reg<U, REG>
100+
where
101+
Self: Readable + Writable,
102+
U: Copy,
103+
{
104+
///Modifies the contents of the register
105+
#[inline(always)]
106+
pub fn modify<F>(&self, f: F)
107+
where
108+
for<'w> F: FnOnce(&R<U, Self>, &'w mut W<U, Self>) -> &'w mut W<U, Self>
109+
{
110+
let bits = self.register.get();
111+
self.register.set(f(&R {bits, _reg: marker::PhantomData}, &mut W {bits, _reg: marker::PhantomData}).bits);
112+
}
113+
}
114+
});
115+
116+
generic_items.push(quote! {
117+
///Register/field reader
118+
pub struct R<U, T> {
119+
pub(crate) bits: U,
120+
_reg: marker::PhantomData<T>,
121+
}
122+
123+
impl<U, T> R<U, T>
38124
where
39125
U: Copy
40126
{
@@ -46,7 +132,7 @@ pub fn render() -> Result<Vec<Tokens>> {
46132
_reg: marker::PhantomData,
47133
}
48134
}
49-
///Read raw bits from field
135+
///Read raw bits from register/field
50136
#[inline(always)]
51137
pub fn bits(&self) -> U {
52138
self.bits
@@ -55,7 +141,19 @@ pub fn render() -> Result<Vec<Tokens>> {
55141
});
56142

57143
generic_items.push(quote! {
58-
impl<FI> FR<bool, FI> {
144+
impl<U, T, FI> PartialEq<FI> for R<U, T>
145+
where
146+
U: PartialEq,
147+
FI: ToBits<U>
148+
{
149+
fn eq(&self, other: &FI) -> bool {
150+
self.bits.eq(&other._bits())
151+
}
152+
}
153+
});
154+
155+
generic_items.push(quote! {
156+
impl<FI> R<bool, FI> {
59157
///Value of the field as raw bits
60158
#[inline(always)]
61159
pub fn bit(&self) -> bool {
@@ -74,6 +172,27 @@ pub fn render() -> Result<Vec<Tokens>> {
74172
}
75173
});
76174

175+
generic_items.push(quote! {
176+
///Register writer
177+
pub struct W<U, REG> {
178+
///Writable bits
179+
pub bits: U,
180+
_reg: marker::PhantomData<REG>,
181+
}
182+
});
183+
184+
generic_items.push(quote! {
185+
impl<U, REG> W<U, REG> {
186+
///Writes raw bits to the register
187+
#[inline(always)]
188+
pub fn bits(&mut self, bits: U) -> &mut Self {
189+
self.bits = bits;
190+
self
191+
}
192+
}
193+
});
194+
195+
77196
generic_items.push(quote! {
78197
///Used if enumerated values cover not the whole range
79198
#[derive(Clone,Copy,PartialEq)]
@@ -88,7 +207,7 @@ pub fn render() -> Result<Vec<Tokens>> {
88207
code.push(quote! {
89208
#[allow(unused_imports)]
90209
use generic::*;
91-
/// Common register and bit access and modify traits
210+
///Common register and bit access and modify traits
92211
pub mod generic {
93212
#(#generic_items)*
94213
}

0 commit comments

Comments
 (0)