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