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 + 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
261#[doc(hidden)]
262pub mod raw {
263 use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
264
265 pub struct R<REG: RegisterSpec> {
266 pub(crate) bits: REG::Ux,
267 pub(super) _reg: marker::PhantomData<REG>,
268 }
269
270 pub struct W<REG: RegisterSpec> {
271 pub(crate) bits: REG::Ux,
273 pub(super) _reg: marker::PhantomData<REG>,
274 }
275
276 pub struct FieldReader<FI = u8>
277 where
278 FI: FieldSpec,
279 {
280 pub(crate) bits: FI::Ux,
281 _reg: marker::PhantomData<FI>,
282 }
283
284 impl<FI: FieldSpec> FieldReader<FI> {
285 #[allow(unused)]
287 #[inline(always)]
288 pub(crate) const fn new(bits: FI::Ux) -> Self {
289 Self {
290 bits,
291 _reg: marker::PhantomData,
292 }
293 }
294 }
295
296 pub struct BitReader<FI = bool> {
297 pub(crate) bits: bool,
298 _reg: marker::PhantomData<FI>,
299 }
300
301 impl<FI> BitReader<FI> {
302 #[allow(unused)]
304 #[inline(always)]
305 pub(crate) const fn new(bits: bool) -> Self {
306 Self {
307 bits,
308 _reg: marker::PhantomData,
309 }
310 }
311 }
312
313 pub struct FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe>
314 where
315 REG: Writable + RegisterSpec,
316 FI: FieldSpec,
317 {
318 pub(crate) w: &'a mut W<REG>,
319 pub(crate) o: u8,
320 _field: marker::PhantomData<(FI, Safety)>,
321 }
322
323 impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
324 where
325 REG: Writable + RegisterSpec,
326 FI: FieldSpec,
327 {
328 #[allow(unused)]
330 #[inline(always)]
331 pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
332 Self {
333 w,
334 o,
335 _field: marker::PhantomData,
336 }
337 }
338 }
339
340 pub struct BitWriter<'a, REG, FI = bool, M = BitM>
341 where
342 REG: Writable + RegisterSpec,
343 bool: From<FI>,
344 {
345 pub(crate) w: &'a mut W<REG>,
346 pub(crate) o: u8,
347 _field: marker::PhantomData<(FI, M)>,
348 }
349
350 impl<'a, REG, FI, M> BitWriter<'a, REG, FI, M>
351 where
352 REG: Writable + RegisterSpec,
353 bool: From<FI>,
354 {
355 #[allow(unused)]
357 #[inline(always)]
358 pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
359 Self {
360 w,
361 o,
362 _field: marker::PhantomData,
363 }
364 }
365 }
366}
367
368pub type R<REG> = raw::R<REG>;
373
374impl<REG: RegisterSpec> R<REG> {
375 #[inline(always)]
377 pub const fn bits(&self) -> REG::Ux {
378 self.bits
379 }
380}
381
382impl<REG: RegisterSpec, FI> PartialEq<FI> for R<REG>
383where
384 REG::Ux: PartialEq,
385 FI: Copy,
386 REG::Ux: From<FI>,
387{
388 #[inline(always)]
389 fn eq(&self, other: &FI) -> bool {
390 self.bits.eq(®::Ux::from(*other))
391 }
392}
393
394pub type W<REG> = raw::W<REG>;
398
399impl<REG: Writable> W<REG> {
400 #[inline(always)]
406 pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {
407 self.bits = bits;
408 self
409 }
410}
411impl<REG> W<REG>
412where
413 REG: Writable<Safety = Safe>,
414{
415 #[inline(always)]
417 pub fn set(&mut self, bits: REG::Ux) -> &mut Self {
418 self.bits = bits;
419 self
420 }
421}
422
423pub type FieldReader<FI = u8> = raw::FieldReader<FI>;
427
428pub type BitReader<FI = bool> = raw::BitReader<FI>;
430
431impl<FI: FieldSpec> FieldReader<FI> {
432 #[inline(always)]
434 pub const fn bits(&self) -> FI::Ux {
435 self.bits
436 }
437}
438
439impl<FI> PartialEq<FI> for FieldReader<FI>
440where
441 FI: FieldSpec + Copy,
442{
443 #[inline(always)]
444 fn eq(&self, other: &FI) -> bool {
445 self.bits.eq(&FI::Ux::from(*other))
446 }
447}
448
449impl<FI> PartialEq<FI> for BitReader<FI>
450where
451 FI: Copy,
452 bool: From<FI>,
453{
454 #[inline(always)]
455 fn eq(&self, other: &FI) -> bool {
456 self.bits.eq(&bool::from(*other))
457 }
458}
459
460impl<FI> BitReader<FI> {
461 #[inline(always)]
463 pub const fn bit(&self) -> bool {
464 self.bits
465 }
466 #[inline(always)]
468 pub const fn bit_is_clear(&self) -> bool {
469 !self.bit()
470 }
471 #[inline(always)]
473 pub const fn bit_is_set(&self) -> bool {
474 self.bit()
475 }
476}
477
478pub struct Safe;
480pub struct Unsafe;
482
483pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
485 raw::FieldWriter<'a, REG, WI, FI, Safety>;
486
487impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
488where
489 REG: Writable + RegisterSpec,
490 FI: FieldSpec,
491{
492 pub const WIDTH: u8 = WI;
494
495 #[inline(always)]
497 pub const fn width(&self) -> u8 {
498 WI
499 }
500
501 #[inline(always)]
503 pub const fn offset(&self) -> u8 {
504 self.o
505 }
506}
507
508impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
509where
510 REG: Writable + RegisterSpec,
511 FI: FieldSpec,
512 REG::Ux: From<FI::Ux>,
513{
514 #[inline(always)]
520 pub unsafe fn bits(self, value: FI::Ux) -> &'a mut W<REG> {
521 self.w.bits &= !(REG::Ux::mask::<WI>() << self.o);
522 self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << self.o;
523 self.w
524 }
525}
526
527impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI, Safe>
528where
529 REG: Writable + RegisterSpec,
530 FI: FieldSpec,
531 REG::Ux: From<FI::Ux>,
532{
533 #[inline(always)]
535 pub fn set(self, value: FI::Ux) -> &'a mut W<REG> {
536 unsafe { self.bits(value) }
537 }
538}
539
540impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
541where
542 REG: Writable + RegisterSpec,
543 FI: IsEnum,
544 REG::Ux: From<FI::Ux>,
545{
546 #[inline(always)]
548 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
549 unsafe { self.bits(FI::Ux::from(variant)) }
550 }
551}
552
553macro_rules! bit_proxy {
554 ($writer:ident, $mwv:ident) => {
555 #[doc(hidden)]
556 pub struct $mwv;
557
558 pub type $writer<'a, REG, FI = bool> = raw::BitWriter<'a, REG, FI, $mwv>;
560
561 impl<'a, REG, FI> $writer<'a, REG, FI>
562 where
563 REG: Writable + RegisterSpec,
564 bool: From<FI>,
565 {
566 pub const WIDTH: u8 = 1;
568
569 #[inline(always)]
571 pub const fn width(&self) -> u8 {
572 Self::WIDTH
573 }
574
575 #[inline(always)]
577 pub const fn offset(&self) -> u8 {
578 self.o
579 }
580
581 #[inline(always)]
583 pub fn bit(self, value: bool) -> &'a mut W<REG> {
584 self.w.bits &= !(REG::Ux::one() << self.o);
585 self.w.bits |= (REG::Ux::from(value) & REG::Ux::one()) << self.o;
586 self.w
587 }
588 #[inline(always)]
590 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
591 self.bit(bool::from(variant))
592 }
593 }
594 };
595}
596
597bit_proxy!(BitWriter, BitM);
598bit_proxy!(BitWriter1S, Bit1S);
599bit_proxy!(BitWriter0C, Bit0C);
600bit_proxy!(BitWriter1C, Bit1C);
601bit_proxy!(BitWriter0S, Bit0S);
602bit_proxy!(BitWriter1T, Bit1T);
603bit_proxy!(BitWriter0T, Bit0T);
604
605impl<'a, REG, FI> BitWriter<'a, REG, FI>
606where
607 REG: Writable + RegisterSpec,
608 bool: From<FI>,
609{
610 #[inline(always)]
612 pub fn set_bit(self) -> &'a mut W<REG> {
613 self.w.bits |= REG::Ux::one() << self.o;
614 self.w
615 }
616 #[inline(always)]
618 pub fn clear_bit(self) -> &'a mut W<REG> {
619 self.w.bits &= !(REG::Ux::one() << self.o);
620 self.w
621 }
622}
623
624impl<'a, REG, FI> BitWriter1S<'a, REG, FI>
625where
626 REG: Writable + RegisterSpec,
627 bool: From<FI>,
628{
629 #[inline(always)]
631 pub fn set_bit(self) -> &'a mut W<REG> {
632 self.w.bits |= REG::Ux::one() << self.o;
633 self.w
634 }
635}
636
637impl<'a, REG, FI> BitWriter0C<'a, REG, FI>
638where
639 REG: Writable + RegisterSpec,
640 bool: From<FI>,
641{
642 #[inline(always)]
644 pub fn clear_bit(self) -> &'a mut W<REG> {
645 self.w.bits &= !(REG::Ux::one() << self.o);
646 self.w
647 }
648}
649
650impl<'a, REG, FI> BitWriter1C<'a, REG, FI>
651where
652 REG: Writable + RegisterSpec,
653 bool: From<FI>,
654{
655 #[inline(always)]
657 pub fn clear_bit_by_one(self) -> &'a mut W<REG> {
658 self.w.bits |= REG::Ux::one() << self.o;
659 self.w
660 }
661}
662
663impl<'a, REG, FI> BitWriter0S<'a, REG, FI>
664where
665 REG: Writable + RegisterSpec,
666 bool: From<FI>,
667{
668 #[inline(always)]
670 pub fn set_bit_by_zero(self) -> &'a mut W<REG> {
671 self.w.bits &= !(REG::Ux::one() << self.o);
672 self.w
673 }
674}
675
676impl<'a, REG, FI> BitWriter1T<'a, REG, FI>
677where
678 REG: Writable + RegisterSpec,
679 bool: From<FI>,
680{
681 #[inline(always)]
683 pub fn toggle_bit(self) -> &'a mut W<REG> {
684 self.w.bits |= REG::Ux::one() << self.o;
685 self.w
686 }
687}
688
689impl<'a, REG, FI> BitWriter0T<'a, REG, FI>
690where
691 REG: Writable + RegisterSpec,
692 bool: From<FI>,
693{
694 #[inline(always)]
696 pub fn toggle_bit(self) -> &'a mut W<REG> {
697 self.w.bits &= !(REG::Ux::one() << self.o);
698 self.w
699 }
700}