lpc13xx_pac/
generic.rs

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