stm32l5/
generic.rs

1use core::marker;
2
3/// Generic peripheral accessor
4pub struct Periph<RB, const A: usize> {
5    _marker: marker::PhantomData<RB>,
6}
7
8unsafe impl<RB, const A: usize> Send for Periph<RB, A> {}
9
10impl<RB, const A: usize> Periph<RB, A> {
11    ///Pointer to the register block
12    pub const PTR: *const RB = A as *const _;
13
14    ///Return the pointer to the register block
15    #[inline(always)]
16    pub const fn ptr() -> *const RB {
17        Self::PTR
18    }
19
20    /// Steal an instance of this peripheral
21    ///
22    /// # Safety
23    ///
24    /// Ensure that the new instance of the peripheral cannot be used in a way
25    /// that may race with any existing instances, for example by only
26    /// accessing read-only or write-only registers, or by consuming the
27    /// original peripheral and using critical sections to coordinate
28    /// access between multiple new instances.
29    ///
30    /// Additionally, other software such as HALs may rely on only one
31    /// peripheral instance existing to ensure memory safety; ensure
32    /// no stolen instances are passed to such software.
33    pub unsafe fn steal() -> Self {
34        Self {
35            _marker: marker::PhantomData,
36        }
37    }
38}
39
40impl<RB, const A: usize> core::ops::Deref for Periph<RB, A> {
41    type Target = RB;
42
43    #[inline(always)]
44    fn deref(&self) -> &Self::Target {
45        unsafe { &*Self::PTR }
46    }
47}
48
49/// Raw register type (`u8`, `u16`, `u32`, ...)
50pub trait RawReg:
51    Copy
52    + From<bool>
53    + core::ops::BitOr<Output = Self>
54    + core::ops::BitAnd<Output = Self>
55    + core::ops::BitOrAssign
56    + core::ops::BitAndAssign
57    + core::ops::Not<Output = Self>
58    + core::ops::Shl<u8, Output = Self>
59{
60    /// Mask for bits of width `WI`
61    fn mask<const WI: u8>() -> Self;
62    /// `0`
63    const ZERO: Self;
64    /// `1`
65    const ONE: Self;
66}
67
68macro_rules! raw_reg {
69    ($U:ty, $size:literal, $mask:ident) => {
70        impl RawReg for $U {
71            #[inline(always)]
72            fn mask<const WI: u8>() -> Self {
73                $mask::<WI>()
74            }
75            const ZERO: Self = 0;
76            const ONE: Self = 1;
77        }
78        const fn $mask<const WI: u8>() -> $U {
79            <$U>::MAX >> ($size - WI)
80        }
81        impl FieldSpec for $U {
82            type Ux = $U;
83        }
84    };
85}
86
87raw_reg!(u8, 8, mask_u8);
88raw_reg!(u16, 16, mask_u16);
89raw_reg!(u32, 32, mask_u32);
90raw_reg!(u64, 64, mask_u64);
91
92/// Raw register type
93pub trait RegisterSpec {
94    /// Raw register type (`u8`, `u16`, `u32`, ...).
95    type Ux: RawReg;
96}
97
98/// Raw field type
99pub trait FieldSpec: Sized {
100    /// Raw field type (`u8`, `u16`, `u32`, ...).
101    type Ux: Copy + core::fmt::Debug + PartialEq + From<Self>;
102}
103
104/// Marker for fields with fixed values
105pub trait IsEnum: FieldSpec {}
106
107/// Trait implemented by readable registers to enable the `read` method.
108///
109/// Registers marked with `Writable` can be also be `modify`'ed.
110pub trait Readable: RegisterSpec {}
111
112/// Trait implemented by writeable registers.
113///
114/// This enables the  `write`, `write_with_zero` and `reset` methods.
115///
116/// Registers marked with `Readable` can be also be `modify`'ed.
117pub trait Writable: RegisterSpec {
118    /// Is it safe to write any bits to register
119    type Safety;
120
121    /// Specifies the register bits that are not changed if you pass `1` and are changed if you pass `0`
122    const ZERO_TO_MODIFY_FIELDS_BITMAP: Self::Ux = Self::Ux::ZERO;
123
124    /// Specifies the register bits that are not changed if you pass `0` and are changed if you pass `1`
125    const ONE_TO_MODIFY_FIELDS_BITMAP: Self::Ux = Self::Ux::ZERO;
126}
127
128/// Reset value of the register.
129///
130/// This value is the initial value for the `write` method. It can also be directly written to the
131/// register by using the `reset` method.
132pub trait Resettable: RegisterSpec {
133    /// Reset value of the register.
134    const RESET_VALUE: Self::Ux = Self::Ux::ZERO;
135
136    /// Reset value of the register.
137    #[inline(always)]
138    fn reset_value() -> Self::Ux {
139        Self::RESET_VALUE
140    }
141}
142
143#[doc(hidden)]
144pub mod raw {
145    use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
146
147    pub struct R<REG: RegisterSpec> {
148        pub(crate) bits: REG::Ux,
149        pub(super) _reg: marker::PhantomData<REG>,
150    }
151
152    pub struct W<REG: RegisterSpec> {
153        ///Writable bits
154        pub(crate) bits: REG::Ux,
155        pub(super) _reg: marker::PhantomData<REG>,
156    }
157
158    pub struct FieldReader<FI = u8>
159    where
160        FI: FieldSpec,
161    {
162        pub(crate) bits: FI::Ux,
163        _reg: marker::PhantomData<FI>,
164    }
165
166    impl<FI: FieldSpec> FieldReader<FI> {
167        /// Creates a new instance of the reader.
168        #[allow(unused)]
169        #[inline(always)]
170        pub(crate) const fn new(bits: FI::Ux) -> Self {
171            Self {
172                bits,
173                _reg: marker::PhantomData,
174            }
175        }
176    }
177
178    pub struct BitReader<FI = bool> {
179        pub(crate) bits: bool,
180        _reg: marker::PhantomData<FI>,
181    }
182
183    impl<FI> BitReader<FI> {
184        /// Creates a new instance of the reader.
185        #[allow(unused)]
186        #[inline(always)]
187        pub(crate) const fn new(bits: bool) -> Self {
188            Self {
189                bits,
190                _reg: marker::PhantomData,
191            }
192        }
193    }
194
195    #[must_use = "after creating `FieldWriter` you need to call field value setting method"]
196    pub struct FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe>
197    where
198        REG: Writable + RegisterSpec,
199        FI: FieldSpec,
200    {
201        pub(crate) w: &'a mut W<REG>,
202        pub(crate) o: u8,
203        _field: marker::PhantomData<(FI, Safety)>,
204    }
205
206    impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
207    where
208        REG: Writable + RegisterSpec,
209        FI: FieldSpec,
210    {
211        /// Creates a new instance of the writer
212        #[allow(unused)]
213        #[inline(always)]
214        pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
215            Self {
216                w,
217                o,
218                _field: marker::PhantomData,
219            }
220        }
221    }
222
223    #[must_use = "after creating `BitWriter` you need to call bit setting method"]
224    pub struct BitWriter<'a, REG, FI = bool, M = BitM>
225    where
226        REG: Writable + RegisterSpec,
227        bool: From<FI>,
228    {
229        pub(crate) w: &'a mut W<REG>,
230        pub(crate) o: u8,
231        _field: marker::PhantomData<(FI, M)>,
232    }
233
234    impl<'a, REG, FI, M> BitWriter<'a, REG, FI, M>
235    where
236        REG: Writable + RegisterSpec,
237        bool: From<FI>,
238    {
239        /// Creates a new instance of the writer
240        #[allow(unused)]
241        #[inline(always)]
242        pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
243            Self {
244                w,
245                o,
246                _field: marker::PhantomData,
247            }
248        }
249    }
250}
251
252/// Register reader.
253///
254/// Result of the `read` methods of registers. Also used as a closure argument in the `modify`
255/// method.
256pub type R<REG> = raw::R<REG>;
257
258impl<REG: RegisterSpec> R<REG> {
259    /// Reads raw bits from register.
260    #[inline(always)]
261    pub const fn bits(&self) -> REG::Ux {
262        self.bits
263    }
264}
265
266impl<REG: RegisterSpec, FI> PartialEq<FI> for R<REG>
267where
268    REG::Ux: PartialEq,
269    FI: Copy,
270    REG::Ux: From<FI>,
271{
272    #[inline(always)]
273    fn eq(&self, other: &FI) -> bool {
274        self.bits.eq(&REG::Ux::from(*other))
275    }
276}
277
278/// Register writer.
279///
280/// Used as an argument to the closures in the `write` and `modify` methods of the register.
281pub type W<REG> = raw::W<REG>;
282
283impl<REG: Writable> W<REG> {
284    /// Writes raw bits to the register.
285    ///
286    /// # Safety
287    ///
288    /// Passing incorrect value can cause undefined behaviour. See reference manual
289    #[inline(always)]
290    pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {
291        self.bits = bits;
292        self
293    }
294}
295impl<REG> W<REG>
296where
297    REG: Writable<Safety = Safe>,
298{
299    /// Writes raw bits to the register.
300    #[inline(always)]
301    pub fn set(&mut self, bits: REG::Ux) -> &mut Self {
302        self.bits = bits;
303        self
304    }
305}
306
307/// Field reader.
308///
309/// Result of the `read` methods of fields.
310pub type FieldReader<FI = u8> = raw::FieldReader<FI>;
311
312/// Bit-wise field reader
313pub type BitReader<FI = bool> = raw::BitReader<FI>;
314
315impl<FI: FieldSpec> FieldReader<FI> {
316    /// Reads raw bits from field.
317    #[inline(always)]
318    pub const fn bits(&self) -> FI::Ux {
319        self.bits
320    }
321}
322
323impl<FI: FieldSpec> core::fmt::Debug for FieldReader<FI> {
324    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
325        core::fmt::Debug::fmt(&self.bits, f)
326    }
327}
328
329impl<FI> PartialEq<FI> for FieldReader<FI>
330where
331    FI: FieldSpec + Copy,
332{
333    #[inline(always)]
334    fn eq(&self, other: &FI) -> bool {
335        self.bits.eq(&FI::Ux::from(*other))
336    }
337}
338
339impl<FI> PartialEq<FI> for BitReader<FI>
340where
341    FI: Copy,
342    bool: From<FI>,
343{
344    #[inline(always)]
345    fn eq(&self, other: &FI) -> bool {
346        self.bits.eq(&bool::from(*other))
347    }
348}
349
350impl<FI> BitReader<FI> {
351    /// Value of the field as raw bits.
352    #[inline(always)]
353    pub const fn bit(&self) -> bool {
354        self.bits
355    }
356    /// Returns `true` if the bit is clear (0).
357    #[inline(always)]
358    pub const fn bit_is_clear(&self) -> bool {
359        !self.bit()
360    }
361    /// Returns `true` if the bit is set (1).
362    #[inline(always)]
363    pub const fn bit_is_set(&self) -> bool {
364        self.bit()
365    }
366}
367
368impl<FI> core::fmt::Debug for BitReader<FI> {
369    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
370        core::fmt::Debug::fmt(&self.bits, f)
371    }
372}
373
374/// Marker for register/field writers which can take any value of specified width
375pub struct Safe;
376/// You should check that value is allowed to pass to register/field writer marked with this
377pub struct Unsafe;
378/// Marker for field writers are safe to write in specified inclusive range
379pub struct Range<const MIN: u64, const MAX: u64>;
380/// Marker for field writers are safe to write in specified inclusive range
381pub struct RangeFrom<const MIN: u64>;
382/// Marker for field writers are safe to write in specified inclusive range
383pub struct RangeTo<const MAX: u64>;
384
385/// Write field Proxy
386pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
387    raw::FieldWriter<'a, REG, WI, FI, Safety>;
388
389impl<REG, const WI: u8, FI, Safety> FieldWriter<'_, REG, WI, FI, Safety>
390where
391    REG: Writable + RegisterSpec,
392    FI: FieldSpec,
393{
394    /// Field width
395    pub const WIDTH: u8 = WI;
396
397    /// Field width
398    #[inline(always)]
399    pub const fn width(&self) -> u8 {
400        WI
401    }
402
403    /// Field offset
404    #[inline(always)]
405    pub const fn offset(&self) -> u8 {
406        self.o
407    }
408}
409
410impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
411where
412    REG: Writable + RegisterSpec,
413    FI: FieldSpec,
414    REG::Ux: From<FI::Ux>,
415{
416    /// Writes raw bits to the field
417    ///
418    /// # Safety
419    ///
420    /// Passing incorrect value can cause undefined behaviour. See reference manual
421    #[inline(always)]
422    pub unsafe fn bits(self, value: FI::Ux) -> &'a mut W<REG> {
423        self.w.bits &= !(REG::Ux::mask::<WI>() << self.o);
424        self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << self.o;
425        self.w
426    }
427}
428
429impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI, Safe>
430where
431    REG: Writable + RegisterSpec,
432    FI: FieldSpec,
433    REG::Ux: From<FI::Ux>,
434{
435    /// Writes raw bits to the field
436    #[inline(always)]
437    pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
438        unsafe { self.bits(value) }
439    }
440}
441
442impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64>
443    FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
444where
445    REG: Writable + RegisterSpec,
446    FI: FieldSpec,
447    REG::Ux: From<FI::Ux>,
448    u64: From<FI::Ux>,
449{
450    /// Writes raw bits to the field
451    #[inline(always)]
452    pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
453        {
454            let value = u64::from(value);
455            assert!(value >= MIN && value <= MAX);
456        }
457        unsafe { self.bits(value) }
458    }
459}
460
461impl<'a, REG, const WI: u8, FI, const MIN: u64> FieldWriter<'a, REG, WI, FI, RangeFrom<MIN>>
462where
463    REG: Writable + RegisterSpec,
464    FI: FieldSpec,
465    REG::Ux: From<FI::Ux>,
466    u64: From<FI::Ux>,
467{
468    /// Writes raw bits to the field
469    #[inline(always)]
470    pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
471        {
472            let value = u64::from(value);
473            assert!(value >= MIN);
474        }
475        unsafe { self.bits(value) }
476    }
477}
478
479impl<'a, REG, const WI: u8, FI, const MAX: u64> FieldWriter<'a, REG, WI, FI, RangeTo<MAX>>
480where
481    REG: Writable + RegisterSpec,
482    FI: FieldSpec,
483    REG::Ux: From<FI::Ux>,
484    u64: From<FI::Ux>,
485{
486    /// Writes raw bits to the field
487    #[inline(always)]
488    pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
489        {
490            let value = u64::from(value);
491            assert!(value <= MAX);
492        }
493        unsafe { self.bits(value) }
494    }
495}
496
497impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
498where
499    REG: Writable + RegisterSpec,
500    FI: IsEnum,
501    REG::Ux: From<FI::Ux>,
502{
503    /// Writes `variant` to the field
504    #[inline(always)]
505    pub fn variant(self, variant: FI) -> &'a mut W<REG> {
506        unsafe { self.bits(FI::Ux::from(variant)) }
507    }
508}
509
510macro_rules! bit_proxy {
511    ($writer:ident, $mwv:ident) => {
512        #[doc(hidden)]
513        pub struct $mwv;
514
515        /// Bit-wise write field proxy
516        pub type $writer<'a, REG, FI = bool> = raw::BitWriter<'a, REG, FI, $mwv>;
517
518        impl<'a, REG, FI> $writer<'a, REG, FI>
519        where
520            REG: Writable + RegisterSpec,
521            bool: From<FI>,
522        {
523            /// Field width
524            pub const WIDTH: u8 = 1;
525
526            /// Field width
527            #[inline(always)]
528            pub const fn width(&self) -> u8 {
529                Self::WIDTH
530            }
531
532            /// Field offset
533            #[inline(always)]
534            pub const fn offset(&self) -> u8 {
535                self.o
536            }
537
538            /// Writes bit to the field
539            #[inline(always)]
540            pub fn bit(self, value: bool) -> &'a mut W<REG> {
541                self.w.bits &= !(REG::Ux::ONE << self.o);
542                self.w.bits |= (REG::Ux::from(value) & REG::Ux::ONE) << self.o;
543                self.w
544            }
545            /// Writes `variant` to the field
546            #[inline(always)]
547            pub fn variant(self, variant: FI) -> &'a mut W<REG> {
548                self.bit(bool::from(variant))
549            }
550        }
551    };
552}
553
554bit_proxy!(BitWriter, BitM);
555bit_proxy!(BitWriter1S, Bit1S);
556bit_proxy!(BitWriter0C, Bit0C);
557bit_proxy!(BitWriter1C, Bit1C);
558bit_proxy!(BitWriter0S, Bit0S);
559bit_proxy!(BitWriter1T, Bit1T);
560bit_proxy!(BitWriter0T, Bit0T);
561
562impl<'a, REG, FI> BitWriter<'a, REG, FI>
563where
564    REG: Writable + RegisterSpec,
565    bool: From<FI>,
566{
567    /// Sets the field bit
568    #[inline(always)]
569    pub fn set_bit(self) -> &'a mut W<REG> {
570        self.w.bits |= REG::Ux::ONE << self.o;
571        self.w
572    }
573    /// Clears the field bit
574    #[inline(always)]
575    pub fn clear_bit(self) -> &'a mut W<REG> {
576        self.w.bits &= !(REG::Ux::ONE << self.o);
577        self.w
578    }
579}
580
581impl<'a, REG, FI> BitWriter1S<'a, REG, FI>
582where
583    REG: Writable + RegisterSpec,
584    bool: From<FI>,
585{
586    /// Sets the field bit
587    #[inline(always)]
588    pub fn set_bit(self) -> &'a mut W<REG> {
589        self.w.bits |= REG::Ux::ONE << self.o;
590        self.w
591    }
592}
593
594impl<'a, REG, FI> BitWriter0C<'a, REG, FI>
595where
596    REG: Writable + RegisterSpec,
597    bool: From<FI>,
598{
599    /// Clears the field bit
600    #[inline(always)]
601    pub fn clear_bit(self) -> &'a mut W<REG> {
602        self.w.bits &= !(REG::Ux::ONE << self.o);
603        self.w
604    }
605}
606
607impl<'a, REG, FI> BitWriter1C<'a, REG, FI>
608where
609    REG: Writable + RegisterSpec,
610    bool: From<FI>,
611{
612    ///Clears the field bit by passing one
613    #[inline(always)]
614    pub fn clear_bit_by_one(self) -> &'a mut W<REG> {
615        self.w.bits |= REG::Ux::ONE << self.o;
616        self.w
617    }
618}
619
620impl<'a, REG, FI> BitWriter0S<'a, REG, FI>
621where
622    REG: Writable + RegisterSpec,
623    bool: From<FI>,
624{
625    ///Sets the field bit by passing zero
626    #[inline(always)]
627    pub fn set_bit_by_zero(self) -> &'a mut W<REG> {
628        self.w.bits &= !(REG::Ux::ONE << self.o);
629        self.w
630    }
631}
632
633impl<'a, REG, FI> BitWriter1T<'a, REG, FI>
634where
635    REG: Writable + RegisterSpec,
636    bool: From<FI>,
637{
638    ///Toggle the field bit by passing one
639    #[inline(always)]
640    pub fn toggle_bit(self) -> &'a mut W<REG> {
641        self.w.bits |= REG::Ux::ONE << self.o;
642        self.w
643    }
644}
645
646impl<'a, REG, FI> BitWriter0T<'a, REG, FI>
647where
648    REG: Writable + RegisterSpec,
649    bool: From<FI>,
650{
651    ///Toggle the field bit by passing zero
652    #[inline(always)]
653    pub fn toggle_bit(self) -> &'a mut W<REG> {
654        self.w.bits &= !(REG::Ux::ONE << self.o);
655        self.w
656    }
657}
658
659/// This structure provides volatile access to registers.
660#[repr(transparent)]
661pub struct Reg<REG: RegisterSpec> {
662    register: vcell::VolatileCell<REG::Ux>,
663    _marker: marker::PhantomData<REG>,
664}
665
666unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
667
668impl<REG: RegisterSpec> Reg<REG> {
669    /// Returns the underlying memory address of register.
670    ///
671    /// ```ignore
672    /// let reg_ptr = periph.reg.as_ptr();
673    /// ```
674    #[inline(always)]
675    pub fn as_ptr(&self) -> *mut REG::Ux {
676        self.register.as_ptr()
677    }
678}
679
680impl<REG: Readable> Reg<REG> {
681    /// Reads the contents of a `Readable` register.
682    ///
683    /// You can read the raw contents of a register by using `bits`:
684    /// ```ignore
685    /// let bits = periph.reg.read().bits();
686    /// ```
687    /// or get the content of a particular field of a register:
688    /// ```ignore
689    /// let reader = periph.reg.read();
690    /// let bits = reader.field1().bits();
691    /// let flag = reader.field2().bit_is_set();
692    /// ```
693    #[inline(always)]
694    pub fn read(&self) -> R<REG> {
695        R {
696            bits: self.register.get(),
697            _reg: marker::PhantomData,
698        }
699    }
700}
701
702impl<REG: Resettable + Writable> Reg<REG> {
703    /// Writes the reset value to `Writable` register.
704    ///
705    /// Resets the register to its initial state.
706    #[inline(always)]
707    pub fn reset(&self) {
708        self.register.set(REG::RESET_VALUE)
709    }
710
711    /// Writes bits to a `Writable` register.
712    ///
713    /// You can write raw bits into a register:
714    /// ```ignore
715    /// periph.reg.write(|w| unsafe { w.bits(rawbits) });
716    /// ```
717    /// or write only the fields you need:
718    /// ```ignore
719    /// periph.reg.write(|w| w
720    ///     .field1().bits(newfield1bits)
721    ///     .field2().set_bit()
722    ///     .field3().variant(VARIANT)
723    /// );
724    /// ```
725    /// or an alternative way of saying the same:
726    /// ```ignore
727    /// periph.reg.write(|w| {
728    ///     w.field1().bits(newfield1bits);
729    ///     w.field2().set_bit();
730    ///     w.field3().variant(VARIANT)
731    /// });
732    /// ```
733    /// In the latter case, other fields will be set to their reset value.
734    #[inline(always)]
735    pub fn write<F>(&self, f: F) -> REG::Ux
736    where
737        F: FnOnce(&mut W<REG>) -> &mut W<REG>,
738    {
739        let value = f(&mut W {
740            bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
741                | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
742            _reg: marker::PhantomData,
743        })
744        .bits;
745        self.register.set(value);
746        value
747    }
748
749    /// Writes bits to a `Writable` register and produce a value.
750    ///
751    /// You can write raw bits into a register:
752    /// ```ignore
753    /// periph.reg.write_and(|w| unsafe { w.bits(rawbits); });
754    /// ```
755    /// or write only the fields you need:
756    /// ```ignore
757    /// periph.reg.write_and(|w| {
758    ///     w.field1().bits(newfield1bits)
759    ///         .field2().set_bit()
760    ///         .field3().variant(VARIANT);
761    /// });
762    /// ```
763    /// or an alternative way of saying the same:
764    /// ```ignore
765    /// periph.reg.write_and(|w| {
766    ///     w.field1().bits(newfield1bits);
767    ///     w.field2().set_bit();
768    ///     w.field3().variant(VARIANT);
769    /// });
770    /// ```
771    /// In the latter case, other fields will be set to their reset value.
772    ///
773    /// Values can be returned from the closure:
774    /// ```ignore
775    /// let state = periph.reg.write_and(|w| State::set(w.field1()));
776    /// ```
777    #[inline(always)]
778    pub fn from_write<F, T>(&self, f: F) -> T
779    where
780        F: FnOnce(&mut W<REG>) -> T,
781    {
782        let mut writer = W {
783            bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
784                | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
785            _reg: marker::PhantomData,
786        };
787        let result = f(&mut writer);
788
789        self.register.set(writer.bits);
790
791        result
792    }
793}
794
795impl<REG: Writable> Reg<REG> {
796    /// Writes 0 to a `Writable` register.
797    ///
798    /// Similar to `write`, but unused bits will contain 0.
799    ///
800    /// # Safety
801    ///
802    /// Unsafe to use with registers which don't allow to write 0.
803    #[inline(always)]
804    pub unsafe fn write_with_zero<F>(&self, f: F) -> REG::Ux
805    where
806        F: FnOnce(&mut W<REG>) -> &mut W<REG>,
807    {
808        let value = f(&mut W {
809            bits: REG::Ux::ZERO,
810            _reg: marker::PhantomData,
811        })
812        .bits;
813        self.register.set(value);
814        value
815    }
816
817    /// Writes 0 to a `Writable` register and produces a value.
818    ///
819    /// Similar to `write`, but unused bits will contain 0.
820    ///
821    /// # Safety
822    ///
823    /// Unsafe to use with registers which don't allow to write 0.
824    #[inline(always)]
825    pub unsafe fn from_write_with_zero<F, T>(&self, f: F) -> T
826    where
827        F: FnOnce(&mut W<REG>) -> T,
828    {
829        let mut writer = W {
830            bits: REG::Ux::ZERO,
831            _reg: marker::PhantomData,
832        };
833
834        let result = f(&mut writer);
835
836        self.register.set(writer.bits);
837
838        result
839    }
840}
841
842impl<REG: Readable + Writable> Reg<REG> {
843    /// Modifies the contents of the register by reading and then writing it.
844    ///
845    /// E.g. to do a read-modify-write sequence to change parts of a register:
846    /// ```ignore
847    /// periph.reg.modify(|r, w| unsafe { w.bits(
848    ///    r.bits() | 3
849    /// ) });
850    /// ```
851    /// or
852    /// ```ignore
853    /// periph.reg.modify(|_, w| w
854    ///     .field1().bits(newfield1bits)
855    ///     .field2().set_bit()
856    ///     .field3().variant(VARIANT)
857    /// );
858    /// ```
859    /// or an alternative way of saying the same:
860    /// ```ignore
861    /// periph.reg.modify(|_, w| {
862    ///     w.field1().bits(newfield1bits);
863    ///     w.field2().set_bit();
864    ///     w.field3().variant(VARIANT)
865    /// });
866    /// ```
867    /// Other fields will have the value they had before the call to `modify`.
868    #[inline(always)]
869    pub fn modify<F>(&self, f: F) -> REG::Ux
870    where
871        for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
872    {
873        let bits = self.register.get();
874        let value = f(
875            &R {
876                bits,
877                _reg: marker::PhantomData,
878            },
879            &mut W {
880                bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
881                _reg: marker::PhantomData,
882            },
883        )
884        .bits;
885        self.register.set(value);
886        value
887    }
888
889    /// Modifies the contents of the register by reading and then writing it
890    /// and produces a value.
891    ///
892    /// E.g. to do a read-modify-write sequence to change parts of a register:
893    /// ```ignore
894    /// let bits = periph.reg.modify(|r, w| {
895    ///     let new_bits = r.bits() | 3;
896    ///     unsafe {
897    ///         w.bits(new_bits);
898    ///     }
899    ///
900    ///     new_bits
901    /// });
902    /// ```
903    /// or
904    /// ```ignore
905    /// periph.reg.modify(|_, w| {
906    ///     w.field1().bits(newfield1bits)
907    ///         .field2().set_bit()
908    ///         .field3().variant(VARIANT);
909    /// });
910    /// ```
911    /// or an alternative way of saying the same:
912    /// ```ignore
913    /// periph.reg.modify(|_, w| {
914    ///     w.field1().bits(newfield1bits);
915    ///     w.field2().set_bit();
916    ///     w.field3().variant(VARIANT);
917    /// });
918    /// ```
919    /// Other fields will have the value they had before the call to `modify`.
920    #[inline(always)]
921    pub fn from_modify<F, T>(&self, f: F) -> T
922    where
923        for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> T,
924    {
925        let bits = self.register.get();
926
927        let mut writer = W {
928            bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
929            _reg: marker::PhantomData,
930        };
931
932        let result = f(
933            &R {
934                bits,
935                _reg: marker::PhantomData,
936            },
937            &mut writer,
938        );
939
940        self.register.set(writer.bits);
941
942        result
943    }
944}
945
946impl<REG: Readable> core::fmt::Debug for crate::generic::Reg<REG>
947where
948    R<REG>: core::fmt::Debug,
949{
950    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
951        core::fmt::Debug::fmt(&self.read(), f)
952    }
953}
954
955#[cfg(feature = "atomics")]
956
957mod atomic {
958    use super::*;
959    use portable_atomic::Ordering;
960
961    pub trait AtomicOperations {
962        unsafe fn atomic_or(ptr: *mut Self, val: Self);
963        unsafe fn atomic_and(ptr: *mut Self, val: Self);
964        unsafe fn atomic_xor(ptr: *mut Self, val: Self);
965    }
966
967    macro_rules! impl_atomics {
968        ($U:ty, $Atomic:ty) => {
969            impl AtomicOperations for $U {
970                unsafe fn atomic_or(ptr: *mut Self, val: Self) {
971                    (*(ptr as *const $Atomic)).or(val, Ordering::SeqCst);
972                }
973
974                unsafe fn atomic_and(ptr: *mut Self, val: Self) {
975                    (*(ptr as *const $Atomic)).and(val, Ordering::SeqCst);
976                }
977
978                unsafe fn atomic_xor(ptr: *mut Self, val: Self) {
979                    (*(ptr as *const $Atomic)).xor(val, Ordering::SeqCst);
980                }
981            }
982        };
983    }
984
985    impl_atomics!(u8, portable_atomic::AtomicU8);
986    impl_atomics!(u16, portable_atomic::AtomicU16);
987
988    // Exclude 16-bit archs from 32-bit atomics
989    #[cfg(not(target_pointer_width = "16"))]
990    impl_atomics!(u32, portable_atomic::AtomicU32);
991
992    // Enable 64-bit atomics for 64-bit RISCV
993    #[cfg(any(target_pointer_width = "64", target_has_atomic = "64"))]
994    impl_atomics!(u64, portable_atomic::AtomicU64);
995
996    impl<REG: Readable + Writable> Reg<REG>
997    where
998        REG::Ux: AtomicOperations,
999    {
1000        /// Set high every bit in the register that was set in the write proxy. Leave other bits
1001        /// untouched. The write is done in a single atomic instruction.
1002        ///
1003        /// # Safety
1004        ///
1005        /// The resultant bit pattern may not be valid for the register.
1006        #[inline(always)]
1007        pub unsafe fn set_bits<F>(&self, f: F)
1008        where
1009            F: FnOnce(&mut W<REG>) -> &mut W<REG>,
1010        {
1011            let bits = f(&mut W {
1012                bits: REG::Ux::ZERO,
1013                _reg: marker::PhantomData,
1014            })
1015            .bits;
1016            REG::Ux::atomic_or(self.register.as_ptr(), bits);
1017        }
1018
1019        /// Clear every bit in the register that was cleared in the write proxy. Leave other bits
1020        /// untouched. The write is done in a single atomic instruction.
1021        ///
1022        /// # Safety
1023        ///
1024        /// The resultant bit pattern may not be valid for the register.
1025        #[inline(always)]
1026        pub unsafe fn clear_bits<F>(&self, f: F)
1027        where
1028            F: FnOnce(&mut W<REG>) -> &mut W<REG>,
1029        {
1030            let bits = f(&mut W {
1031                bits: !REG::Ux::ZERO,
1032                _reg: marker::PhantomData,
1033            })
1034            .bits;
1035            REG::Ux::atomic_and(self.register.as_ptr(), bits);
1036        }
1037
1038        /// Toggle every bit in the register that was set in the write proxy. Leave other bits
1039        /// untouched. The write is done in a single atomic instruction.
1040        ///
1041        /// # Safety
1042        ///
1043        /// The resultant bit pattern may not be valid for the register.
1044        #[inline(always)]
1045        pub unsafe fn toggle_bits<F>(&self, f: F)
1046        where
1047            F: FnOnce(&mut W<REG>) -> &mut W<REG>,
1048        {
1049            let bits = f(&mut W {
1050                bits: REG::Ux::ZERO,
1051                _reg: marker::PhantomData,
1052            })
1053            .bits;
1054            REG::Ux::atomic_xor(self.register.as_ptr(), bits);
1055        }
1056    }
1057}
1058