stm32f0/
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    /// In the latter case, other fields will be set to their reset value.
103    #[inline(always)]
104    pub fn write<F>(&self, f: F)
105    where
106        F: FnOnce(&mut REG::Writer) -> &mut W<REG>
107    {
108        self.register.set(
109            f(&mut REG::Writer::from(W {
110                bits: REG::reset_value(),
111                _reg: marker::PhantomData,
112            }))
113            .bits,
114        );
115    }
116}
117
118impl<REG: Writable> Reg<REG>
119where
120    REG::Ux: Default,
121{
122    /// Writes 0 to a `Writable` register.
123    ///
124    /// Similar to `write`, but unused bits will contain 0.
125    #[inline(always)]
126    pub unsafe fn write_with_zero<F>(&self, f: F)
127    where
128        F: FnOnce(&mut REG::Writer) -> &mut W<REG>
129    {
130        self.register.set(
131            (*f(&mut REG::Writer::from(W {
132                bits: REG::Ux::default(),
133                _reg: marker::PhantomData,
134            })))
135            .bits,
136        );
137    }
138}
139
140impl<REG: Readable + Writable> Reg<REG> {
141    /// Modifies the contents of the register by reading and then writing it.
142    ///
143    /// E.g. to do a read-modify-write sequence to change parts of a register:
144    /// ```ignore
145    /// periph.reg.modify(|r, w| unsafe { w.bits(
146    ///    r.bits() | 3
147    /// ) });
148    /// ```
149    /// or
150    /// ```ignore
151    /// periph.reg.modify(|_, w| w
152    ///     .field1().bits(newfield1bits)
153    ///     .field2().set_bit()
154    ///     .field3().variant(VARIANT)
155    /// );
156    /// ```
157    /// Other fields will have the value they had before the call to `modify`.
158    #[inline(always)]
159    pub fn modify<F>(&self, f: F)
160    where
161        for<'w> F: FnOnce(&REG::Reader, &'w mut REG::Writer) -> &'w mut W<REG>
162    {
163        let bits = self.register.get();
164        self.register.set(
165            f(
166                &REG::Reader::from(R {
167                    bits,
168                    _reg: marker::PhantomData,
169                }),
170                &mut REG::Writer::from(W {
171                    bits,
172                    _reg: marker::PhantomData,
173                }),
174            )
175            .bits,
176        );
177    }
178}
179
180/// Register reader.
181///
182/// Result of the `read` methods of registers. Also used as a closure argument in the `modify`
183/// method.
184pub struct R<REG: RegisterSpec + ?Sized> {
185    pub(crate) bits: REG::Ux,
186    _reg: marker::PhantomData<REG>,
187}
188
189impl<REG: RegisterSpec> R<REG> {
190    /// Reads raw bits from register.
191    #[inline(always)]
192    pub fn bits(&self) -> REG::Ux {
193        self.bits
194    }
195}
196
197impl<REG: RegisterSpec, FI> PartialEq<FI> for R<REG>
198where
199    REG::Ux: PartialEq,
200    FI: Copy + Into<REG::Ux>,
201{
202    #[inline(always)]
203    fn eq(&self, other: &FI) -> bool {
204        self.bits.eq(&(*other).into())
205    }
206}
207
208/// Register writer.
209///
210/// Used as an argument to the closures in the `write` and `modify` methods of the register.
211pub struct W<REG: RegisterSpec + ?Sized> {
212    ///Writable bits
213    pub(crate) bits: REG::Ux,
214    _reg: marker::PhantomData<REG>,
215}
216
217impl<REG: RegisterSpec> W<REG> {
218    /// Writes raw bits to the register.
219    #[inline(always)]
220    pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {
221        self.bits = bits;
222        self
223    }
224}
225
226#[doc(hidden)]
227pub struct FieldReaderRaw<U, T> {
228    pub(crate) bits: U,
229    _reg: marker::PhantomData<T>,
230}
231
232impl<U, FI> FieldReaderRaw<U, FI>
233where
234    U: Copy,
235{
236    /// Creates a new instance of the reader.
237    #[allow(unused)]
238    #[inline(always)]
239    pub(crate) fn new(bits: U) -> Self {
240        Self {
241            bits,
242            _reg: marker::PhantomData,
243        }
244    }
245}
246
247#[doc(hidden)]
248pub struct BitReaderRaw<T> {
249    pub(crate) bits: bool,
250    _reg: marker::PhantomData<T>,
251}
252
253impl<FI> BitReaderRaw<FI> {
254    /// Creates a new instance of the reader.
255    #[allow(unused)]
256    #[inline(always)]
257    pub(crate) fn new(bits: bool) -> Self {
258        Self {
259            bits,
260            _reg: marker::PhantomData,
261        }
262    }
263}
264
265/// Field reader.
266///
267/// Result of the `read` methods of fields.
268pub type FieldReader<U, FI> = FieldReaderRaw<U, FI>;
269
270/// Bit-wise field reader
271pub type BitReader<FI> = BitReaderRaw<FI>;
272
273impl<U, FI> FieldReader<U, FI>
274where
275    U: Copy,
276{
277    /// Reads raw bits from field.
278    #[inline(always)]
279    pub fn bits(&self) -> U {
280        self.bits
281    }
282}
283
284impl<U, FI> PartialEq<FI> for FieldReader<U, FI>
285where
286    U: PartialEq,
287    FI: Copy + Into<U>,
288{
289    #[inline(always)]
290    fn eq(&self, other: &FI) -> bool {
291        self.bits.eq(&(*other).into())
292    }
293}
294
295impl<FI> PartialEq<FI> for BitReader<FI>
296where
297    FI: Copy + Into<bool>,
298{
299    #[inline(always)]
300    fn eq(&self, other: &FI) -> bool {
301        self.bits.eq(&(*other).into())
302    }
303}
304
305impl<FI> BitReader<FI> {
306    /// Value of the field as raw bits.
307    #[inline(always)]
308    pub fn bit(&self) -> bool {
309        self.bits
310    }
311    /// Returns `true` if the bit is clear (0).
312    #[inline(always)]
313    pub fn bit_is_clear(&self) -> bool {
314        !self.bit()
315    }
316    /// Returns `true` if the bit is set (1).
317    #[inline(always)]
318    pub fn bit_is_set(&self) -> bool {
319        self.bit()
320    }
321}
322
323#[doc(hidden)]
324pub struct Safe;
325#[doc(hidden)]
326pub struct Unsafe;
327
328#[doc(hidden)]
329pub struct FieldWriterRaw<'a, U, REG, N, FI, Safety, const WI: u8, const O: u8>
330where
331    REG: Writable + RegisterSpec<Ux = U>,
332    FI: Into<N>,
333{
334    pub(crate) w: &'a mut REG::Writer,
335    _field: marker::PhantomData<(N, FI, Safety)>,
336}
337
338impl<'a, U, REG, N, FI, Safety, const WI: u8, const O: u8> FieldWriterRaw<'a, U, REG, N, FI, Safety, WI, O>
339where
340    REG: Writable + RegisterSpec<Ux = U>,
341    FI: Into<N>,
342{
343    /// Creates a new instance of the writer
344    #[allow(unused)]
345    #[inline(always)]
346    pub(crate) fn new(w: &'a mut REG::Writer) -> Self {
347        Self {
348            w,
349            _field: marker::PhantomData,
350        }
351    }
352}
353
354#[doc(hidden)]
355pub struct BitWriterRaw<'a, U, REG, FI, M, const O: u8>
356where
357    REG: Writable + RegisterSpec<Ux = U>,
358    FI: Into<bool>,
359{
360    pub(crate) w: &'a mut REG::Writer,
361    _field: marker::PhantomData<(FI, M)>,
362}
363
364impl<'a, U, REG, FI, M, const O: u8> BitWriterRaw<'a, U, REG, FI, M, O>
365where
366    REG: Writable + RegisterSpec<Ux = U>,
367    FI: Into<bool>,
368{
369    /// Creates a new instance of the writer
370    #[allow(unused)]
371    #[inline(always)]
372    pub(crate) fn new(w: &'a mut REG::Writer) -> Self {
373        Self {
374            w,
375            _field: marker::PhantomData,
376        }
377    }
378}
379
380/// Write field Proxy with unsafe `bits`
381pub type FieldWriter<'a, U, REG, N, FI, const WI: u8, const O: u8> = FieldWriterRaw<'a, U, REG, N, FI, Unsafe, WI, O>;
382/// Write field Proxy with safe `bits`
383pub type FieldWriterSafe<'a, U, REG, N, FI, const WI: u8, const O: u8> = FieldWriterRaw<'a, U, REG, N, FI, Safe, WI, O>;
384
385
386impl<'a, U, REG, N, FI, const WI: u8, const OF: u8> FieldWriter<'a, U, REG, N, FI, WI, OF>
387where
388    REG: Writable + RegisterSpec<Ux = U>,
389    FI: Into<N>,
390{
391    /// Field width
392    pub const WIDTH: u8 = WI;
393    /// Field offset
394    pub const OFFSET: u8 = OF;
395}
396
397impl<'a, U, REG, N, FI, const WI: u8, const OF: u8> FieldWriterSafe<'a, U, REG, N, FI, WI, OF>
398where
399    REG: Writable + RegisterSpec<Ux = U>,
400    FI: Into<N>,
401{
402    /// Field width
403    pub const WIDTH: u8 = WI;
404    /// Field offset
405    pub const OFFSET: u8 = OF;
406}
407
408macro_rules! bit_proxy {
409    ($writer:ident, $mwv:ident) => {
410        #[doc(hidden)]
411        pub struct $mwv;
412
413        /// Bit-wise write field proxy
414        pub type $writer<'a, U, REG, FI, const O: u8> = BitWriterRaw<'a, U, REG, FI, $mwv, O>;
415
416        impl<'a, U, REG, FI, const OF: u8> $writer<'a, U, REG, FI, OF>
417        where
418            REG: Writable + RegisterSpec<Ux = U>,
419            FI: Into<bool>,
420        {
421            /// Field width
422            pub const WIDTH: u8 = 1;
423            /// Field offset
424            pub const OFFSET: u8 = OF;
425        }
426    }
427}
428
429macro_rules! impl_bit_proxy {
430    ($writer:ident, $U:ty) => {
431        impl<'a, REG, FI, const OF: u8> $writer<'a, $U, REG, FI, OF>
432        where
433            REG: Writable + RegisterSpec<Ux = $U>,
434            FI: Into<bool>,
435        {
436            /// Writes bit to the field
437            #[inline(always)]
438            pub fn bit(self, value: bool) -> &'a mut REG::Writer {
439                self.w.bits = (self.w.bits & !(1 << { OF })) | ((<$U>::from(value) & 1) << { OF });
440                self.w
441            }
442            /// Writes `variant` to the field
443            #[inline(always)]
444            pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
445                self.bit(variant.into())
446            }
447        }
448    }
449}
450
451bit_proxy!(BitWriter, BitM);
452bit_proxy!(BitWriter1S, Bit1S);
453bit_proxy!(BitWriter0C, Bit0C);
454bit_proxy!(BitWriter1C, Bit1C);
455bit_proxy!(BitWriter0S, Bit0S);
456bit_proxy!(BitWriter1T, Bit1T);
457bit_proxy!(BitWriter0T, Bit0T);
458
459macro_rules! impl_proxy {
460    ($U:ty) => {
461        impl<'a, REG, N, FI, const WI: u8, const OF: u8> FieldWriter<'a, $U, REG, N, FI, WI, OF>
462        where
463            REG: Writable + RegisterSpec<Ux = $U>,
464            N: Into<$U>,
465            FI: Into<N>,
466        {
467            const MASK: $U = <$U>::MAX >> (<$U>::MAX.leading_ones() as u8 - { WI });
468            /// Writes raw bits to the field
469            ///
470            /// # Safety
471            ///
472            /// Passing incorrect value can cause undefined behaviour. See reference manual
473            #[inline(always)]
474            pub unsafe fn bits(self, value: N) -> &'a mut REG::Writer {
475                self.w.bits =
476                    (self.w.bits & !(Self::MASK << { OF })) | ((value.into() & Self::MASK) << { OF });
477                self.w
478            }
479            /// Writes `variant` to the field
480            #[inline(always)]
481            pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
482                unsafe { self.bits(variant.into()) }
483            }
484        }
485        impl<'a, REG, N, FI, const WI: u8, const OF: u8> FieldWriterSafe<'a, $U, REG, N, FI, WI, OF>
486        where
487            REG: Writable + RegisterSpec<Ux = $U>,
488            N: Into<$U>,
489            FI: Into<N>,
490        {
491            const MASK: $U = <$U>::MAX >> (<$U>::MAX.leading_ones() as u8 - { WI });
492            /// Writes raw bits to the field
493            #[inline(always)]
494            pub fn bits(self, value: N) -> &'a mut REG::Writer {
495                self.w.bits =
496                    (self.w.bits & !(Self::MASK << { OF })) | ((value.into() & Self::MASK) << { OF });
497                self.w
498            }
499            /// Writes `variant` to the field
500            #[inline(always)]
501            pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
502                self.bits(variant.into())
503            }
504        }
505        impl_bit_proxy!(BitWriter, $U);
506        impl_bit_proxy!(BitWriter1S, $U);
507        impl_bit_proxy!(BitWriter0C, $U);
508        impl_bit_proxy!(BitWriter1C, $U);
509        impl_bit_proxy!(BitWriter0S, $U);
510        impl_bit_proxy!(BitWriter1T, $U);
511        impl_bit_proxy!(BitWriter0T, $U);
512        impl<'a, REG, FI, const OF: u8> BitWriter<'a, $U, REG, FI, OF>
513        where
514            REG: Writable + RegisterSpec<Ux = $U>,
515            FI: Into<bool>,
516        {
517            /// Sets the field bit
518            #[inline(always)]
519            pub fn set_bit(self) -> &'a mut REG::Writer {
520                self.bit(true)
521            }
522            /// Clears the field bit
523            #[inline(always)]
524            pub fn clear_bit(self) -> &'a mut REG::Writer {
525                self.bit(false)
526            }
527        }
528        impl<'a, REG, FI, const OF: u8> BitWriter1S<'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        }
539        impl<'a, REG, FI, const OF: u8> BitWriter0C<'a, $U, REG, FI, OF>
540        where
541            REG: Writable + RegisterSpec<Ux = $U>,
542            FI: Into<bool>,
543        {
544            /// Clears the field bit
545            #[inline(always)]
546            pub fn clear_bit(self) -> &'a mut REG::Writer {
547                self.bit(false)
548            }
549        }
550        impl<'a, REG, FI, const OF: u8> BitWriter1C<'a, $U, REG, FI, OF>
551        where
552            REG: Writable + RegisterSpec<Ux = $U>,
553            FI: Into<bool>,
554        {
555            ///Clears the field bit by passing one
556            #[inline(always)]
557            pub fn clear_bit_by_one(self) -> &'a mut REG::Writer {
558                self.bit(true)
559            }
560        }
561        impl<'a, REG, FI, const OF: u8> BitWriter0S<'a, $U, REG, FI, OF>
562        where
563            REG: Writable + RegisterSpec<Ux = $U>,
564            FI: Into<bool>,
565        {
566            ///Sets the field bit by passing zero
567            #[inline(always)]
568            pub fn set_bit_by_zero(self) -> &'a mut REG::Writer {
569                self.bit(false)
570            }
571        }
572        impl<'a, REG, FI, const OF: u8> BitWriter1T<'a, $U, REG, FI, OF>
573        where
574            REG: Writable + RegisterSpec<Ux = $U>,
575            FI: Into<bool>,
576        {
577            ///Toggle the field bit by passing one
578            #[inline(always)]
579            pub fn toggle_bit(self) -> &'a mut REG::Writer {
580                self.bit(true)
581            }
582        }
583        impl<'a, REG, FI, const OF: u8> BitWriter0T<'a, $U, REG, FI, OF>
584        where
585            REG: Writable + RegisterSpec<Ux = $U>,
586            FI: Into<bool>,
587        {
588            ///Toggle the field bit by passing zero
589            #[inline(always)]
590            pub fn toggle_bit(self) -> &'a mut REG::Writer {
591                self.bit(false)
592            }
593        }
594    }
595}
596
597impl_proxy!(u8);
598impl_proxy!(u16);
599impl_proxy!(u32);