stm32wb_stm32hal/
generic.rs

1use core::marker;
2
3///This trait shows that register has `read` method
4///
5///Registers marked with `Writable` can be also `modify`'ed
6pub trait Readable {}
7
8///This trait shows that register has `write`, `write_with_zero` and `reset` method
9///
10///Registers marked with `Readable` can be also `modify`'ed
11pub trait Writable {}
12
13///Reset value of the register
14///
15///This value is initial value for `write` method.
16///It can be also directly writed to register by `reset` method.
17pub trait ResetValue {
18    ///Register size
19    type Type;
20    ///Reset value of the register
21    fn reset_value() -> Self::Type;
22}
23
24///This structure provides volatile access to register
25pub struct Reg<U, REG> {
26    register: vcell::VolatileCell<U>,
27    _marker: marker::PhantomData<REG>,
28}
29
30unsafe impl<U: Send, REG> Send for Reg<U, REG> { }
31
32impl<U, REG> Reg<U, REG>
33where
34    Self: Readable,
35    U: Copy
36{
37    ///Reads the contents of `Readable` register
38    ///
39    ///You can read the contents of a register in such way:
40    ///```ignore
41    ///let bits = periph.reg.read().bits();
42    ///```
43    ///or get the content of a particular field of a register.
44    ///```ignore
45    ///let reader = periph.reg.read();
46    ///let bits = reader.field1().bits();
47    ///let flag = reader.field2().bit_is_set();
48    ///```
49    #[inline(always)]
50    pub fn read(&self) -> R<U, Self> {
51        R {bits: self.register.get(), _reg: marker::PhantomData}
52    }
53}
54
55impl<U, REG> Reg<U, REG>
56where
57    Self: ResetValue<Type=U> + Writable,
58    U: Copy,
59{
60    ///Writes the reset value to `Writable` register
61    ///
62    ///Resets the register to its initial state
63    #[inline(always)]
64    pub fn reset(&self) {
65        self.register.set(Self::reset_value())
66    }
67}
68
69impl<U, REG> Reg<U, REG>
70where
71    Self: ResetValue<Type=U> + Writable,
72    U: Copy
73{
74    ///Writes bits to `Writable` register
75    ///
76    ///You can write raw bits into a register:
77    ///```ignore
78    ///periph.reg.write(|w| unsafe { w.bits(rawbits) });
79    ///```
80    ///or write only the fields you need:
81    ///```ignore
82    ///periph.reg.write(|w| w
83    ///    .field1().bits(newfield1bits)
84    ///    .field2().set_bit()
85    ///    .field3().variant(VARIANT)
86    ///);
87    ///```
88    ///Other fields will have reset value.
89    #[inline(always)]
90    pub fn write<F>(&self, f: F)
91    where
92        F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
93    {
94        self.register.set(f(&mut W {bits: Self::reset_value(), _reg: marker::PhantomData}).bits);
95    }
96}
97
98impl<U, REG> Reg<U, REG>
99where
100    Self: Writable,
101    U: Copy + Default
102{
103    ///Writes Zero to `Writable` register
104    ///
105    ///Similar to `write`, but unused bits will contain 0.
106    #[inline(always)]
107    pub fn write_with_zero<F>(&self, f: F)
108    where
109        F: FnOnce(&mut W<U, Self>) -> &mut W<U, Self>
110    {
111        self.register.set(f(&mut W {bits: U::default(), _reg: marker::PhantomData }).bits);
112    }
113}
114
115impl<U, REG> Reg<U, REG>
116where
117    Self: Readable + Writable,
118    U: Copy,
119{
120    ///Modifies the contents of the register
121    ///
122    ///E.g. to do a read-modify-write sequence to change parts of a register:
123    ///```ignore
124    ///periph.reg.modify(|r, w| unsafe { w.bits(
125    ///   r.bits() | 3
126    ///) });
127    ///```
128    ///or
129    ///```ignore
130    ///periph.reg.modify(|_, w| w
131    ///    .field1().bits(newfield1bits)
132    ///    .field2().set_bit()
133    ///    .field3().variant(VARIANT)
134    ///);
135    ///```
136    ///Other fields will have value they had before call `modify`.
137    #[inline(always)]
138    pub fn modify<F>(&self, f: F)
139    where
140        for<'w> F: FnOnce(&R<U, Self>, &'w mut W<U, Self>) -> &'w mut W<U, Self>
141    {
142        let bits = self.register.get();
143        self.register.set(f(&R {bits, _reg: marker::PhantomData}, &mut W {bits, _reg: marker::PhantomData}).bits);
144    }
145}
146
147///Register/field reader
148///
149///Result of the [`read`](Reg::read) method of a register.
150///Also it can be used in the [`modify`](Reg::read) method
151pub struct R<U, T> {
152    pub(crate) bits: U,
153    _reg: marker::PhantomData<T>,
154}
155
156impl<U, T> R<U, T>
157where
158    U: Copy
159{
160    ///Create new instance of reader
161    #[inline(always)]
162    pub(crate) fn new(bits: U) -> Self {
163        Self {
164            bits,
165            _reg: marker::PhantomData,
166        }
167    }
168    ///Read raw bits from register/field
169    #[inline(always)]
170    pub fn bits(&self) -> U {
171        self.bits
172    }
173}
174
175impl<U, T, FI> PartialEq<FI> for R<U, T>
176where
177    U: PartialEq,
178    FI: Copy+Into<U>
179{
180    #[inline(always)]
181    fn eq(&self, other: &FI) -> bool {
182        self.bits.eq(&(*other).into())
183    }
184}
185
186impl<FI> R<bool, FI> {
187    ///Value of the field as raw bits
188    #[inline(always)]
189    pub fn bit(&self) -> bool {
190        self.bits
191    }
192    ///Returns `true` if the bit is clear (0)
193    #[inline(always)]
194    pub fn bit_is_clear(&self) -> bool {
195        !self.bit()
196    }
197    ///Returns `true` if the bit is set (1)
198    #[inline(always)]
199    pub fn bit_is_set(&self) -> bool {
200        self.bit()
201    }
202}
203
204///Register writer
205///
206///Used as an argument to the closures in the [`write`](Reg::write) and [`modify`](Reg::modify) methods of the register
207pub struct W<U, REG> {
208    ///Writable bits
209    pub(crate) bits: U,
210    _reg: marker::PhantomData<REG>,
211}
212
213impl<U, REG> W<U, REG> {
214    ///Writes raw bits to the register
215    #[inline(always)]
216    pub unsafe fn bits(&mut self, bits: U) -> &mut Self {
217        self.bits = bits;
218        self
219    }
220}
221
222///Used if enumerated values cover not the whole range
223#[derive(Clone,Copy,PartialEq)]
224pub enum Variant<U, T> {
225    ///Expected variant
226    Val(T),
227    ///Raw bits
228    Res(U),
229}
230