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 Readable: RegisterSpec {}
63
64pub trait Writable: RegisterSpec {
70 const ZERO_TO_MODIFY_FIELDS_BITMAP: Self::Ux;
72
73 const ONE_TO_MODIFY_FIELDS_BITMAP: Self::Ux;
75}
76
77pub trait Resettable: RegisterSpec {
82 const RESET_VALUE: Self::Ux;
84
85 #[inline(always)]
87 fn reset_value() -> Self::Ux {
88 Self::RESET_VALUE
89 }
90}
91
92#[repr(transparent)]
94pub struct Reg<REG: RegisterSpec> {
95 register: vcell::VolatileCell<REG::Ux>,
96 _marker: marker::PhantomData<REG>,
97}
98
99unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
100
101impl<REG: RegisterSpec> Reg<REG> {
102 #[inline(always)]
108 pub fn as_ptr(&self) -> *mut REG::Ux {
109 self.register.as_ptr()
110 }
111}
112
113impl<REG: Readable> Reg<REG> {
114 #[inline(always)]
127 pub fn read(&self) -> R<REG> {
128 R {
129 bits: self.register.get(),
130 _reg: marker::PhantomData,
131 }
132 }
133}
134
135impl<REG: Resettable + Writable> Reg<REG> {
136 #[inline(always)]
140 pub fn reset(&self) {
141 self.register.set(REG::RESET_VALUE)
142 }
143
144 #[inline(always)]
168 pub fn write<F>(&self, f: F)
169 where
170 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
171 {
172 self.register.set(
173 f(&mut W {
174 bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
175 | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
176 _reg: marker::PhantomData,
177 })
178 .bits,
179 );
180 }
181}
182
183impl<REG: Writable> Reg<REG> {
184 #[inline(always)]
192 pub unsafe fn write_with_zero<F>(&self, f: F)
193 where
194 F: FnOnce(&mut W<REG>) -> &mut W<REG>,
195 {
196 self.register.set(
197 f(&mut W {
198 bits: REG::Ux::default(),
199 _reg: marker::PhantomData,
200 })
201 .bits,
202 );
203 }
204}
205
206impl<REG: Readable + Writable> Reg<REG> {
207 #[inline(always)]
233 pub fn modify<F>(&self, f: F)
234 where
235 for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
236 {
237 let bits = self.register.get();
238 self.register.set(
239 f(
240 &R {
241 bits,
242 _reg: marker::PhantomData,
243 },
244 &mut W {
245 bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
246 | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
247 _reg: marker::PhantomData,
248 },
249 )
250 .bits,
251 );
252 }
253}
254
255#[doc(hidden)]
256pub mod raw {
257 use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
258
259 pub struct R<REG: RegisterSpec> {
260 pub(crate) bits: REG::Ux,
261 pub(super) _reg: marker::PhantomData<REG>,
262 }
263
264 pub struct W<REG: RegisterSpec> {
265 pub(crate) bits: REG::Ux,
267 pub(super) _reg: marker::PhantomData<REG>,
268 }
269
270 pub struct FieldReader<FI = u8>
271 where
272 FI: FieldSpec,
273 {
274 pub(crate) bits: FI::Ux,
275 _reg: marker::PhantomData<FI>,
276 }
277
278 impl<FI: FieldSpec> FieldReader<FI> {
279 #[allow(unused)]
281 #[inline(always)]
282 pub(crate) const fn new(bits: FI::Ux) -> Self {
283 Self {
284 bits,
285 _reg: marker::PhantomData,
286 }
287 }
288 }
289
290 pub struct BitReader<FI = bool> {
291 pub(crate) bits: bool,
292 _reg: marker::PhantomData<FI>,
293 }
294
295 impl<FI> BitReader<FI> {
296 #[allow(unused)]
298 #[inline(always)]
299 pub(crate) const fn new(bits: bool) -> Self {
300 Self {
301 bits,
302 _reg: marker::PhantomData,
303 }
304 }
305 }
306
307 pub struct FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe>
308 where
309 REG: Writable + RegisterSpec,
310 FI: FieldSpec,
311 {
312 pub(crate) w: &'a mut W<REG>,
313 pub(crate) o: u8,
314 _field: marker::PhantomData<(FI, Safety)>,
315 }
316
317 impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety>
318 where
319 REG: Writable + RegisterSpec,
320 FI: FieldSpec,
321 {
322 #[allow(unused)]
324 #[inline(always)]
325 pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
326 Self {
327 w,
328 o,
329 _field: marker::PhantomData,
330 }
331 }
332 }
333
334 pub struct BitWriter<'a, REG, FI = bool, M = BitM>
335 where
336 REG: Writable + RegisterSpec,
337 bool: From<FI>,
338 {
339 pub(crate) w: &'a mut W<REG>,
340 pub(crate) o: u8,
341 _field: marker::PhantomData<(FI, M)>,
342 }
343
344 impl<'a, REG, FI, M> BitWriter<'a, REG, FI, M>
345 where
346 REG: Writable + RegisterSpec,
347 bool: From<FI>,
348 {
349 #[allow(unused)]
351 #[inline(always)]
352 pub(crate) fn new(w: &'a mut W<REG>, o: u8) -> Self {
353 Self {
354 w,
355 o,
356 _field: marker::PhantomData,
357 }
358 }
359 }
360}
361
362pub type R<REG> = raw::R<REG>;
367
368impl<REG: RegisterSpec> R<REG> {
369 #[inline(always)]
371 pub const fn bits(&self) -> REG::Ux {
372 self.bits
373 }
374}
375
376impl<REG: RegisterSpec, FI> PartialEq<FI> for R<REG>
377where
378 REG::Ux: PartialEq,
379 FI: Copy,
380 REG::Ux: From<FI>,
381{
382 #[inline(always)]
383 fn eq(&self, other: &FI) -> bool {
384 self.bits.eq(®::Ux::from(*other))
385 }
386}
387
388pub type W<REG> = raw::W<REG>;
392
393pub type FieldReader<FI = u8> = raw::FieldReader<FI>;
397
398pub type BitReader<FI = bool> = raw::BitReader<FI>;
400
401impl<FI: FieldSpec> FieldReader<FI> {
402 #[inline(always)]
404 pub const fn bits(&self) -> FI::Ux {
405 self.bits
406 }
407}
408
409impl<FI> PartialEq<FI> for FieldReader<FI>
410where
411 FI: FieldSpec + Copy,
412{
413 #[inline(always)]
414 fn eq(&self, other: &FI) -> bool {
415 self.bits.eq(&FI::Ux::from(*other))
416 }
417}
418
419impl<FI> PartialEq<FI> for BitReader<FI>
420where
421 FI: Copy,
422 bool: From<FI>,
423{
424 #[inline(always)]
425 fn eq(&self, other: &FI) -> bool {
426 self.bits.eq(&bool::from(*other))
427 }
428}
429
430impl<FI> BitReader<FI> {
431 #[inline(always)]
433 pub const fn bit(&self) -> bool {
434 self.bits
435 }
436 #[inline(always)]
438 pub const fn bit_is_clear(&self) -> bool {
439 !self.bit()
440 }
441 #[inline(always)]
443 pub const fn bit_is_set(&self) -> bool {
444 self.bit()
445 }
446}
447
448#[doc(hidden)]
449pub struct Safe;
450#[doc(hidden)]
451pub struct Unsafe;
452
453pub type FieldWriter<'a, REG, const WI: u8, FI = u8> = raw::FieldWriter<'a, REG, WI, FI, Unsafe>;
455pub type FieldWriterSafe<'a, REG, const WI: u8, FI = u8> = raw::FieldWriter<'a, REG, WI, FI, Safe>;
457
458impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI>
459where
460 REG: Writable + RegisterSpec,
461 FI: FieldSpec,
462 REG::Ux: From<FI::Ux>,
463{
464 pub const WIDTH: u8 = WI;
466
467 #[inline(always)]
469 pub const fn width(&self) -> u8 {
470 WI
471 }
472
473 #[inline(always)]
475 pub const fn offset(&self) -> u8 {
476 self.o
477 }
478
479 #[inline(always)]
485 pub unsafe fn bits(self, value: FI::Ux) -> &'a mut W<REG> {
486 self.w.bits &= !(REG::Ux::mask::<WI>() << self.o);
487 self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << self.o;
488 self.w
489 }
490 #[inline(always)]
492 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
493 unsafe { self.bits(FI::Ux::from(variant)) }
494 }
495}
496
497impl<'a, REG, const WI: u8, FI> FieldWriterSafe<'a, REG, WI, FI>
498where
499 REG: Writable + RegisterSpec,
500 FI: FieldSpec,
501 REG::Ux: From<FI::Ux>,
502{
503 pub const WIDTH: u8 = WI;
505
506 #[inline(always)]
508 pub const fn width(&self) -> u8 {
509 WI
510 }
511
512 #[inline(always)]
514 pub const fn offset(&self) -> u8 {
515 self.o
516 }
517
518 #[inline(always)]
520 pub 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 #[inline(always)]
527 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
528 self.bits(FI::Ux::from(variant))
529 }
530}
531
532macro_rules! bit_proxy {
533 ($writer:ident, $mwv:ident) => {
534 #[doc(hidden)]
535 pub struct $mwv;
536
537 pub type $writer<'a, REG, FI = bool> = raw::BitWriter<'a, REG, FI, $mwv>;
539
540 impl<'a, REG, FI> $writer<'a, REG, FI>
541 where
542 REG: Writable + RegisterSpec,
543 bool: From<FI>,
544 {
545 pub const WIDTH: u8 = 1;
547
548 #[inline(always)]
550 pub const fn width(&self) -> u8 {
551 Self::WIDTH
552 }
553
554 #[inline(always)]
556 pub const fn offset(&self) -> u8 {
557 self.o
558 }
559
560 #[inline(always)]
562 pub fn bit(self, value: bool) -> &'a mut W<REG> {
563 self.w.bits &= !(REG::Ux::one() << self.o);
564 self.w.bits |= (REG::Ux::from(value) & REG::Ux::one()) << self.o;
565 self.w
566 }
567 #[inline(always)]
569 pub fn variant(self, variant: FI) -> &'a mut W<REG> {
570 self.bit(bool::from(variant))
571 }
572 }
573 };
574}
575
576bit_proxy!(BitWriter, BitM);
577bit_proxy!(BitWriter1S, Bit1S);
578bit_proxy!(BitWriter0C, Bit0C);
579bit_proxy!(BitWriter1C, Bit1C);
580bit_proxy!(BitWriter0S, Bit0S);
581bit_proxy!(BitWriter1T, Bit1T);
582bit_proxy!(BitWriter0T, Bit0T);
583
584impl<'a, REG, FI> BitWriter<'a, REG, FI>
585where
586 REG: Writable + RegisterSpec,
587 bool: From<FI>,
588{
589 #[inline(always)]
591 pub fn set_bit(self) -> &'a mut W<REG> {
592 self.w.bits |= REG::Ux::one() << self.o;
593 self.w
594 }
595 #[inline(always)]
597 pub fn clear_bit(self) -> &'a mut W<REG> {
598 self.w.bits &= !(REG::Ux::one() << self.o);
599 self.w
600 }
601}
602
603impl<'a, REG, FI> BitWriter1S<'a, REG, FI>
604where
605 REG: Writable + RegisterSpec,
606 bool: From<FI>,
607{
608 #[inline(always)]
610 pub fn set_bit(self) -> &'a mut W<REG> {
611 self.w.bits |= REG::Ux::one() << self.o;
612 self.w
613 }
614}
615
616impl<'a, REG, FI> BitWriter0C<'a, REG, FI>
617where
618 REG: Writable + RegisterSpec,
619 bool: From<FI>,
620{
621 #[inline(always)]
623 pub fn clear_bit(self) -> &'a mut W<REG> {
624 self.w.bits &= !(REG::Ux::one() << self.o);
625 self.w
626 }
627}
628
629impl<'a, REG, FI> BitWriter1C<'a, REG, FI>
630where
631 REG: Writable + RegisterSpec,
632 bool: From<FI>,
633{
634 #[inline(always)]
636 pub fn clear_bit_by_one(self) -> &'a mut W<REG> {
637 self.w.bits |= REG::Ux::one() << self.o;
638 self.w
639 }
640}
641
642impl<'a, REG, FI> BitWriter0S<'a, REG, FI>
643where
644 REG: Writable + RegisterSpec,
645 bool: From<FI>,
646{
647 #[inline(always)]
649 pub fn set_bit_by_zero(self) -> &'a mut W<REG> {
650 self.w.bits &= !(REG::Ux::one() << self.o);
651 self.w
652 }
653}
654
655impl<'a, REG, FI> BitWriter1T<'a, REG, FI>
656where
657 REG: Writable + RegisterSpec,
658 bool: From<FI>,
659{
660 #[inline(always)]
662 pub fn toggle_bit(self) -> &'a mut W<REG> {
663 self.w.bits |= REG::Ux::one() << self.o;
664 self.w
665 }
666}
667
668impl<'a, REG, FI> BitWriter0T<'a, REG, FI>
669where
670 REG: Writable + RegisterSpec,
671 bool: From<FI>,
672{
673 #[inline(always)]
675 pub fn toggle_bit(self) -> &'a mut W<REG> {
676 self.w.bits &= !(REG::Ux::one() << self.o);
677 self.w
678 }
679}
680