1 | #![allow (unused)] |
2 | use core::cell::UnsafeCell; |
3 | |
4 | /// A read-write register of type T. |
5 | /// |
6 | /// Contains one value of type T and provides volatile read/write functions to it. |
7 | /// |
8 | /// # Safety |
9 | /// This register should be used where reads and writes to this peripheral register do not |
10 | /// lead to memory unsafety. For example, it is a poor choice for a DMA target, but less |
11 | /// worrisome for a GPIO output data register. |
12 | /// |
13 | /// Access to this register must be synchronised; if multiple threads (or the main thread and an |
14 | /// interrupt service routine) are accessing it simultaneously you may encounter data races. |
15 | pub struct RWRegister<T> { |
16 | register: UnsafeCell<T>, |
17 | } |
18 | |
19 | impl<T: Copy> RWRegister<T> { |
20 | /// Reads the value of the register. |
21 | #[inline (always)] |
22 | pub fn read(&self) -> T { |
23 | unsafe { ::core::ptr::read_volatile(self.register.get()) } |
24 | } |
25 | |
26 | /// Writes a new value to the register. |
27 | #[inline (always)] |
28 | pub fn write(&self, val: T) { |
29 | unsafe { ::core::ptr::write_volatile(self.register.get(), src:val) } |
30 | } |
31 | } |
32 | |
33 | /// A read-write register of type T, where read/write access is unsafe. |
34 | /// |
35 | /// Contains one value of type T and provides volatile read/write functions to it. |
36 | /// |
37 | /// # Safety |
38 | /// This register should be used where reads and writes to this peripheral may invoke |
39 | /// undefined behaviour or memory unsafety. For example, any registers you write a memory |
40 | /// address into. |
41 | /// |
42 | /// Access to this register must be synchronised; if multiple threads (or the main thread and an |
43 | /// interrupt service routine) are accessing it simultaneously you may encounter data races. |
44 | pub struct UnsafeRWRegister<T> { |
45 | register: UnsafeCell<T>, |
46 | } |
47 | |
48 | impl<T: Copy> UnsafeRWRegister<T> { |
49 | /// Reads the value of the register. |
50 | #[inline (always)] |
51 | pub unsafe fn read(&self) -> T { |
52 | ::core::ptr::read_volatile(self.register.get()) |
53 | } |
54 | |
55 | /// Writes a new value to the register. |
56 | #[inline (always)] |
57 | pub unsafe fn write(&self, val: T) { |
58 | ::core::ptr::write_volatile(self.register.get(), src:val) |
59 | } |
60 | } |
61 | |
62 | /// A read-only register of type T. |
63 | /// |
64 | /// Contains one value of type T and provides a volatile read function to it. |
65 | /// |
66 | /// # Safety |
67 | /// This register should be used where reads and writes to this peripheral register do not |
68 | /// lead to memory unsafety. |
69 | /// |
70 | /// Access to this register must be synchronised; if multiple threads (or the main thread and an |
71 | /// interrupt service routine) are accessing it simultaneously you may encounter data races. |
72 | pub struct RORegister<T> { |
73 | register: UnsafeCell<T>, |
74 | } |
75 | |
76 | impl<T: Copy> RORegister<T> { |
77 | /// Reads the value of the register. |
78 | #[inline (always)] |
79 | pub fn read(&self) -> T { |
80 | unsafe { ::core::ptr::read_volatile(self.register.get()) } |
81 | } |
82 | } |
83 | |
84 | /// A read-only register of type T, where read access is unsafe. |
85 | /// |
86 | /// Contains one value of type T and provides a volatile read function to it. |
87 | /// |
88 | /// # Safety |
89 | /// This register should be used where reads to this peripheral may invoke |
90 | /// undefined behaviour or memory unsafety. |
91 | /// |
92 | /// Access to this register must be synchronised; if multiple threads (or the main thread and an |
93 | /// interrupt service routine) are accessing it simultaneously you may encounter data races. |
94 | pub struct UnsafeRORegister<T> { |
95 | register: UnsafeCell<T>, |
96 | } |
97 | |
98 | impl<T: Copy> UnsafeRORegister<T> { |
99 | /// Reads the value of the register. |
100 | #[inline (always)] |
101 | pub unsafe fn read(&self) -> T { |
102 | ::core::ptr::read_volatile(self.register.get()) |
103 | } |
104 | } |
105 | |
106 | /// A write-only register of type T. |
107 | /// |
108 | /// Contains one value of type T and provides a volatile write function to it. |
109 | /// |
110 | /// # Safety |
111 | /// This register should be used where writes to this peripheral register do not lead to memory |
112 | /// unsafety. |
113 | /// |
114 | /// Access to this register must be synchronised; if multiple threads (or the main thread and an |
115 | /// interrupt service routine) are accessing it simultaneously you may encounter data races. |
116 | pub struct WORegister<T> { |
117 | register: UnsafeCell<T>, |
118 | } |
119 | |
120 | impl<T: Copy> WORegister<T> { |
121 | /// Writes a new value to the register. |
122 | #[inline (always)] |
123 | pub fn write(&self, val: T) { |
124 | unsafe { ::core::ptr::write_volatile(self.register.get(), src:val) } |
125 | } |
126 | } |
127 | |
128 | /// A write-only register of type T, where write access is unsafe. |
129 | /// |
130 | /// Contains one value of type T and provides a volatile write function to it. |
131 | /// |
132 | /// # Safety |
133 | /// This register should be used where reads and writes to this peripheral may invoke |
134 | /// undefined behaviour or memory unsafety. |
135 | /// |
136 | /// Access to this register must be synchronised; if multiple threads (or the main thread and an |
137 | /// interrupt service routine) are accessing it simultaneously you may encounter data races. |
138 | pub struct UnsafeWORegister<T> { |
139 | register: UnsafeCell<T>, |
140 | } |
141 | |
142 | impl<T: Copy> UnsafeWORegister<T> { |
143 | /// Writes a new value to the register. |
144 | #[inline (always)] |
145 | pub unsafe fn write(&self, val: T) { |
146 | ::core::ptr::write_volatile(self.register.get(), src:val) |
147 | } |
148 | } |
149 | |
150 | /// Write to a RWRegister or UnsafeRWRegister. |
151 | /// |
152 | /// # Examples |
153 | /// ```rust,ignore |
154 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
155 | /// // Safely acquire the peripheral instance (will panic if already acquired) |
156 | /// let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
157 | /// |
158 | /// // Write some value to the register. |
159 | /// write_reg!(stm32ral::gpio, gpioa, ODR, 1<<3); |
160 | /// |
161 | /// // Write values to specific fields. Unspecified fields are written to 0. |
162 | /// write_reg!(stm32ral::gpio, gpioa, MODER, MODER3: Output, MODER4: Analog); |
163 | /// |
164 | /// // Unsafe access without requiring you to first `take()` the instance |
165 | /// unsafe { write_reg!(stm32ral::gpio, GPIOA, MODER, MODER3: Output, MODER4: Analog) }; |
166 | /// # } |
167 | /// ``` |
168 | /// |
169 | /// # Usage |
170 | /// Like `modify_reg!`, this macro can be used in two ways, either with a single value to write to |
171 | /// the whole register, or with multiple fields each with their own value. |
172 | /// |
173 | /// In both cases, the first arguments are: |
174 | /// * the path to the peripheral module: `stm32ral::gpio`, |
175 | /// * a reference to the instance of that peripheral: 'gpioa' (anything which dereferences to |
176 | /// `RegisterBlock`, such as `Instance`, `&Instance`, `&RegisterBlock`, or |
177 | /// `*const RegisterBlock`), |
178 | /// * the register you wish you access: `MODER` (a field on the `RegisterBlock`). |
179 | /// |
180 | /// In the single-value usage, the final argument is just the value to write: |
181 | /// ```rust,ignore |
182 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
183 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
184 | /// // Turn on PA3 (and turn everything else off). |
185 | /// write_reg!(stm32ral::gpio, gpioa, ODR, 1<<3); |
186 | /// # } |
187 | /// ``` |
188 | /// |
189 | /// Otherwise, the remaining arguments are each `Field: Value` pairs: |
190 | /// ```rust,ignore |
191 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
192 | /// // Set PA3 to Output, PA4 to Analog, and everything else to 0 (which is Input). |
193 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
194 | /// write_reg!(stm32ral::gpio, gpioa, MODER, MODER3: 0b01, MODER4: 0b11); |
195 | /// # } |
196 | /// ``` |
197 | /// For fields with annotated values, you can also specify a named value: |
198 | /// ```rust,ignore |
199 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
200 | /// // As above, but with named values. |
201 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
202 | /// write_reg!(stm32ral::gpio, gpioa, MODER, MODER3: Output, MODER4: Analog); |
203 | /// # } |
204 | /// ``` |
205 | /// |
206 | /// This macro expands to calling `(*$instance).$register.write(value)`, |
207 | /// where in the second usage, the value is computed as the bitwise OR of |
208 | /// each field value, which are masked and shifted appropriately for the given field. |
209 | /// The named values are brought into scope by `use $peripheral::$register::$field::*` for |
210 | /// each field. The same constants could just be specified manually: |
211 | /// ```rust,ignore |
212 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
213 | /// // As above, but being explicit about named values. |
214 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
215 | /// write_reg!(stm32ral::gpio, gpioa, MODER, MODER3: stm32ral::gpio::MODER::MODER3::RW::Output, |
216 | /// MODER4: stm32ral::gpio::MODER::MODER4::RW::Analog); |
217 | /// # } |
218 | /// ``` |
219 | /// |
220 | /// The fully expanded form is equivalent to: |
221 | /// ```rust,ignore |
222 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
223 | /// // As above, but expanded. |
224 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
225 | /// (*gpioa).MODER.write( |
226 | /// ((stm32ral::gpio::MODER::MODER3::RW::Output << stm32ral::gpio::MODER::MODER3::offset) |
227 | /// & stm32ral::gpio::MODER::MODER3::mask) |
228 | /// | |
229 | /// ((stm32ral::gpio::MODER::MODER4::RW::Analog << stm32ral::gpio::MODER::MODER4::offset) |
230 | /// & stm32ral::gpio::MODER::MODER4::mask) |
231 | /// ); |
232 | /// # } |
233 | /// ``` |
234 | /// |
235 | /// # Safety |
236 | /// This macro will require an unsafe function or block when used with an UnsafeRWRegister, |
237 | /// but not if used with RWRegister. |
238 | /// |
239 | /// When run in an unsafe context, peripheral instances are directly accessible without requiring |
240 | /// having called `take()` beforehand: |
241 | /// ```rust,ignore |
242 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
243 | /// unsafe { write_reg!(stm32ral::gpio, GPIOA, MODER, MODER3: Output, MODER4: Analog) }; |
244 | /// # } |
245 | /// ``` |
246 | /// This works because `GPIOA` is a `*const RegisterBlock` in the `stm32ral::gpio` module; |
247 | /// and the macro brings such constants into scope and then dereferences the provided reference. |
248 | #[macro_export ] |
249 | macro_rules! write_reg { |
250 | ( $periph:path, $instance:expr, $reg:ident, $( $field:ident : $value:expr ),+ ) => {{ |
251 | #[allow(unused_imports)] |
252 | use $periph::{*}; |
253 | #[allow(unused_imports)] |
254 | (*$instance).$reg.write( |
255 | $({ use $periph::{$reg::$field::{mask, offset, W::*, RW::*}}; ($value << offset) & mask }) | * |
256 | ); |
257 | }}; |
258 | ( $periph:path, $instance:expr, $reg:ident, $value:expr ) => {{ |
259 | #[allow(unused_imports)] |
260 | use $periph::{*}; |
261 | (*$instance).$reg.write($value); |
262 | }}; |
263 | } |
264 | |
265 | /// Modify a RWRegister or UnsafeRWRegister. |
266 | /// |
267 | /// # Examples |
268 | /// ```rust,ignore |
269 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
270 | /// // Safely acquire the peripheral instance (will panic if already acquired) |
271 | /// let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
272 | /// |
273 | /// // Update the register to ensure bit 3 is set. |
274 | /// modify_reg!(stm32ral::gpio, gpioa, ODR, |reg| reg | (1<<3)); |
275 | /// |
276 | /// // Write values to specific fields. Unspecified fields are left unchanged. |
277 | /// modify_reg!(stm32ral::gpio, gpioa, MODER, MODER3: Output, MODER4: Analog); |
278 | /// |
279 | /// // Unsafe access without requiring you to first `take()` the instance |
280 | /// unsafe { modify_reg!(stm32ral::gpio, GPIOA, MODER, MODER3: Output, MODER4: Analog) }; |
281 | /// # } |
282 | /// ``` |
283 | /// |
284 | /// # Usage |
285 | /// Like `write_reg!`, this macro can be used in two ways, either with a modification of the entire |
286 | /// register, or by specifying which fields to change and what value to change them to. |
287 | /// |
288 | /// In both cases, the first arguments are: |
289 | /// * the path to the peripheral module: `stm32ral::gpio`, |
290 | /// * a reference to the instance of that peripheral: 'gpioa' (anything which dereferences to |
291 | /// `RegisterBlock`, such as `Instance`, `&Instance`, `&RegisterBlock`, or |
292 | /// `*const RegisterBlock`), |
293 | /// * the register you wish you access: `MODER` (a field on the `RegisterBlock`). |
294 | /// |
295 | /// In the whole-register usage, the final argument is a closure that accepts the current value |
296 | /// of the register and returns the new value to write: |
297 | /// ```rust,ignore |
298 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
299 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
300 | /// // Turn on PA3 without affecting anything else. |
301 | /// modify_reg!(stm32ral::gpio, gpioa, ODR, |reg| reg | (1<<3)); |
302 | /// # } |
303 | /// ``` |
304 | /// |
305 | /// Otherwise, the remaining arguments are `Field: Value` pairs: |
306 | /// ```rust,ignore |
307 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
308 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
309 | /// // Set PA3 to Output, PA4 to Analog, and leave everything else unchanged. |
310 | /// modify_reg!(stm32ral::gpio, gpioa, MODER, MODER3: 0b01, MODER4: 0b11); |
311 | /// # } |
312 | /// ``` |
313 | /// |
314 | /// For fields with annotated values, you can also specify a named value: |
315 | /// ```rust,ignore |
316 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
317 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
318 | /// // As above, but with named values. |
319 | /// modify_reg!(stm32ral::gpio, gpioa, MODER, MODER3: Output, MODER4: Analog); |
320 | /// # } |
321 | /// ``` |
322 | /// |
323 | /// This macro expands to calling `(*instance).register.write(value)`. |
324 | /// When called with a closure, `(*instance).register.read()` is called, the result |
325 | /// passed in to the closure, and the return value of the closure is used for `value`. |
326 | /// When called with `Field: Value` arguments, the current value is read and then masked |
327 | /// according to the specified fields, and then ORd with the OR of each field value, |
328 | /// each masked and shifted appropriately for the field. The named values are brought into scope |
329 | /// by `use peripheral::register::field::*` for each field. The same constants could just be |
330 | /// specified manually: |
331 | /// ```rust,ignore |
332 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
333 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
334 | /// // As above, but being explicit about named values. |
335 | /// modify_reg!(stm32ral::gpio, gpioa, MODER, MODER3: stm32ral::gpio::MODER::MODER3::RW::Output, |
336 | /// MODER4: stm32ral::gpio::MODER::MODER4::RW::Analog); |
337 | /// # } |
338 | /// ``` |
339 | /// |
340 | /// The fully expanded form is equivalent to: |
341 | /// ```rust,ignore |
342 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
343 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
344 | /// // As above, but expanded. |
345 | /// (*gpioa).MODER.write( |
346 | /// ( |
347 | /// // First read the current value... |
348 | /// (*gpioa).MODER.read() |
349 | /// // Then AND it with an appropriate mask... |
350 | /// & |
351 | /// !( stm32ral::gpio::MODER::MODER3::mask | stm32ral::gpio::MODER::MODER4::mask ) |
352 | /// ) |
353 | /// // Then OR with each field value. |
354 | /// | |
355 | /// ((stm32ral::gpio::MODER::MODER3::RW::Output << stm32ral::gpio::MODER::MODER3::offset) |
356 | /// & stm32ral::gpio::MODER::MODER3::mask) |
357 | /// | |
358 | /// ((stm32ral::gpio::MODER::MODER4::RW::Analog << stm32ral::gpio::MODER::MODER3::offset) |
359 | /// & stm32ral::gpio::MODER::MODER3::mask) |
360 | /// ); |
361 | /// # } |
362 | /// ``` |
363 | /// |
364 | /// # Safety |
365 | /// This macro will require an unsafe function or block when used with an UnsafeRWRegister, |
366 | /// but not if used with RWRegister. |
367 | /// |
368 | /// When run in an unsafe context, peripheral instances are directly accessible without requiring |
369 | /// having called `take()` beforehand: |
370 | /// ```rust,ignore |
371 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
372 | /// unsafe { modify_reg!(stm32ral::gpio, GPIOA, MODER, MODER3: Output, MODER4: Analog) }; |
373 | /// # } |
374 | /// ``` |
375 | /// This works because `GPIOA` is a `*const RegisterBlock` in the `stm32ral::gpio` module; |
376 | /// and the macro brings such constants into scope and then dereferences the provided reference. |
377 | #[macro_export ] |
378 | macro_rules! modify_reg { |
379 | ( $periph:path, $instance:expr, $reg:ident, $( $field:ident : $value:expr ),+ ) => {{ |
380 | #[allow(unused_imports)] |
381 | use $periph::{*}; |
382 | #[allow(unused_imports)] |
383 | (*$instance).$reg.write( |
384 | ((*$instance).$reg.read() & !( $({ use $periph::{$reg::$field::mask}; mask }) | * )) |
385 | | $({ use $periph::{$reg::$field::{mask, offset, W::*, RW::*}}; ($value << offset) & mask }) | *); |
386 | }}; |
387 | ( $periph:path, $instance:expr, $reg:ident, $fn:expr ) => {{ |
388 | #[allow(unused_imports)] |
389 | use $periph::{*}; |
390 | (*$instance).$reg.write($fn((*$instance).$reg.read())); |
391 | }}; |
392 | } |
393 | |
394 | /// Read the value from a RORegister, RWRegister, UnsafeRORegister, or UnsafeRWRegister. |
395 | /// |
396 | /// # Examples |
397 | /// ```rust,ignore |
398 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
399 | /// // Safely acquire the peripheral instance (will panic if already acquired) |
400 | /// let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
401 | /// |
402 | /// // Read the whole register. |
403 | /// let val = read_reg!(stm32ral::gpio, gpioa, IDR); |
404 | /// |
405 | /// // Read one field from the register. |
406 | /// let val = read_reg!(stm32ral::gpio, gpioa, IDR, IDR2); |
407 | /// |
408 | /// // Read multiple fields from the register. |
409 | /// let (val1, val2, val3) = read_reg!(stm32ral::gpio, gpioa, IDR, IDR0, IDR1, IDR2); |
410 | /// |
411 | /// // Check if one field is equal to a specific value, with the field's named values in scope. |
412 | /// while read_reg!(stm32ral::gpio, gpioa, IDR, IDR2 == High) {} |
413 | /// |
414 | /// // Unsafe access without requiring you to first `take()` the instance |
415 | /// let val = unsafe { read_reg!(stm32ral::gpio, GPIOA, IDR) }; |
416 | /// # } |
417 | /// ``` |
418 | /// |
419 | /// # Usage |
420 | /// Like `write_reg!`, this macro can be used multiple ways, either reading the entire register or |
421 | /// reading a one or more fields from it and potentially performing a comparison with one field. |
422 | /// |
423 | /// In all cases, the first arguments are: |
424 | /// * the path to the peripheral module: `stm32ral::gpio`, |
425 | /// * a reference to the instance of that peripheral: 'gpioa' (anything which dereferences to |
426 | /// `RegisterBlock`, such as `Instance`, `&Instance`, `&RegisterBlock`, or |
427 | /// `*const RegisterBlock`), |
428 | /// * the register you wish to access: `IDR` (a field on the `RegisterBlock`). |
429 | /// |
430 | /// In the whole-register usage, the macro simply returns the register's value: |
431 | /// ```rust,ignore |
432 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
433 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
434 | /// // Read the entire value of GPIOA.IDR into `val`. |
435 | /// let val = read_reg!(stm32ral::gpio, gpioa, IDR); |
436 | /// # } |
437 | /// ``` |
438 | /// |
439 | /// For reading individual fields, the macro masks and shifts appropriately: |
440 | /// ```rust,ignore |
441 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
442 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
443 | /// // Read just the value of the field GPIOA.IDR2 into `val`. |
444 | /// let val = read_reg!(stm32ral::gpio, gpioa, IDR, IDR2); |
445 | /// |
446 | /// // As above, but expanded for exposition: |
447 | /// let val = ((*gpioa).IDR.read() & stm32ral::gpio::IDR::IDR2::mask) |
448 | /// >> stm32ral::gpio::IDR::IDR2::offset; |
449 | /// |
450 | /// // Read multiple fields |
451 | /// let (val1, val2) = read_reg!(stm32ral::gpio, gpioa, IDR, IDR2, IDR3); |
452 | /// |
453 | /// // As above, but expanded for exposition: |
454 | /// let (val1, val2) = { let val = (*gpioa).IDR.read(); |
455 | /// ((val & stm32ral::gpio::IDR::IDR2::mask) >> stm32ral::gpio::IDR::IDR2::offset, |
456 | /// (val & stm32ral::gpio::IDR::IDR3::mask) >> stm32ral::gpio::IDR::IDR3::offset, |
457 | /// )}; |
458 | /// # } |
459 | /// ``` |
460 | /// |
461 | /// For comparing a single field, the macro masks and shifts and then performs the comparison: |
462 | /// ```rust,ignore |
463 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
464 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
465 | /// # let rcc = stm32ral::rcc::RCC::take().unwrap(); |
466 | /// // Loop while PA2 is High. |
467 | /// while read_reg!(stm32ral::gpio, gpioa, IDR, IDR2 == High) {} |
468 | /// |
469 | /// // Only proceed if the clock is not the HSI. |
470 | /// if read_reg!(stm32ral::rcc, rcc, CFGR, SWS != HSI) { } |
471 | /// |
472 | /// // Equivalent expansion: |
473 | /// if (((*rcc).CFGR.read() & stm32ral::rcc::CFGR::SWS::mask) |
474 | /// >> stm32ral::rcc::CFGR::SWS::offset) != stm32ral::rcc::CFGR::SWS::R::HSI { } |
475 | /// # } |
476 | /// ``` |
477 | /// |
478 | /// # Safety |
479 | /// This macro will require an unsafe function or block when used with an UnsafeRWRegister or |
480 | /// UnsafeRORegister, but not if used with RWRegister, or RORegister. |
481 | /// |
482 | /// When run in an unsafe context, peripheral instances are directly accessible without requiring |
483 | /// having called `take()` beforehand: |
484 | /// ```rust,ignore |
485 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
486 | /// let val = unsafe { read_reg!(stm32ral::gpio, GPIOA, MODER) }; |
487 | /// # } |
488 | /// ``` |
489 | /// This works because `GPIOA` is a `*const RegisterBlock` in the `stm32ral::gpio` module; |
490 | /// and the macro brings such constants into scope and then dereferences the provided reference. |
491 | #[macro_export ] |
492 | macro_rules! read_reg { |
493 | ( $periph:path, $instance:expr, $reg:ident, $( $field:ident ),+ ) => {{ |
494 | #[allow(unused_imports)] |
495 | use $periph::{*}; |
496 | let val = ((*$instance).$reg.read()); |
497 | ( $({ |
498 | #[allow(unused_imports)] |
499 | use $periph::{$reg::$field::{mask, offset, R::*, RW::*}}; |
500 | (val & mask) >> offset |
501 | }) , *) |
502 | }}; |
503 | ( $periph:path, $instance:expr, $reg:ident, $field:ident $($cmp:tt)* ) => {{ |
504 | #[allow(unused_imports)] |
505 | use $periph::{*}; |
506 | #[allow(unused_imports)] |
507 | use $periph::{$reg::$field::{mask, offset, R::*, RW::*}}; |
508 | (((*$instance).$reg.read() & mask) >> offset) $($cmp)* |
509 | }}; |
510 | ( $periph:path, $instance:expr, $reg:ident ) => {{ |
511 | #[allow(unused_imports)] |
512 | use $periph::{*}; |
513 | ((*$instance).$reg.read()) |
514 | }}; |
515 | } |
516 | |
517 | /// Reset a RWRegister, UnsafeRWRegister, WORegister, or UnsafeWORegister to its reset value. |
518 | /// |
519 | /// # Examples |
520 | /// ```rust,ignore |
521 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
522 | /// // Safely acquire the peripheral instance (will panic if already acquired) |
523 | /// let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
524 | /// |
525 | /// // Reset PA14 and PA15 to their reset state |
526 | /// reset_reg!(stm32ral::gpio, gpioa, GPIOA, MODER, MODER14, MODER15); |
527 | /// |
528 | /// // Reset the entire GPIOA.MODER to its reset state |
529 | /// reset_reg!(stm32ral::gpio, gpioa, GPIOA, MODER); |
530 | /// # } |
531 | /// ``` |
532 | /// |
533 | /// # Usage |
534 | /// Like `write_reg!`, this macro can be used in two ways, either resetting the entire register |
535 | /// or just resetting specific fields within in. The register or fields are written with their |
536 | /// reset values. |
537 | /// |
538 | /// In both cases, the first arguments are: |
539 | /// * the path to the peripheral module: `stm32ral::gpio`, |
540 | /// * a reference to the instance of that peripheral: 'gpioa' (anything which dereferences to |
541 | /// `RegisterBlock`, such as `Instance`, `&Instance`, `&RegisterBlock`, or |
542 | /// `*const RegisterBlock`), |
543 | /// * the module for the instance of that peripheral: `GPIOA`, |
544 | /// * the register you wish to access: `MODER` (a field on the `RegisterBlock`). |
545 | /// |
546 | /// In the whole-register usage, that's it: |
547 | /// ```rust,ignore |
548 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
549 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
550 | /// // Reset the entire GPIOA.MODER |
551 | /// reset_reg!(stm32ral::gpio, gpioa, GPIOA, MODER); |
552 | /// # } |
553 | /// ``` |
554 | /// |
555 | /// Otherwise, the remaining arguments are each field names: |
556 | /// ```rust,ignore |
557 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
558 | /// # let gpioa = stm32ral::gpio::GPIOA::take().unwrap(); |
559 | /// // Reset the JTAG pins |
560 | /// reset_reg!(stm32ral::gpio, gpioa, GPIOA, MODER, MODER13, MODER14, MODER15); |
561 | /// reset_reg!(stm32ral::gpio, gpioa, GPIOB, MODER, MODER3, MODER4); |
562 | /// # } |
563 | /// ``` |
564 | /// |
565 | /// The second form is only available to RWRegister and UnsafeRWRegister, since `.read()` is |
566 | /// not available for WORegister and UnsafeWORegister. |
567 | /// |
568 | /// This macro expands to calling `(*$instance).$register.write(value)`, where |
569 | /// `value` is either the register's reset value, or the current read value of the register |
570 | /// masked appropriately and combined with the reset value for each field. |
571 | /// |
572 | /// # Safety |
573 | /// This macro will require an unsafe function or block when used with an UnsafeRWRegister or |
574 | /// UnsafeRORegister, but not if used with RWRegister or RORegister. |
575 | /// |
576 | /// When run in an unsafe context, peripheral instances are directly accessible without requiring |
577 | /// having called `take()` beforehand: |
578 | /// ```rust,ignore |
579 | /// # use stm32ral::{read_reg, write_reg, modify_reg, reset_reg}; fn main() { |
580 | /// unsafe { reset_reg!(stm32ral::gpio, GPIOA, GPIOA, MODER) }; |
581 | /// # } |
582 | /// ``` |
583 | /// This works because `GPIOA` is a `*const RegisterBlock` in the `stm32ral::gpio` module; |
584 | /// and the macro brings such constants into scope and then dereferences the provided reference. |
585 | /// |
586 | /// Note that the second argument is a `*const` and the third is a path; despite both being written |
587 | /// `GPIOA` they are not the same thing. |
588 | #[macro_export ] |
589 | macro_rules! reset_reg { |
590 | ( $periph:path, $instance:expr, $instancemod:path, $reg:ident, $( $field:ident ),+ ) => {{ |
591 | #[allow(unused_imports)] |
592 | use $periph::{*}; |
593 | use $periph::{$instancemod::{reset}}; |
594 | #[allow(unused_imports)] |
595 | (*$instance).$reg.write({ |
596 | let resetmask: u32 = $({ use $periph::{$reg::$field::mask}; mask }) | *; |
597 | ((*$instance).$reg.read() & !resetmask) | (reset.$reg & resetmask) |
598 | }); |
599 | }}; |
600 | ( $periph:path, $instance:expr, $instancemod:path, $reg:ident ) => {{ |
601 | #[allow(unused_imports)] |
602 | use $periph::{*}; |
603 | use $periph::{$instancemod::{reset}}; |
604 | (*$instance).$reg.write(reset.$reg); |
605 | }}; |
606 | } |
607 | |