Skip to content

Commit 7b9d119

Browse files
committed
generic register rebase on master
1 parent c166d12 commit 7b9d119

File tree

3 files changed

+214
-116
lines changed

3 files changed

+214
-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

+147-13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,25 @@ 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<U> {
28+
///Reset value of the register
29+
fn reset_value() -> U;
30+
}
31+
1332
///Converting enumerated values to bits
1433
pub trait ToBits<N> {
1534
///Conversion method
@@ -18,23 +37,105 @@ pub fn render() -> Result<Vec<Tokens>> {
1837
});
1938

2039
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>,
40+
///This structure provides volatile access to register
41+
pub struct Reg<U, REG> {
42+
register: vcell::VolatileCell<U>,
43+
_marker: marker::PhantomData<REG>,
2544
}
2645

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

37-
impl<U, T> FR<U, T>
131+
generic_items.push(quote! {
132+
///Register/field reader
133+
pub struct R<U, T> {
134+
pub(crate) bits: U,
135+
_reg: marker::PhantomData<T>,
136+
}
137+
138+
impl<U, T> R<U, T>
38139
where
39140
U: Copy
40141
{
@@ -46,7 +147,7 @@ pub fn render() -> Result<Vec<Tokens>> {
46147
_reg: marker::PhantomData,
47148
}
48149
}
49-
///Read raw bits from field
150+
///Read raw bits from register/field
50151
#[inline(always)]
51152
pub fn bits(&self) -> U {
52153
self.bits
@@ -55,7 +156,19 @@ pub fn render() -> Result<Vec<Tokens>> {
55156
});
56157

57158
generic_items.push(quote! {
58-
impl<FI> FR<bool, FI> {
159+
impl<U, T, FI> PartialEq<FI> for R<U, T>
160+
where
161+
U: PartialEq,
162+
FI: ToBits<U>
163+
{
164+
fn eq(&self, other: &FI) -> bool {
165+
self.bits.eq(&other._bits())
166+
}
167+
}
168+
});
169+
170+
generic_items.push(quote! {
171+
impl<FI> R<bool, FI> {
59172
///Value of the field as raw bits
60173
#[inline(always)]
61174
pub fn bit(&self) -> bool {
@@ -74,6 +187,27 @@ pub fn render() -> Result<Vec<Tokens>> {
74187
}
75188
});
76189

190+
generic_items.push(quote! {
191+
///Register writer
192+
pub struct W<U, REG> {
193+
///Writable bits
194+
pub bits: U,
195+
_reg: marker::PhantomData<REG>,
196+
}
197+
});
198+
199+
generic_items.push(quote! {
200+
impl<U, REG> W<U, REG> {
201+
///Writes raw bits to the register
202+
#[inline(always)]
203+
pub fn bits(&mut self, bits: U) -> &mut Self {
204+
self.bits = bits;
205+
self
206+
}
207+
}
208+
});
209+
210+
77211
generic_items.push(quote! {
78212
///Used if enumerated values cover not the whole range
79213
#[derive(Clone,Copy,PartialEq)]
@@ -88,7 +222,7 @@ pub fn render() -> Result<Vec<Tokens>> {
88222
code.push(quote! {
89223
#[allow(unused_imports)]
90224
use generic::*;
91-
/// Common register and bit access and modify traits
225+
///Common register and bit access and modify traits
92226
pub mod generic {
93227
#(#generic_items)*
94228
}

0 commit comments

Comments
 (0)