Skip to main content

mcan/reg/
generic.rs

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