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