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#[doc(hidden)]
99pub mod raw {
100 use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
101
102 pub struct R<REG: RegisterSpec> {
103 pub(crate) bits: REG::Ux,
104 pub(super) _reg: marker::PhantomData<REG>,
105 }
106
107 pub struct W<REG: RegisterSpec> {
108 pub(crate) bits: REG::Ux,
110 pub(super) _reg: marker::PhantomData<REG>,
111 }
112
113 pub struct FieldReader<FI = u8>
114 where
115 FI: FieldSpec,
116 {
117 pub(crate) bits: FI::Ux,
118 _reg: marker::PhantomData<FI>,
119 }
120
121 impl<FI: FieldSpec> FieldReader<FI> {
122 #[allow(unused)]
124 #[inline(always)]
125 pub(crate) const fn new(bits: FI::Ux) -> Self {
126 Self {
127 bits,
128 _reg: marker::PhantomData,
129 }
130 }
131 }
132
133 pub struct BitReader<FI = bool> {
134 pub(crate) bits: bool,
135 _reg: marker::PhantomData<FI>,
136 }
137
138 impl<FI> BitReader<FI> {
139 #[allow(unused)]
141 #[inline(always)]
142 pub(crate) const fn new(bits: bool) -> Self {
143 Self {
144 bits,
145 _reg: marker::PhantomData,
146 }
147 }
148 }
149
150 #[must_use = "after creating `FieldWriter` you need to call field value setting method"]
151 pub struct FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe>
152 where
153 REG: Writable + RegisterSpec,
154 FI: FieldSpec,
155 {
156 pub(crate) w: &'a mut W<REG>,
157 pub(crate) o: u8,
158 _field: marker::PhantomData<(FI, Safety)>,
159 }
160
161 impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
162 where
163 REG: Writable + RegisterSpec,
164 FI: FieldSpec,
165 {
166 #[allow(unused)]
168 #[inline(always)]
169 pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
170 Self {
171 w,
172 o,
173 _field: marker::PhantomData,
174 }
175 }
176 }
177
178 #[must_use = "after creating `BitWriter` you need to call bit setting method"]
179 pub struct BitWriter<'a, REG, FI = bool, M = BitM>
180 where
181 REG: Writable + RegisterSpec,
182 bool: From<FI>,
183 {
184 pub(crate) w: &'a mut W<REG>,
185 pub(crate) o: u8,
186 _field: marker::PhantomData<(FI, M)>,
187 }
188
189 impl<'a, REG, FI, M> BitWriter<'a, REG, FI, M>
190 where
191 REG: Writable + RegisterSpec,
192 bool: From<FI>,
193 {
194 #[allow(unused)]
196 #[inline(always)]
197 pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
198 Self {
199 w,
200 o,
201 _field: marker::PhantomData,
202 }
203 }
204 }
205}
206
207pub type R<REG> = raw::R<REG>;
212
213impl<REG: RegisterSpec> R<REG> {
214 #[inline(always)]
216 pub const fn bits(&self) -> REG::Ux {
217 self.bits
218 }
219}
220
221impl<REG: RegisterSpec, FI> PartialEq<FI> for R<REG>
222where
223 REG::Ux: PartialEq,
224 FI: Copy,
225 REG::Ux: From<FI>,
226{
227 #[inline(always)]
228 fn eq(&self, other: &FI) -> bool {
229 self.bits.eq(®::Ux::from(*other))
230 }
231}
232
233pub type W<REG> = raw::W<REG>;
237
238impl<REG: Writable> W<REG> {
239 #[inline(always)]
245 pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {
246 self.bits = bits;
247 self
248 }
249}
250impl<REG> W<REG> where REG: Writable<Safety = Safe> {
251 #[inline(always)]
253 pub fn set(&mut self, bits: REG::Ux) -> &mut Self {
254 self.bits = bits;
255 self
256 }
257}
258
259pub type FieldReader<FI = u8> = raw::FieldReader<FI>;
263
264pub type BitReader<FI = bool> = raw::BitReader<FI>;
266
267impl<FI: FieldSpec> FieldReader<FI> {
268 #[inline(always)]
270 pub const fn bits(&self) -> FI::Ux {
271 self.bits
272 }
273}
274
275impl<FI: FieldSpec> core::fmt::Debug for FieldReader<FI> {
276 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
277 core::fmt::Debug::fmt(&self.bits, f)
278 }
279}
280
281impl<FI> PartialEq<FI> for FieldReader<FI>
282where
283 FI: FieldSpec + Copy,
284{
285 #[inline(always)]
286 fn eq(&self, other: &FI) -> bool {
287 self.bits.eq(&FI::Ux::from(*other))
288 }
289}
290
291impl<FI> PartialEq<FI> for BitReader<FI>
292where
293 FI: Copy,
294 bool: From<FI>,
295{
296 #[inline(always)]
297 fn eq(&self, other: &FI) -> bool {
298 self.bits.eq(&bool::from(*other))
299 }
300}
301
302impl<FI> BitReader<FI> {
303 #[inline(always)]
305 pub const fn bit(&self) -> bool {
306 self.bits
307 }
308 #[inline(always)]
310 pub const fn bit_is_clear(&self) -> bool {
311 !self.bit()
312 }
313 #[inline(always)]
315 pub const fn bit_is_set(&self) -> bool {
316 self.bit()
317 }
318}
319
320impl<FI> core::fmt::Debug for BitReader<FI> {
321 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
322 core::fmt::Debug::fmt(&self.bits, f)
323 }
324}
325
326pub struct Safe;
328pub struct Unsafe;
330pub struct Range<const MIN: u64, const MAX: u64>;
332pub struct RangeFrom<const MIN: u64>;
334pub struct RangeTo<const MAX: u64>;
336
337pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> = raw::FieldWriter<'a, REG, WI, FI, Safety>;
339
340impl<REG, const WI: u8, FI, Safety> FieldWriter<'_, REG, WI, FI, Safety>
341where
342 REG: Writable + RegisterSpec,
343 FI: FieldSpec,
344{
345 pub const WIDTH: u8 = WI;
347
348 #[inline(always)]
350 pub const fn width(&self) -> u8 {
351 WI
352 }
353
354 #[inline(always)]
356 pub const fn offset(&self) -> u8 {
357 self.o
358 }
359}
360
361impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
362where
363 REG: Writable + RegisterSpec,
364 FI: FieldSpec,
365 REG::Ux: From<FI::Ux>,
366{
367 #[inline(always)]
373 pub unsafe fn bits(self, value: FI::Ux) -> &'a mut W<REG> {
374 self.w.bits &= !(REG::Ux::mask::<WI>() << self.o);
375 self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << self.o;
376 self.w
377 }
378}
379
380impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI, Safe>
381where
382 REG: Writable + RegisterSpec,
383 FI: FieldSpec,
384 REG::Ux: From<FI::Ux>,
385{
386 #[inline(always)]
388 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
389 unsafe { self.bits(value) }
390 }
391}
392
393impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64> FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
394where
395 REG: Writable + RegisterSpec,
396 FI: FieldSpec,
397 REG::Ux: From<FI::Ux>,
398 u64: From<FI::Ux>,
399{
400 #[inline(always)]
402 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
403 {
404 let value = u64::from(value);
405 assert!(value >= MIN && value <= MAX);
406 }
407 unsafe { self.bits(value) }
408 }
409}
410
411impl<'a, REG, const WI: u8, FI, const MIN: u64> FieldWriter<'a, REG, WI, FI, RangeFrom<MIN>>
412where
413 REG: Writable + RegisterSpec,
414 FI: FieldSpec,
415 REG::Ux: From<FI::Ux>,
416 u64: From<FI::Ux>,
417{
418 #[inline(always)]
420 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
421 {
422 let value = u64::from(value);
423 assert!(value >= MIN);
424 }
425 unsafe { self.bits(value) }
426 }
427}
428
429impl<'a, REG, const WI: u8, FI, const MAX: u64> FieldWriter<'a, REG, WI, FI, RangeTo<MAX>>
430where
431 REG: Writable + RegisterSpec,
432 FI: FieldSpec,
433 REG::Ux: From<FI::Ux>,
434 u64: From<FI::Ux>,
435{
436 #[inline(always)]
438 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
439 {
440 let value = u64::from(value);
441 assert!(value <= MAX);
442 }
443 unsafe { self.bits(value) }
444 }
445}
446
447impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
448where
449 REG: Writable + RegisterSpec,
450 FI: IsEnum,
451 REG::Ux: From<FI::Ux>,
452{
453 #[inline(always)]
455 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
456 unsafe { self.bits(FI::Ux::from(variant)) }
457 }
458}
459
460macro_rules! bit_proxy {
461 ($writer:ident, $mwv:ident) => {
462 #[doc(hidden)]
463 pub struct $mwv;
464
465 pub type $writer<'a, REG, FI = bool> = raw::BitWriter<'a, REG, FI, $mwv>;
467
468 impl<'a, REG, FI> $writer<'a, REG, FI>
469 where
470 REG: Writable + RegisterSpec,
471 bool: From<FI>,
472 {
473 pub const WIDTH: u8 = 1;
475
476 #[inline(always)]
478 pub const fn width(&self) -> u8 {
479 Self::WIDTH
480 }
481
482 #[inline(always)]
484 pub const fn offset(&self) -> u8 {
485 self.o
486 }
487
488 #[inline(always)]
490 pub fn bit(self, value: bool) -> &'a mut W<REG> {
491 self.w.bits &= !(REG::Ux::one() << self.o);
492 self.w.bits |= (REG::Ux::from(value) & REG::Ux::one()) << self.o;
493 self.w
494 }
495 #[inline(always)]
497 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
498 self.bit(bool::from(variant))
499 }
500 }
501 };
502}
503
504bit_proxy!(BitWriter, BitM);
505bit_proxy!(BitWriter1S, Bit1S);
506bit_proxy!(BitWriter0C, Bit0C);
507bit_proxy!(BitWriter1C, Bit1C);
508bit_proxy!(BitWriter0S, Bit0S);
509bit_proxy!(BitWriter1T, Bit1T);
510bit_proxy!(BitWriter0T, Bit0T);
511
512impl<'a, REG, FI> BitWriter<'a, REG, FI>
513where
514 REG: Writable + RegisterSpec,
515 bool: From<FI>,
516{
517 #[inline(always)]
519 pub fn set_bit(self) -> &'a mut W<REG> {
520 self.w.bits |= REG::Ux::one() << self.o;
521 self.w
522 }
523 #[inline(always)]
525 pub fn clear_bit(self) -> &'a mut W<REG> {
526 self.w.bits &= !(REG::Ux::one() << self.o);
527 self.w
528 }
529}
530
531impl<'a, REG, FI> BitWriter1S<'a, REG, FI>
532where
533 REG: Writable + RegisterSpec,
534 bool: From<FI>,
535{
536 #[inline(always)]
538 pub fn set_bit(self) -> &'a mut W<REG> {
539 self.w.bits |= REG::Ux::one() << self.o;
540 self.w
541 }
542}
543
544impl<'a, REG, FI> BitWriter0C<'a, REG, FI>
545where
546 REG: Writable + RegisterSpec,
547 bool: From<FI>,
548{
549 #[inline(always)]
551 pub fn clear_bit(self) -> &'a mut W<REG> {
552 self.w.bits &= !(REG::Ux::one() << self.o);
553 self.w
554 }
555}
556
557impl<'a, REG, FI> BitWriter1C<'a, REG, FI>
558where
559 REG: Writable + RegisterSpec,
560 bool: From<FI>,
561{
562 #[inline(always)]
564 pub fn clear_bit_by_one(self) -> &'a mut W<REG> {
565 self.w.bits |= REG::Ux::one() << self.o;
566 self.w
567 }
568}
569
570impl<'a, REG, FI> BitWriter0S<'a, REG, FI>
571where
572 REG: Writable + RegisterSpec,
573 bool: From<FI>,
574{
575 #[inline(always)]
577 pub fn set_bit_by_zero(self) -> &'a mut W<REG> {
578 self.w.bits &= !(REG::Ux::one() << self.o);
579 self.w
580 }
581}
582
583impl<'a, REG, FI> BitWriter1T<'a, REG, FI>
584where
585 REG: Writable + RegisterSpec,
586 bool: From<FI>,
587{
588 #[inline(always)]
590 pub fn toggle_bit(self) -> &'a mut W<REG> {
591 self.w.bits |= REG::Ux::one() << self.o;
592 self.w
593 }
594}
595
596impl<'a, REG, FI> BitWriter0T<'a, REG, FI>
597where
598 REG: Writable + RegisterSpec,
599 bool: From<FI>,
600{
601 #[inline(always)]
603 pub fn toggle_bit(self) -> &'a mut W<REG> {
604 self.w.bits &= !(REG::Ux::one() << self.o);
605 self.w
606 }
607}
608
609#[repr(transparent)]
611pub struct Reg<REG: RegisterSpec> {
612 register: vcell::VolatileCell<REG::Ux>,
613 _marker: marker::PhantomData<REG>,
614}
615
616unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
617
618impl<REG: RegisterSpec> Reg<REG> {
619 #[inline(always)]
625 pub fn as_ptr(&self) -> *mut REG::Ux {
626 self.register.as_ptr()
627 }
628}
629
630impl<REG: Readable> Reg<REG> {
631 #[inline(always)]
644 pub fn read(&self) -> R<REG> {
645 R {
646 bits: self.register.get(),
647 _reg: marker::PhantomData,
648 }
649 }
650}
651
652impl<REG: Resettable + Writable> Reg<REG> {
653 #[inline(always)]
657 pub fn reset(&self) {
658 self.register.set(REG::RESET_VALUE)
659 }
660
661 #[inline(always)]
685 pub fn write<F>(&self, f: F) -> REG::Ux
686 where
687 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
688 {
689 let value = f(&mut W {
690 bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
691 | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
692 _reg: marker::PhantomData,
693 })
694 .bits;
695 self.register.set(value);
696 value
697 }
698
699 #[inline(always)]
728 pub fn from_write<F, T>(&self, f: F) -> T
729 where
730 F: FnOnce(&mut W<REG>) -> T,
731 {
732 let mut writer = W {
733 bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
734 | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
735 _reg: marker::PhantomData,
736 };
737 let result = f(&mut writer);
738
739 self.register.set(writer.bits);
740
741 result
742 }
743}
744
745impl<REG: Writable> Reg<REG> {
746 #[inline(always)]
754 pub unsafe fn write_with_zero<F>(&self, f: F) -> REG::Ux
755 where
756 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
757 {
758 let value = f(&mut W {
759 bits: REG::Ux::default(),
760 _reg: marker::PhantomData,
761 })
762 .bits;
763 self.register.set(value);
764 value
765 }
766
767 #[inline(always)]
775 pub unsafe fn from_write_with_zero<F, T>(&self, f: F) -> T
776 where
777 F: FnOnce(&mut W<REG>) -> T,
778 {
779 let mut writer = W {
780 bits: REG::Ux::default(),
781 _reg: marker::PhantomData,
782 };
783
784 let result = f(&mut writer);
785
786 self.register.set(writer.bits);
787
788 result
789 }
790}
791
792impl<REG: Readable + Writable> Reg<REG> {
793 #[inline(always)]
819 pub fn modify<F>(&self, f: F) -> REG::Ux
820 where
821 for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
822 {
823 let bits = self.register.get();
824 let value = f(
825 &R {
826 bits,
827 _reg: marker::PhantomData,
828 },
829 &mut W {
830 bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
831 _reg: marker::PhantomData,
832 },
833 )
834 .bits;
835 self.register.set(value);
836 value
837 }
838
839 #[inline(always)]
871 pub fn from_modify<F, T>(&self, f: F) -> T
872 where
873 for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> T,
874 {
875 let bits = self.register.get();
876
877 let mut writer = W {
878 bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
879 _reg: marker::PhantomData,
880 };
881
882 let result = f(
883 &R {
884 bits,
885 _reg: marker::PhantomData,
886 },
887 &mut writer,
888 );
889
890 self.register.set(writer.bits);
891
892 result
893 }
894}
895
896impl<REG: Readable> core::fmt::Debug for crate::generic::Reg<REG>
897where
898 R<REG>: core::fmt::Debug,
899{
900 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
901 core::fmt::Debug::fmt(&self.read(), f)
902 }
903}
904
905#[cfg(feature = "atomics")]
906
907mod atomic {
908 use super::*;
909 use portable_atomic::Ordering;
910
911 pub trait AtomicOperations {
912 unsafe fn atomic_or(ptr: *mut Self, val: Self);
913 unsafe fn atomic_and(ptr: *mut Self, val: Self);
914 unsafe fn atomic_xor(ptr: *mut Self, val: Self);
915 }
916
917 macro_rules! impl_atomics {
918 ($U:ty, $Atomic:ty) => {
919 impl AtomicOperations for $U {
920 unsafe fn atomic_or(ptr: *mut Self, val: Self) {
921 (*(ptr as *const $Atomic)).or(val, Ordering::SeqCst);
922 }
923
924 unsafe fn atomic_and(ptr: *mut Self, val: Self) {
925 (*(ptr as *const $Atomic)).and(val, Ordering::SeqCst);
926 }
927
928 unsafe fn atomic_xor(ptr: *mut Self, val: Self) {
929 (*(ptr as *const $Atomic)).xor(val, Ordering::SeqCst);
930 }
931 }
932 };
933 }
934
935 impl_atomics!(u8, portable_atomic::AtomicU8);
936 impl_atomics!(u16, portable_atomic::AtomicU16);
937
938 #[cfg(not(target_pointer_width = "16"))]
940 impl_atomics!(u32, portable_atomic::AtomicU32);
941
942 #[cfg(any(target_pointer_width = "64", target_has_atomic = "64"))]
944 impl_atomics!(u64, portable_atomic::AtomicU64);
945
946 impl<REG: Readable + Writable> Reg<REG>
947 where
948 REG::Ux: AtomicOperations
949 {
950 #[inline(always)]
957 pub unsafe fn set_bits<F>(&self, f: F)
958 where
959 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
960 {
961 let bits = f(&mut W {
962 bits: Default::default(),
963 _reg: marker::PhantomData,
964 })
965 .bits;
966 REG::Ux::atomic_or(self.register.as_ptr(), bits);
967 }
968
969 #[inline(always)]
976 pub unsafe fn clear_bits<F>(&self, f: F)
977 where
978 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
979 {
980 let bits = f(&mut W {
981 bits: !REG::Ux::default(),
982 _reg: marker::PhantomData,
983 })
984 .bits;
985 REG::Ux::atomic_and(self.register.as_ptr(), bits);
986 }
987
988 #[inline(always)]
995 pub unsafe fn toggle_bits<F>(&self, f: F)
996 where
997 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
998 {
999 let bits = f(&mut W {
1000 bits: Default::default(),
1001 _reg: marker::PhantomData,
1002 })
1003 .bits;
1004 REG::Ux::atomic_xor(self.register.as_ptr(), bits);
1005 }
1006 }
1007}
1008