1use core::marker;
2
3pub 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 fn mask<const WI: u8>() -> Self;
17 fn one() -> Self;
19}
20
21macro_rules! raw_reg {
22 ($U:ty, $size:literal, $mask:ident) => {
23 impl RawReg for $U {
24 #[inline(always)]
25 fn mask<const WI: u8>() -> Self {
26 $mask::<WI>()
27 }
28 #[inline(always)]
29 fn one() -> Self {
30 1
31 }
32 }
33 const fn $mask<const WI: u8>() -> $U {
34 <$U>::MAX >> ($size - WI)
35 }
36 impl FieldSpec for $U {
37 type Ux = $U;
38 }
39 };
40}
41
42raw_reg!(u8, 8, mask_u8);
43raw_reg!(u16, 16, mask_u16);
44raw_reg!(u32, 32, mask_u32);
45raw_reg!(u64, 64, mask_u64);
46
47pub trait RegisterSpec {
49 type Ux: RawReg;
51}
52
53pub trait FieldSpec: Sized {
55 type Ux: Copy + core::fmt::Debug + PartialEq + From<Self>;
57}
58
59pub trait IsEnum: FieldSpec {}
61
62pub trait Readable: RegisterSpec {}
66
67pub trait Writable: RegisterSpec {
73 type Safety;
75
76 const ZERO_TO_MODIFY_FIELDS_BITMAP: Self::Ux;
78
79 const ONE_TO_MODIFY_FIELDS_BITMAP: Self::Ux;
81}
82
83pub trait Resettable: RegisterSpec {
88 const RESET_VALUE: Self::Ux;
90
91 #[inline(always)]
93 fn reset_value() -> Self::Ux {
94 Self::RESET_VALUE
95 }
96}
97
98#[repr(transparent)]
100pub struct Reg<REG: RegisterSpec> {
101 register: vcell::VolatileCell<REG::Ux>,
102 _marker: marker::PhantomData<REG>,
103}
104
105unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
106
107impl<REG: RegisterSpec> Reg<REG> {
108 #[inline(always)]
114 pub fn as_ptr(&self) -> *mut REG::Ux {
115 self.register.as_ptr()
116 }
117}
118
119impl<REG: Readable> Reg<REG> {
120 #[inline(always)]
133 pub fn read(&self) -> R<REG> {
134 R {
135 bits: self.register.get(),
136 _reg: marker::PhantomData,
137 }
138 }
139}
140
141impl<REG: Resettable + Writable> Reg<REG> {
142 #[inline(always)]
146 pub fn reset(&self) {
147 self.register.set(REG::RESET_VALUE)
148 }
149
150 #[inline(always)]
174 pub fn write<F>(&self, f: F)
175 where
176 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
177 {
178 self.register.set(
179 f(&mut W {
180 bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
181 | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
182 _reg: marker::PhantomData,
183 })
184 .bits,
185 );
186 }
187}
188
189impl<REG: Writable> Reg<REG> {
190 #[inline(always)]
198 pub unsafe fn write_with_zero<F>(&self, f: F)
199 where
200 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
201 {
202 self.register.set(
203 f(&mut W {
204 bits: REG::Ux::default(),
205 _reg: marker::PhantomData,
206 })
207 .bits,
208 );
209 }
210}
211
212impl<REG: Readable + Writable> Reg<REG> {
213 #[inline(always)]
239 pub fn modify<F>(&self, f: F)
240 where
241 for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
242 {
243 let bits = self.register.get();
244 self.register.set(
245 f(
246 &R {
247 bits,
248 _reg: marker::PhantomData,
249 },
250 &mut W {
251 bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
252 | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
253 _reg: marker::PhantomData,
254 },
255 )
256 .bits,
257 );
258 }
259}
260
261impl<REG: Readable> core::fmt::Debug for crate::generic::Reg<REG>
262where
263 R<REG>: core::fmt::Debug,
264{
265 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
266 core::fmt::Debug::fmt(&self.read(), f)
267 }
268}
269
270#[doc(hidden)]
271pub mod raw {
272 use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
273
274 pub struct R<REG: RegisterSpec> {
275 pub(crate) bits: REG::Ux,
276 pub(super) _reg: marker::PhantomData<REG>,
277 }
278
279 pub struct W<REG: RegisterSpec> {
280 pub(crate) bits: REG::Ux,
282 pub(super) _reg: marker::PhantomData<REG>,
283 }
284
285 pub struct FieldReader<FI = u8>
286 where
287 FI: FieldSpec,
288 {
289 pub(crate) bits: FI::Ux,
290 _reg: marker::PhantomData<FI>,
291 }
292
293 impl<FI: FieldSpec> FieldReader<FI> {
294 #[allow(unused)]
296 #[inline(always)]
297 pub(crate) const fn new(bits: FI::Ux) -> Self {
298 Self {
299 bits,
300 _reg: marker::PhantomData,
301 }
302 }
303 }
304
305 pub struct BitReader<FI = bool> {
306 pub(crate) bits: bool,
307 _reg: marker::PhantomData<FI>,
308 }
309
310 impl<FI> BitReader<FI> {
311 #[allow(unused)]
313 #[inline(always)]
314 pub(crate) const fn new(bits: bool) -> Self {
315 Self {
316 bits,
317 _reg: marker::PhantomData,
318 }
319 }
320 }
321
322 pub struct FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe>
323 where
324 REG: Writable + RegisterSpec,
325 FI: FieldSpec,
326 {
327 pub(crate) w: &'a mut W<REG>,
328 pub(crate) o: u8,
329 _field: marker::PhantomData<(FI, Safety)>,
330 }
331
332 impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
333 where
334 REG: Writable + RegisterSpec,
335 FI: FieldSpec,
336 {
337 #[allow(unused)]
339 #[inline(always)]
340 pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
341 Self {
342 w,
343 o,
344 _field: marker::PhantomData,
345 }
346 }
347 }
348
349 pub struct BitWriter<'a, REG, FI = bool, M = BitM>
350 where
351 REG: Writable + RegisterSpec,
352 bool: From<FI>,
353 {
354 pub(crate) w: &'a mut W<REG>,
355 pub(crate) o: u8,
356 _field: marker::PhantomData<(FI, M)>,
357 }
358
359 impl<'a, REG, FI, M> BitWriter<'a, REG, FI, M>
360 where
361 REG: Writable + RegisterSpec,
362 bool: From<FI>,
363 {
364 #[allow(unused)]
366 #[inline(always)]
367 pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
368 Self {
369 w,
370 o,
371 _field: marker::PhantomData,
372 }
373 }
374 }
375}
376
377pub type R<REG> = raw::R<REG>;
382
383impl<REG: RegisterSpec> R<REG> {
384 #[inline(always)]
386 pub const fn bits(&self) -> REG::Ux {
387 self.bits
388 }
389}
390
391impl<REG: RegisterSpec, FI> PartialEq<FI> for R<REG>
392where
393 REG::Ux: PartialEq,
394 FI: Copy,
395 REG::Ux: From<FI>,
396{
397 #[inline(always)]
398 fn eq(&self, other: &FI) -> bool {
399 self.bits.eq(®::Ux::from(*other))
400 }
401}
402
403pub type W<REG> = raw::W<REG>;
407
408impl<REG: Writable> W<REG> {
409 #[inline(always)]
415 pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {
416 self.bits = bits;
417 self
418 }
419}
420impl<REG> W<REG>
421where
422 REG: Writable<Safety = Safe>,
423{
424 #[inline(always)]
426 pub fn set(&mut self, bits: REG::Ux) -> &mut Self {
427 self.bits = bits;
428 self
429 }
430}
431
432pub type FieldReader<FI = u8> = raw::FieldReader<FI>;
436
437pub type BitReader<FI = bool> = raw::BitReader<FI>;
439
440impl<FI: FieldSpec> FieldReader<FI> {
441 #[inline(always)]
443 pub const fn bits(&self) -> FI::Ux {
444 self.bits
445 }
446}
447
448impl<FI: FieldSpec> core::fmt::Debug for FieldReader<FI> {
449 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
450 core::fmt::Debug::fmt(&self.bits, f)
451 }
452}
453
454impl<FI> PartialEq<FI> for FieldReader<FI>
455where
456 FI: FieldSpec + Copy,
457{
458 #[inline(always)]
459 fn eq(&self, other: &FI) -> bool {
460 self.bits.eq(&FI::Ux::from(*other))
461 }
462}
463
464impl<FI> PartialEq<FI> for BitReader<FI>
465where
466 FI: Copy,
467 bool: From<FI>,
468{
469 #[inline(always)]
470 fn eq(&self, other: &FI) -> bool {
471 self.bits.eq(&bool::from(*other))
472 }
473}
474
475impl<FI> BitReader<FI> {
476 #[inline(always)]
478 pub const fn bit(&self) -> bool {
479 self.bits
480 }
481 #[inline(always)]
483 pub const fn bit_is_clear(&self) -> bool {
484 !self.bit()
485 }
486 #[inline(always)]
488 pub const fn bit_is_set(&self) -> bool {
489 self.bit()
490 }
491}
492
493impl<FI> core::fmt::Debug for BitReader<FI> {
494 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
495 core::fmt::Debug::fmt(&self.bits, f)
496 }
497}
498
499pub struct Safe;
501pub struct Unsafe;
503pub struct Range<const MIN: u64, const MAX: u64>;
505pub struct RangeFrom<const MIN: u64>;
507pub struct RangeTo<const MAX: u64>;
509
510pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
512 raw::FieldWriter<'a, REG, WI, FI, Safety>;
513
514impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
515where
516 REG: Writable + RegisterSpec,
517 FI: FieldSpec,
518{
519 pub const WIDTH: u8 = WI;
521
522 #[inline(always)]
524 pub const fn width(&self) -> u8 {
525 WI
526 }
527
528 #[inline(always)]
530 pub const fn offset(&self) -> u8 {
531 self.o
532 }
533}
534
535impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
536where
537 REG: Writable + RegisterSpec,
538 FI: FieldSpec,
539 REG::Ux: From<FI::Ux>,
540{
541 #[inline(always)]
547 pub unsafe fn bits(self, value: FI::Ux) -> &'a mut W<REG> {
548 self.w.bits &= !(REG::Ux::mask::<WI>() << self.o);
549 self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << self.o;
550 self.w
551 }
552}
553
554impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI, Safe>
555where
556 REG: Writable + RegisterSpec,
557 FI: FieldSpec,
558 REG::Ux: From<FI::Ux>,
559{
560 #[inline(always)]
562 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
563 unsafe { self.bits(value) }
564 }
565}
566
567impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64>
568 FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
569where
570 REG: Writable + RegisterSpec,
571 FI: FieldSpec,
572 REG::Ux: From<FI::Ux>,
573 u64: From<FI::Ux>,
574{
575 #[inline(always)]
577 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
578 {
579 let value = u64::from(value);
580 assert!(value >= MIN && value <= MAX);
581 }
582 unsafe { self.bits(value) }
583 }
584}
585
586impl<'a, REG, const WI: u8, FI, const MIN: u64> FieldWriter<'a, REG, WI, FI, RangeFrom<MIN>>
587where
588 REG: Writable + RegisterSpec,
589 FI: FieldSpec,
590 REG::Ux: From<FI::Ux>,
591 u64: From<FI::Ux>,
592{
593 #[inline(always)]
595 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
596 {
597 let value = u64::from(value);
598 assert!(value >= MIN);
599 }
600 unsafe { self.bits(value) }
601 }
602}
603
604impl<'a, REG, const WI: u8, FI, const MAX: u64> FieldWriter<'a, REG, WI, FI, RangeTo<MAX>>
605where
606 REG: Writable + RegisterSpec,
607 FI: FieldSpec,
608 REG::Ux: From<FI::Ux>,
609 u64: From<FI::Ux>,
610{
611 #[inline(always)]
613 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
614 {
615 let value = u64::from(value);
616 assert!(value <= MAX);
617 }
618 unsafe { self.bits(value) }
619 }
620}
621
622impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
623where
624 REG: Writable + RegisterSpec,
625 FI: IsEnum,
626 REG::Ux: From<FI::Ux>,
627{
628 #[inline(always)]
630 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
631 unsafe { self.bits(FI::Ux::from(variant)) }
632 }
633}
634
635macro_rules! bit_proxy {
636 ($writer:ident, $mwv:ident) => {
637 #[doc(hidden)]
638 pub struct $mwv;
639
640 pub type $writer<'a, REG, FI = bool> = raw::BitWriter<'a, REG, FI, $mwv>;
642
643 impl<'a, REG, FI> $writer<'a, REG, FI>
644 where
645 REG: Writable + RegisterSpec,
646 bool: From<FI>,
647 {
648 pub const WIDTH: u8 = 1;
650
651 #[inline(always)]
653 pub const fn width(&self) -> u8 {
654 Self::WIDTH
655 }
656
657 #[inline(always)]
659 pub const fn offset(&self) -> u8 {
660 self.o
661 }
662
663 #[inline(always)]
665 pub fn bit(self, value: bool) -> &'a mut W<REG> {
666 self.w.bits &= !(REG::Ux::one() << self.o);
667 self.w.bits |= (REG::Ux::from(value) & REG::Ux::one()) << self.o;
668 self.w
669 }
670 #[inline(always)]
672 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
673 self.bit(bool::from(variant))
674 }
675 }
676 };
677}
678
679bit_proxy!(BitWriter, BitM);
680bit_proxy!(BitWriter1S, Bit1S);
681bit_proxy!(BitWriter0C, Bit0C);
682bit_proxy!(BitWriter1C, Bit1C);
683bit_proxy!(BitWriter0S, Bit0S);
684bit_proxy!(BitWriter1T, Bit1T);
685bit_proxy!(BitWriter0T, Bit0T);
686
687impl<'a, REG, FI> BitWriter<'a, REG, FI>
688where
689 REG: Writable + RegisterSpec,
690 bool: From<FI>,
691{
692 #[inline(always)]
694 pub fn set_bit(self) -> &'a mut W<REG> {
695 self.w.bits |= REG::Ux::one() << self.o;
696 self.w
697 }
698 #[inline(always)]
700 pub fn clear_bit(self) -> &'a mut W<REG> {
701 self.w.bits &= !(REG::Ux::one() << self.o);
702 self.w
703 }
704}
705
706impl<'a, REG, FI> BitWriter1S<'a, REG, FI>
707where
708 REG: Writable + RegisterSpec,
709 bool: From<FI>,
710{
711 #[inline(always)]
713 pub fn set_bit(self) -> &'a mut W<REG> {
714 self.w.bits |= REG::Ux::one() << self.o;
715 self.w
716 }
717}
718
719impl<'a, REG, FI> BitWriter0C<'a, REG, FI>
720where
721 REG: Writable + RegisterSpec,
722 bool: From<FI>,
723{
724 #[inline(always)]
726 pub fn clear_bit(self) -> &'a mut W<REG> {
727 self.w.bits &= !(REG::Ux::one() << self.o);
728 self.w
729 }
730}
731
732impl<'a, REG, FI> BitWriter1C<'a, REG, FI>
733where
734 REG: Writable + RegisterSpec,
735 bool: From<FI>,
736{
737 #[inline(always)]
739 pub fn clear_bit_by_one(self) -> &'a mut W<REG> {
740 self.w.bits |= REG::Ux::one() << self.o;
741 self.w
742 }
743}
744
745impl<'a, REG, FI> BitWriter0S<'a, REG, FI>
746where
747 REG: Writable + RegisterSpec,
748 bool: From<FI>,
749{
750 #[inline(always)]
752 pub fn set_bit_by_zero(self) -> &'a mut W<REG> {
753 self.w.bits &= !(REG::Ux::one() << self.o);
754 self.w
755 }
756}
757
758impl<'a, REG, FI> BitWriter1T<'a, REG, FI>
759where
760 REG: Writable + RegisterSpec,
761 bool: From<FI>,
762{
763 #[inline(always)]
765 pub fn toggle_bit(self) -> &'a mut W<REG> {
766 self.w.bits |= REG::Ux::one() << self.o;
767 self.w
768 }
769}
770
771impl<'a, REG, FI> BitWriter0T<'a, REG, FI>
772where
773 REG: Writable + RegisterSpec,
774 bool: From<FI>,
775{
776 #[inline(always)]
778 pub fn toggle_bit(self) -> &'a mut W<REG> {
779 self.w.bits &= !(REG::Ux::one() << self.o);
780 self.w
781 }
782}