stm32f3_staging/
generic.rs

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