@@ -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