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}