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