@@ -87,6 +87,51 @@ impl<REG: Resettable + Writable> Reg<REG> {
87
87
. bits ,
88
88
) ;
89
89
}
90
+
91
+ /// Writes bits to a `Writable` register and produce a value.
92
+ ///
93
+ /// You can write raw bits into a register:
94
+ /// ```ignore
95
+ /// periph.reg.write_and(|w| unsafe { w.bits(rawbits); });
96
+ /// ```
97
+ /// or write only the fields you need:
98
+ /// ```ignore
99
+ /// periph.reg.write_and(|w| {
100
+ /// w.field1().bits(newfield1bits)
101
+ /// .field2().set_bit()
102
+ /// .field3().variant(VARIANT);
103
+ /// });
104
+ /// ```
105
+ /// or an alternative way of saying the same:
106
+ /// ```ignore
107
+ /// periph.reg.write_and(|w| {
108
+ /// w.field1().bits(newfield1bits);
109
+ /// w.field2().set_bit();
110
+ /// w.field3().variant(VARIANT);
111
+ /// });
112
+ /// ```
113
+ /// In the latter case, other fields will be set to their reset value.
114
+ ///
115
+ /// Values can be returned from the closure:
116
+ /// ```ignore
117
+ /// let state = periph.reg.write_and(|w| State::set(w.field1()));
118
+ /// ```
119
+ #[ inline( always) ]
120
+ pub fn from_write < F , T > ( & self , f : F ) -> T
121
+ where
122
+ F : FnOnce ( & mut W < REG > ) -> T ,
123
+ {
124
+ let mut writer = W {
125
+ bits : REG :: RESET_VALUE & !REG :: ONE_TO_MODIFY_FIELDS_BITMAP
126
+ | REG :: ZERO_TO_MODIFY_FIELDS_BITMAP ,
127
+ _reg : marker:: PhantomData ,
128
+ } ;
129
+ let result = f ( & mut writer) ;
130
+
131
+ self . register . set ( writer. bits ) ;
132
+
133
+ result
134
+ }
90
135
}
91
136
92
137
impl < REG : Writable > Reg < REG > {
@@ -110,6 +155,30 @@ impl<REG: Writable> Reg<REG> {
110
155
. bits ,
111
156
) ;
112
157
}
158
+
159
+ /// Writes 0 to a `Writable` register and produces a value.
160
+ ///
161
+ /// Similar to `write`, but unused bits will contain 0.
162
+ ///
163
+ /// # Safety
164
+ ///
165
+ /// Unsafe to use with registers which don't allow to write 0.
166
+ #[ inline( always) ]
167
+ pub unsafe fn from_write_with_zero < F , T > ( & self , f : F ) -> T
168
+ where
169
+ F : FnOnce ( & mut W < REG > ) -> T ,
170
+ {
171
+ let mut writer = W {
172
+ bits : REG :: Ux :: default ( ) ,
173
+ _reg : marker:: PhantomData ,
174
+ } ;
175
+
176
+ let result = f ( & mut writer) ;
177
+
178
+ self . register . set ( writer. bits ) ;
179
+
180
+ result
181
+ }
113
182
}
114
183
115
184
impl < REG : Readable + Writable > Reg < REG > {
@@ -159,11 +228,67 @@ impl<REG: Readable + Writable> Reg<REG> {
159
228
. bits ,
160
229
) ;
161
230
}
231
+
232
+ /// Modifies the contents of the register by reading and then writing it
233
+ /// and produces a value.
234
+ ///
235
+ /// E.g. to do a read-modify-write sequence to change parts of a register:
236
+ /// ```ignore
237
+ /// let bits = periph.reg.modify(|r, w| {
238
+ /// let new_bits = r.bits() | 3;
239
+ /// unsafe {
240
+ /// w.bits(new_bits);
241
+ /// }
242
+ ///
243
+ /// new_bits
244
+ /// });
245
+ /// ```
246
+ /// or
247
+ /// ```ignore
248
+ /// periph.reg.modify(|_, w| {
249
+ /// w.field1().bits(newfield1bits)
250
+ /// .field2().set_bit()
251
+ /// .field3().variant(VARIANT);
252
+ /// });
253
+ /// ```
254
+ /// or an alternative way of saying the same:
255
+ /// ```ignore
256
+ /// periph.reg.modify(|_, w| {
257
+ /// w.field1().bits(newfield1bits);
258
+ /// w.field2().set_bit();
259
+ /// w.field3().variant(VARIANT);
260
+ /// });
261
+ /// ```
262
+ /// Other fields will have the value they had before the call to `modify`.
263
+ #[ inline( always) ]
264
+ pub fn from_modify < F , T > ( & self , f : F ) -> T
265
+ where
266
+ for < ' w > F : FnOnce ( & R < REG > , & ' w mut W < REG > ) -> T ,
267
+ {
268
+ let bits = self . register . get ( ) ;
269
+
270
+ let mut writer = W {
271
+ bits : bits & !REG :: ONE_TO_MODIFY_FIELDS_BITMAP | REG :: ZERO_TO_MODIFY_FIELDS_BITMAP ,
272
+ _reg : marker:: PhantomData ,
273
+ } ;
274
+
275
+ let result = f (
276
+ & R {
277
+ bits,
278
+ _reg : marker:: PhantomData ,
279
+ } ,
280
+ & mut writer,
281
+ ) ;
282
+
283
+ self . register . set ( writer. bits ) ;
284
+
285
+ result
286
+ }
162
287
}
163
288
164
289
impl < REG : Readable > core:: fmt:: Debug for crate :: generic:: Reg < REG >
165
290
where
166
- R < REG > : core:: fmt:: Debug
291
+ R < REG > : core:: fmt:: Debug ,
167
292
{
168
293
fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
169
294
core:: fmt:: Debug :: fmt ( & self . read ( ) , f)
0 commit comments