atsam3s2c/
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 + 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/// This structure provides volatile access to registers.
99#[repr(transparent)]
100pub struct Reg<REG: RegisterSpec> {
101    register: vcell::VolatileCell<REG::Ux>,
102    _marker: marker::PhantomData<REG>,
103}
104
105unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
106
107impl<REG: RegisterSpec> Reg<REG> {
108    /// Returns the underlying memory address of register.
109    ///
110    /// ```ignore
111    /// let reg_ptr = periph.reg.as_ptr();
112    /// ```
113    #[inline(always)]
114    pub fn as_ptr(&self) -> *mut REG::Ux {
115        self.register.as_ptr()
116    }
117}
118
119impl<REG: Readable> Reg<REG> {
120    /// Reads the contents of a `Readable` register.
121    ///
122    /// You can read the raw contents of a register by using `bits`:
123    /// ```ignore
124    /// let bits = periph.reg.read().bits();
125    /// ```
126    /// or get the content of a particular field of a register:
127    /// ```ignore
128    /// let reader = periph.reg.read();
129    /// let bits = reader.field1().bits();
130    /// let flag = reader.field2().bit_is_set();
131    /// ```
132    #[inline(always)]
133    pub fn read(&self) -> R<REG> {
134        R {
135            bits: self.register.get(),
136            _reg: marker::PhantomData,
137        }
138    }
139}
140
141impl<REG: Resettable + Writable> Reg<REG> {
142    /// Writes the reset value to `Writable` register.
143    ///
144    /// Resets the register to its initial state.
145    #[inline(always)]
146    pub fn reset(&self) {
147        self.register.set(REG::RESET_VALUE)
148    }
149
150    /// Writes bits to a `Writable` register.
151    ///
152    /// You can write raw bits into a register:
153    /// ```ignore
154    /// periph.reg.write(|w| unsafe { w.bits(rawbits) });
155    /// ```
156    /// or write only the fields you need:
157    /// ```ignore
158    /// periph.reg.write(|w| w
159    ///     .field1().bits(newfield1bits)
160    ///     .field2().set_bit()
161    ///     .field3().variant(VARIANT)
162    /// );
163    /// ```
164    /// or an alternative way of saying the same:
165    /// ```ignore
166    /// periph.reg.write(|w| {
167    ///     w.field1().bits(newfield1bits);
168    ///     w.field2().set_bit();
169    ///     w.field3().variant(VARIANT)
170    /// });
171    /// ```
172    /// In the latter case, other fields will be set to their reset value.
173    #[inline(always)]
174    pub fn write<F>(&self, f: F)
175    where
176        F: FnOnce(&mut W<REG>) -> &mut W<REG>,
177    {
178        self.register.set(
179            f(&mut W {
180                bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
181                    | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
182                _reg: marker::PhantomData,
183            })
184            .bits,
185        );
186    }
187}
188
189impl<REG: Writable> Reg<REG> {
190    /// Writes 0 to a `Writable` register.
191    ///
192    /// Similar to `write`, but unused bits will contain 0.
193    ///
194    /// # Safety
195    ///
196    /// Unsafe to use with registers which don't allow to write 0.
197    #[inline(always)]
198    pub unsafe fn write_with_zero<F>(&self, f: F)
199    where
200        F: FnOnce(&mut W<REG>) -> &mut W<REG>,
201    {
202        self.register.set(
203            f(&mut W {
204                bits: REG::Ux::default(),
205                _reg: marker::PhantomData,
206            })
207            .bits,
208        );
209    }
210}
211
212impl<REG: Readable + Writable> Reg<REG> {
213    /// Modifies the contents of the register by reading and then writing it.
214    ///
215    /// E.g. to do a read-modify-write sequence to change parts of a register:
216    /// ```ignore
217    /// periph.reg.modify(|r, w| unsafe { w.bits(
218    ///    r.bits() | 3
219    /// ) });
220    /// ```
221    /// or
222    /// ```ignore
223    /// periph.reg.modify(|_, w| w
224    ///     .field1().bits(newfield1bits)
225    ///     .field2().set_bit()
226    ///     .field3().variant(VARIANT)
227    /// );
228    /// ```
229    /// or an alternative way of saying the same:
230    /// ```ignore
231    /// periph.reg.modify(|_, w| {
232    ///     w.field1().bits(newfield1bits);
233    ///     w.field2().set_bit();
234    ///     w.field3().variant(VARIANT)
235    /// });
236    /// ```
237    /// Other fields will have the value they had before the call to `modify`.
238    #[inline(always)]
239    pub fn modify<F>(&self, f: F)
240    where
241        for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
242    {
243        let bits = self.register.get();
244        self.register.set(
245            f(
246                &R {
247                    bits,
248                    _reg: marker::PhantomData,
249                },
250                &mut W {
251                    bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
252                        | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
253                    _reg: marker::PhantomData,
254                },
255            )
256            .bits,
257        );
258    }
259}
260
261#[doc(hidden)]
262pub mod raw {
263    use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
264
265    pub struct R<REG: RegisterSpec> {
266        pub(crate) bits: REG::Ux,
267        pub(super) _reg: marker::PhantomData<REG>,
268    }
269
270    pub struct W<REG: RegisterSpec> {
271        ///Writable bits
272        pub(crate) bits: REG::Ux,
273        pub(super) _reg: marker::PhantomData<REG>,
274    }
275
276    pub struct FieldReader<FI = u8>
277    where
278        FI: FieldSpec,
279    {
280        pub(crate) bits: FI::Ux,
281        _reg: marker::PhantomData<FI>,
282    }
283
284    impl<FI: FieldSpec> FieldReader<FI> {
285        /// Creates a new instance of the reader.
286        #[allow(unused)]
287        #[inline(always)]
288        pub(crate) const fn new(bits: FI::Ux) -> Self {
289            Self {
290                bits,
291                _reg: marker::PhantomData,
292            }
293        }
294    }
295
296    pub struct BitReader<FI = bool> {
297        pub(crate) bits: bool,
298        _reg: marker::PhantomData<FI>,
299    }
300
301    impl<FI> BitReader<FI> {
302        /// Creates a new instance of the reader.
303        #[allow(unused)]
304        #[inline(always)]
305        pub(crate) const fn new(bits: bool) -> Self {
306            Self {
307                bits,
308                _reg: marker::PhantomData,
309            }
310        }
311    }
312
313    pub struct FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe>
314    where
315        REG: Writable + RegisterSpec,
316        FI: FieldSpec,
317    {
318        pub(crate) w: &'a mut W<REG>,
319        pub(crate) o: u8,
320        _field: marker::PhantomData<(FI, Safety)>,
321    }
322
323    impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
324    where
325        REG: Writable + RegisterSpec,
326        FI: FieldSpec,
327    {
328        /// Creates a new instance of the writer
329        #[allow(unused)]
330        #[inline(always)]
331        pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
332            Self {
333                w,
334                o,
335                _field: marker::PhantomData,
336            }
337        }
338    }
339
340    pub struct BitWriter<'a, REG, FI = bool, M = BitM>
341    where
342        REG: Writable + RegisterSpec,
343        bool: From<FI>,
344    {
345        pub(crate) w: &'a mut W<REG>,
346        pub(crate) o: u8,
347        _field: marker::PhantomData<(FI, M)>,
348    }
349
350    impl<'a, REG, FI, M> BitWriter<'a, REG, FI, M>
351    where
352        REG: Writable + RegisterSpec,
353        bool: From<FI>,
354    {
355        /// Creates a new instance of the writer
356        #[allow(unused)]
357        #[inline(always)]
358        pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
359            Self {
360                w,
361                o,
362                _field: marker::PhantomData,
363            }
364        }
365    }
366}
367
368/// Register reader.
369///
370/// Result of the `read` methods of registers. Also used as a closure argument in the `modify`
371/// method.
372pub type R<REG> = raw::R<REG>;
373
374impl<REG: RegisterSpec> R<REG> {
375    /// Reads raw bits from register.
376    #[inline(always)]
377    pub const fn bits(&self) -> REG::Ux {
378        self.bits
379    }
380}
381
382impl<REG: RegisterSpec, FI> PartialEq<FI> for R<REG>
383where
384    REG::Ux: PartialEq,
385    FI: Copy,
386    REG::Ux: From<FI>,
387{
388    #[inline(always)]
389    fn eq(&self, other: &FI) -> bool {
390        self.bits.eq(&REG::Ux::from(*other))
391    }
392}
393
394/// Register writer.
395///
396/// Used as an argument to the closures in the `write` and `modify` methods of the register.
397pub type W<REG> = raw::W<REG>;
398
399impl<REG: Writable> W<REG> {
400    /// Writes raw bits to the register.
401    ///
402    /// # Safety
403    ///
404    /// Passing incorrect value can cause undefined behaviour. See reference manual
405    #[inline(always)]
406    pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {
407        self.bits = bits;
408        self
409    }
410}
411impl<REG> W<REG>
412where
413    REG: Writable<Safety = Safe>,
414{
415    /// Writes raw bits to the register.
416    #[inline(always)]
417    pub fn set(&mut self, bits: REG::Ux) -> &mut Self {
418        self.bits = bits;
419        self
420    }
421}
422
423/// Field reader.
424///
425/// Result of the `read` methods of fields.
426pub type FieldReader<FI = u8> = raw::FieldReader<FI>;
427
428/// Bit-wise field reader
429pub type BitReader<FI = bool> = raw::BitReader<FI>;
430
431impl<FI: FieldSpec> FieldReader<FI> {
432    /// Reads raw bits from field.
433    #[inline(always)]
434    pub const fn bits(&self) -> FI::Ux {
435        self.bits
436    }
437}
438
439impl<FI> PartialEq<FI> for FieldReader<FI>
440where
441    FI: FieldSpec + Copy,
442{
443    #[inline(always)]
444    fn eq(&self, other: &FI) -> bool {
445        self.bits.eq(&FI::Ux::from(*other))
446    }
447}
448
449impl<FI> PartialEq<FI> for BitReader<FI>
450where
451    FI: Copy,
452    bool: From<FI>,
453{
454    #[inline(always)]
455    fn eq(&self, other: &FI) -> bool {
456        self.bits.eq(&bool::from(*other))
457    }
458}
459
460impl<FI> BitReader<FI> {
461    /// Value of the field as raw bits.
462    #[inline(always)]
463    pub const fn bit(&self) -> bool {
464        self.bits
465    }
466    /// Returns `true` if the bit is clear (0).
467    #[inline(always)]
468    pub const fn bit_is_clear(&self) -> bool {
469        !self.bit()
470    }
471    /// Returns `true` if the bit is set (1).
472    #[inline(always)]
473    pub const fn bit_is_set(&self) -> bool {
474        self.bit()
475    }
476}
477
478/// Marker for register/field writers which can take any value of specified width
479pub struct Safe;
480/// You should check that value is allowed to pass to register/field writer marked with this
481pub struct Unsafe;
482
483/// Write field Proxy
484pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
485    raw::FieldWriter<'a, REG, WI, FI, Safety>;
486
487impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
488where
489    REG: Writable + RegisterSpec,
490    FI: FieldSpec,
491{
492    /// Field width
493    pub const WIDTH: u8 = WI;
494
495    /// Field width
496    #[inline(always)]
497    pub const fn width(&self) -> u8 {
498        WI
499    }
500
501    /// Field offset
502    #[inline(always)]
503    pub const fn offset(&self) -> u8 {
504        self.o
505    }
506}
507
508impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
509where
510    REG: Writable + RegisterSpec,
511    FI: FieldSpec,
512    REG::Ux: From<FI::Ux>,
513{
514    /// Writes raw bits to the field
515    ///
516    /// # Safety
517    ///
518    /// Passing incorrect value can cause undefined behaviour. See reference manual
519    #[inline(always)]
520    pub unsafe fn bits(self, value: FI::Ux) -> &'a mut W<REG> {
521        self.w.bits &= !(REG::Ux::mask::<WI>() << self.o);
522        self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << self.o;
523        self.w
524    }
525}
526
527impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI, Safe>
528where
529    REG: Writable + RegisterSpec,
530    FI: FieldSpec,
531    REG::Ux: From<FI::Ux>,
532{
533    /// Writes raw bits to the field
534    #[inline(always)]
535    pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
536        unsafe { self.bits(value) }
537    }
538}
539
540impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
541where
542    REG: Writable + RegisterSpec,
543    FI: IsEnum,
544    REG::Ux: From<FI::Ux>,
545{
546    /// Writes `variant` to the field
547    #[inline(always)]
548    pub fn variant(self, variant: FI) -> &'a mut W<REG> {
549        unsafe { self.bits(FI::Ux::from(variant)) }
550    }
551}
552
553macro_rules! bit_proxy {
554    ($writer:ident, $mwv:ident) => {
555        #[doc(hidden)]
556        pub struct $mwv;
557
558        /// Bit-wise write field proxy
559        pub type $writer<'a, REG, FI = bool> = raw::BitWriter<'a, REG, FI, $mwv>;
560
561        impl<'a, REG, FI> $writer<'a, REG, FI>
562        where
563            REG: Writable + RegisterSpec,
564            bool: From<FI>,
565        {
566            /// Field width
567            pub const WIDTH: u8 = 1;
568
569            /// Field width
570            #[inline(always)]
571            pub const fn width(&self) -> u8 {
572                Self::WIDTH
573            }
574
575            /// Field offset
576            #[inline(always)]
577            pub const fn offset(&self) -> u8 {
578                self.o
579            }
580
581            /// Writes bit to the field
582            #[inline(always)]
583            pub fn bit(self, value: bool) -> &'a mut W<REG> {
584                self.w.bits &= !(REG::Ux::one() << self.o);
585                self.w.bits |= (REG::Ux::from(value) & REG::Ux::one()) << self.o;
586                self.w
587            }
588            /// Writes `variant` to the field
589            #[inline(always)]
590            pub fn variant(self, variant: FI) -> &'a mut W<REG> {
591                self.bit(bool::from(variant))
592            }
593        }
594    };
595}
596
597bit_proxy!(BitWriter, BitM);
598bit_proxy!(BitWriter1S, Bit1S);
599bit_proxy!(BitWriter0C, Bit0C);
600bit_proxy!(BitWriter1C, Bit1C);
601bit_proxy!(BitWriter0S, Bit0S);
602bit_proxy!(BitWriter1T, Bit1T);
603bit_proxy!(BitWriter0T, Bit0T);
604
605impl<'a, REG, FI> BitWriter<'a, REG, FI>
606where
607    REG: Writable + RegisterSpec,
608    bool: From<FI>,
609{
610    /// Sets the field bit
611    #[inline(always)]
612    pub fn set_bit(self) -> &'a mut W<REG> {
613        self.w.bits |= REG::Ux::one() << self.o;
614        self.w
615    }
616    /// Clears the field bit
617    #[inline(always)]
618    pub fn clear_bit(self) -> &'a mut W<REG> {
619        self.w.bits &= !(REG::Ux::one() << self.o);
620        self.w
621    }
622}
623
624impl<'a, REG, FI> BitWriter1S<'a, REG, FI>
625where
626    REG: Writable + RegisterSpec,
627    bool: From<FI>,
628{
629    /// Sets the field bit
630    #[inline(always)]
631    pub fn set_bit(self) -> &'a mut W<REG> {
632        self.w.bits |= REG::Ux::one() << self.o;
633        self.w
634    }
635}
636
637impl<'a, REG, FI> BitWriter0C<'a, REG, FI>
638where
639    REG: Writable + RegisterSpec,
640    bool: From<FI>,
641{
642    /// Clears the field bit
643    #[inline(always)]
644    pub fn clear_bit(self) -> &'a mut W<REG> {
645        self.w.bits &= !(REG::Ux::one() << self.o);
646        self.w
647    }
648}
649
650impl<'a, REG, FI> BitWriter1C<'a, REG, FI>
651where
652    REG: Writable + RegisterSpec,
653    bool: From<FI>,
654{
655    ///Clears the field bit by passing one
656    #[inline(always)]
657    pub fn clear_bit_by_one(self) -> &'a mut W<REG> {
658        self.w.bits |= REG::Ux::one() << self.o;
659        self.w
660    }
661}
662
663impl<'a, REG, FI> BitWriter0S<'a, REG, FI>
664where
665    REG: Writable + RegisterSpec,
666    bool: From<FI>,
667{
668    ///Sets the field bit by passing zero
669    #[inline(always)]
670    pub fn set_bit_by_zero(self) -> &'a mut W<REG> {
671        self.w.bits &= !(REG::Ux::one() << self.o);
672        self.w
673    }
674}
675
676impl<'a, REG, FI> BitWriter1T<'a, REG, FI>
677where
678    REG: Writable + RegisterSpec,
679    bool: From<FI>,
680{
681    ///Toggle the field bit by passing one
682    #[inline(always)]
683    pub fn toggle_bit(self) -> &'a mut W<REG> {
684        self.w.bits |= REG::Ux::one() << self.o;
685        self.w
686    }
687}
688
689impl<'a, REG, FI> BitWriter0T<'a, REG, FI>
690where
691    REG: Writable + RegisterSpec,
692    bool: From<FI>,
693{
694    ///Toggle the field bit by passing zero
695    #[inline(always)]
696    pub fn toggle_bit(self) -> &'a mut W<REG> {
697        self.w.bits &= !(REG::Ux::one() << self.o);
698        self.w
699    }
700}