Skip to content

Commit f84b507

Browse files
committed
Try #347:
2 parents c166d12 + e7b3539 commit f84b507

File tree

3 files changed

+218
-116
lines changed

3 files changed

+218
-116
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

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

13+
///This trait shows that register has `read` method
14+
///
15+
///Registers marked with `Writable` can be also `modify`'ed
16+
pub trait Readable {}
17+
18+
///This trait shows that register has `write`, `write_with_zero` and `reset` method
19+
///
20+
///Registers marked with `Readable` can be also `modify`'ed
21+
pub trait Writable {}
22+
23+
///Reset value of the register
24+
///
25+
///This value is initial value for `write` method.
26+
///It can be also directly writed to register by `reset` method.
27+
pub trait ResetValue {
28+
///Register size
29+
type Type;
30+
///Reset value of the register
31+
fn reset_value() -> Self::Type;
32+
}
33+
1334
///Converting enumerated values to bits
1435
pub trait ToBits<N> {
1536
///Conversion method
@@ -18,23 +39,105 @@ pub fn render() -> Result<Vec<Tokens>> {
1839
});
1940

2041
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>,
42+
///This structure provides volatile access to register
43+
pub struct Reg<U, REG> {
44+
register: vcell::VolatileCell<U>,
45+
_marker: marker::PhantomData<REG>,
2546
}
2647

27-
impl<U, T, FI> PartialEq<FI> for FR<U, T>
48+
unsafe impl<U: Send, REG> Send for Reg<U, REG> { }
49+
50+
impl<U, REG> Reg<U, REG>
2851
where
29-
U: PartialEq,
30-
FI: ToBits<U>
52+
Self: Readable,
53+
U: Copy
3154
{
32-
fn eq(&self, other: &FI) -> bool {
33-
self.bits.eq(&other._bits())
55+
///Reads the contents of `Readable` register
56+
///
57+
///See [reading](https://rust-embedded.github.io/book/start/registers.html#reading) in book.
58+
#[inline(always)]
59+
pub fn read(&self) -> R<U, Self> {
60+
R {bits: self.register.get(), _reg: marker::PhantomData}
61+
}
62+
}
63+
64+
impl<U, REG> Reg<U, REG>
65+
where
66+
Self: ResetValue<Type=U> + Writable,
67+
U: Copy,
68+
{
69+
///Writes the reset value to `Writable` register
70+
#[inline(always)]
71+
pub fn reset(&self) {
72+
self.register.set(Self::reset_value())
73+
}
74+
}
75+
});
76+
77+
generic_items.push(quote! {
78+
impl<U, REG> Reg<U, REG>
79+
where
80+
Self: ResetValue<Type=U> + Writable,
81+
U: Copy
82+
{
83+
///Writes bits to `Writable` register
84+
///
85+
///See [writing](https://rust-embedded.github.io/book/start/registers.html#writing) in book.
86+
#[inline(always)]
87+
pub fn write<F>(&self, f: F)
88+
where
89+
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
90+
{
91+
self.register.set(f(&mut W {bits: Self::reset_value(), _reg: marker::PhantomData}).bits);
92+
}
93+
}
94+
});
95+
96+
generic_items.push(quote! {
97+
impl<U, REG> Reg<U, REG>
98+
where
99+
Self: Writable,
100+
U: Copy + Default
101+
{
102+
///Writes Zero to `Writable` register
103+
#[inline(always)]
104+
pub fn write_with_zero<F>(&self, f: F)
105+
where
106+
F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
107+
{
108+
self.register.set(f(&mut W {bits: U::default(), _reg: marker::PhantomData }).bits);
34109
}
35110
}
111+
});
112+
113+
generic_items.push(quote! {
114+
impl<U, REG> Reg<U, REG>
115+
where
116+
Self: Readable + Writable,
117+
U: Copy,
118+
{
119+
///Modifies the contents of the register
120+
///
121+
///See [modifying](https://rust-embedded.github.io/book/start/registers.html#modifying) in book.
122+
#[inline(always)]
123+
pub fn modify<F>(&self, f: F)
124+
where
125+
for<'w> F: FnOnce(&R<U, Self>, &'w mut W<U, Self>) -> &'w mut W<U, Self>
126+
{
127+
let bits = self.register.get();
128+
self.register.set(f(&R {bits, _reg: marker::PhantomData}, &mut W {bits, _reg: marker::PhantomData}).bits);
129+
}
130+
}
131+
});
36132

37-
impl<U, T> FR<U, T>
133+
generic_items.push(quote! {
134+
///Register/field reader
135+
pub struct R<U, T> {
136+
pub(crate) bits: U,
137+
_reg: marker::PhantomData<T>,
138+
}
139+
140+
impl<U, T> R<U, T>
38141
where
39142
U: Copy
40143
{
@@ -46,7 +149,7 @@ pub fn render() -> Result<Vec<Tokens>> {
46149
_reg: marker::PhantomData,
47150
}
48151
}
49-
///Read raw bits from field
152+
///Read raw bits from register/field
50153
#[inline(always)]
51154
pub fn bits(&self) -> U {
52155
self.bits
@@ -55,7 +158,19 @@ pub fn render() -> Result<Vec<Tokens>> {
55158
});
56159

57160
generic_items.push(quote! {
58-
impl<FI> FR<bool, FI> {
161+
impl<U, T, FI> PartialEq<FI> for R<U, T>
162+
where
163+
U: PartialEq,
164+
FI: ToBits<U>
165+
{
166+
fn eq(&self, other: &FI) -> bool {
167+
self.bits.eq(&other._bits())
168+
}
169+
}
170+
});
171+
172+
generic_items.push(quote! {
173+
impl<FI> R<bool, FI> {
59174
///Value of the field as raw bits
60175
#[inline(always)]
61176
pub fn bit(&self) -> bool {
@@ -74,6 +189,27 @@ pub fn render() -> Result<Vec<Tokens>> {
74189
}
75190
});
76191

192+
generic_items.push(quote! {
193+
///Register writer
194+
pub struct W<U, REG> {
195+
///Writable bits
196+
pub bits: U,
197+
_reg: marker::PhantomData<REG>,
198+
}
199+
});
200+
201+
generic_items.push(quote! {
202+
impl<U, REG> W<U, REG> {
203+
///Writes raw bits to the register
204+
#[inline(always)]
205+
pub fn bits(&mut self, bits: U) -> &mut Self {
206+
self.bits = bits;
207+
self
208+
}
209+
}
210+
});
211+
212+
77213
generic_items.push(quote! {
78214
///Used if enumerated values cover not the whole range
79215
#[derive(Clone,Copy,PartialEq)]
@@ -88,7 +224,7 @@ pub fn render() -> Result<Vec<Tokens>> {
88224
code.push(quote! {
89225
#[allow(unused_imports)]
90226
use generic::*;
91-
/// Common register and bit access and modify traits
227+
///Common register and bit access and modify traits
92228
pub mod generic {
93229
#(#generic_items)*
94230
}

0 commit comments

Comments
 (0)