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