1use core::marker;
2
3pub trait RegisterSpec {
5 type Ux: Copy;
7}
8
9pub trait Readable: RegisterSpec {
13 type Reader: From<R<Self>> + core::ops::Deref<Target = R<Self>>;
15}
16
17pub trait Writable: RegisterSpec {
23 type Writer: From<W<Self>> + core::ops::DerefMut<Target = W<Self>>;
25}
26
27pub trait Resettable: RegisterSpec {
32 fn reset_value() -> Self::Ux;
34}
35
36#[repr(transparent)]
38pub struct Reg<REG: RegisterSpec> {
39 register: vcell::VolatileCell<REG::Ux>,
40 _marker: marker::PhantomData<REG>,
41}
42
43unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
44
45impl<REG: RegisterSpec> Reg<REG> {
46 #[inline(always)]
52 pub fn as_ptr(&self) -> *mut REG::Ux {
53 self.register.as_ptr()
54 }
55}
56
57impl<REG: Readable> Reg<REG> {
58 #[inline(always)]
71 pub fn read(&self) -> REG::Reader {
72 REG::Reader::from(R {
73 bits: self.register.get(),
74 _reg: marker::PhantomData,
75 })
76 }
77}
78
79impl<REG: Resettable + Writable> Reg<REG> {
80 #[inline(always)]
84 pub fn reset(&self) {
85 self.register.set(REG::reset_value())
86 }
87
88 #[inline(always)]
112 pub fn write<F>(&self, f: F)
113 where
114 F: FnOnce(&mut REG::Writer) -> &mut W<REG>
115 {
116 self.register.set(
117 f(&mut REG::Writer::from(W {
118 bits: REG::reset_value(),
119 _reg: marker::PhantomData,
120 }))
121 .bits,
122 );
123 }
124}
125
126impl<REG: Writable> Reg<REG>
127where
128 REG::Ux: Default,
129{
130 #[inline(always)]
134 pub unsafe fn write_with_zero<F>(&self, f: F)
135 where
136 F: FnOnce(&mut REG::Writer) -> &mut W<REG>
137 {
138 self.register.set(
139 (*f(&mut REG::Writer::from(W {
140 bits: REG::Ux::default(),
141 _reg: marker::PhantomData,
142 })))
143 .bits,
144 );
145 }
146}
147
148impl<REG: Readable + Writable> Reg<REG> {
149 #[inline(always)]
175 pub fn modify<F>(&self, f: F)
176 where
177 for<'w> F: FnOnce(®::Reader, &'w mut REG::Writer) -> &'w mut W<REG>
178 {
179 let bits = self.register.get();
180 self.register.set(
181 f(
182 ®::Reader::from(R {
183 bits,
184 _reg: marker::PhantomData,
185 }),
186 &mut REG::Writer::from(W {
187 bits,
188 _reg: marker::PhantomData,
189 }),
190 )
191 .bits,
192 );
193 }
194}
195
196pub struct R<REG: RegisterSpec + ?Sized> {
201 pub(crate) bits: REG::Ux,
202 _reg: marker::PhantomData<REG>,
203}
204
205impl<REG: RegisterSpec> R<REG> {
206 #[inline(always)]
208 pub fn bits(&self) -> REG::Ux {
209 self.bits
210 }
211}
212
213impl<REG: RegisterSpec, FI> PartialEq<FI> for R<REG>
214where
215 REG::Ux: PartialEq,
216 FI: Copy + Into<REG::Ux>,
217{
218 #[inline(always)]
219 fn eq(&self, other: &FI) -> bool {
220 self.bits.eq(&(*other).into())
221 }
222}
223
224pub struct W<REG: RegisterSpec + ?Sized> {
228 pub(crate) bits: REG::Ux,
230 _reg: marker::PhantomData<REG>,
231}
232
233impl<REG: RegisterSpec> W<REG> {
234 #[inline(always)]
236 pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {
237 self.bits = bits;
238 self
239 }
240}
241
242#[doc(hidden)]
243pub struct FieldReaderRaw<U, T> {
244 pub(crate) bits: U,
245 _reg: marker::PhantomData<T>,
246}
247
248impl<U, FI> FieldReaderRaw<U, FI>
249where
250 U: Copy,
251{
252 #[allow(unused)]
254 #[inline(always)]
255 pub(crate) fn new(bits: U) -> Self {
256 Self {
257 bits,
258 _reg: marker::PhantomData,
259 }
260 }
261}
262
263#[doc(hidden)]
264pub struct BitReaderRaw<T> {
265 pub(crate) bits: bool,
266 _reg: marker::PhantomData<T>,
267}
268
269impl<FI> BitReaderRaw<FI> {
270 #[allow(unused)]
272 #[inline(always)]
273 pub(crate) fn new(bits: bool) -> Self {
274 Self {
275 bits,
276 _reg: marker::PhantomData,
277 }
278 }
279}
280
281pub type FieldReader<U, FI> = FieldReaderRaw<U, FI>;
285
286pub type BitReader<FI> = BitReaderRaw<FI>;
288
289impl<U, FI> FieldReader<U, FI>
290where
291 U: Copy,
292{
293 #[inline(always)]
295 pub fn bits(&self) -> U {
296 self.bits
297 }
298}
299
300impl<U, FI> PartialEq<FI> for FieldReader<U, FI>
301where
302 U: PartialEq,
303 FI: Copy + Into<U>,
304{
305 #[inline(always)]
306 fn eq(&self, other: &FI) -> bool {
307 self.bits.eq(&(*other).into())
308 }
309}
310
311impl<FI> PartialEq<FI> for BitReader<FI>
312where
313 FI: Copy + Into<bool>,
314{
315 #[inline(always)]
316 fn eq(&self, other: &FI) -> bool {
317 self.bits.eq(&(*other).into())
318 }
319}
320
321impl<FI> BitReader<FI> {
322 #[inline(always)]
324 pub fn bit(&self) -> bool {
325 self.bits
326 }
327 #[inline(always)]
329 pub fn bit_is_clear(&self) -> bool {
330 !self.bit()
331 }
332 #[inline(always)]
334 pub fn bit_is_set(&self) -> bool {
335 self.bit()
336 }
337}
338
339#[doc(hidden)]
340pub struct Safe;
341#[doc(hidden)]
342pub struct Unsafe;
343
344#[doc(hidden)]
345pub struct FieldWriterRaw<'a, U, REG, N, FI, Safety, const WI: u8, const O: u8>
346where
347 REG: Writable + RegisterSpec<Ux = U>,
348 FI: Into<N>,
349{
350 pub(crate) w: &'a mut REG::Writer,
351 _field: marker::PhantomData<(N, FI, Safety)>,
352}
353
354impl<'a, U, REG, N, FI, Safety, const WI: u8, const O: u8> FieldWriterRaw<'a, U, REG, N, FI, Safety, WI, O>
355where
356 REG: Writable + RegisterSpec<Ux = U>,
357 FI: Into<N>,
358{
359 #[allow(unused)]
361 #[inline(always)]
362 pub(crate) fn new(w: &'a mut REG::Writer) -> Self {
363 Self {
364 w,
365 _field: marker::PhantomData,
366 }
367 }
368}
369
370#[doc(hidden)]
371pub struct BitWriterRaw<'a, U, REG, FI, M, const O: u8>
372where
373 REG: Writable + RegisterSpec<Ux = U>,
374 FI: Into<bool>,
375{
376 pub(crate) w: &'a mut REG::Writer,
377 _field: marker::PhantomData<(FI, M)>,
378}
379
380impl<'a, U, REG, FI, M, const O: u8> BitWriterRaw<'a, U, REG, FI, M, O>
381where
382 REG: Writable + RegisterSpec<Ux = U>,
383 FI: Into<bool>,
384{
385 #[allow(unused)]
387 #[inline(always)]
388 pub(crate) fn new(w: &'a mut REG::Writer) -> Self {
389 Self {
390 w,
391 _field: marker::PhantomData,
392 }
393 }
394}
395
396pub type FieldWriter<'a, U, REG, N, FI, const WI: u8, const O: u8> = FieldWriterRaw<'a, U, REG, N, FI, Unsafe, WI, O>;
398pub type FieldWriterSafe<'a, U, REG, N, FI, const WI: u8, const O: u8> = FieldWriterRaw<'a, U, REG, N, FI, Safe, WI, O>;
400
401
402impl<'a, U, REG, N, FI, const WI: u8, const OF: u8> FieldWriter<'a, U, REG, N, FI, WI, OF>
403where
404 REG: Writable + RegisterSpec<Ux = U>,
405 FI: Into<N>,
406{
407 pub const WIDTH: u8 = WI;
409 pub const OFFSET: u8 = OF;
411}
412
413impl<'a, U, REG, N, FI, const WI: u8, const OF: u8> FieldWriterSafe<'a, U, REG, N, FI, WI, OF>
414where
415 REG: Writable + RegisterSpec<Ux = U>,
416 FI: Into<N>,
417{
418 pub const WIDTH: u8 = WI;
420 pub const OFFSET: u8 = OF;
422}
423
424macro_rules! bit_proxy {
425 ($writer:ident, $mwv:ident) => {
426 #[doc(hidden)]
427 pub struct $mwv;
428
429 pub type $writer<'a, U, REG, FI, const O: u8> = BitWriterRaw<'a, U, REG, FI, $mwv, O>;
431
432 impl<'a, U, REG, FI, const OF: u8> $writer<'a, U, REG, FI, OF>
433 where
434 REG: Writable + RegisterSpec<Ux = U>,
435 FI: Into<bool>,
436 {
437 pub const WIDTH: u8 = 1;
439 pub const OFFSET: u8 = OF;
441 }
442 }
443}
444
445macro_rules! impl_bit_proxy {
446 ($writer:ident, $U:ty) => {
447 impl<'a, REG, FI, const OF: u8> $writer<'a, $U, REG, FI, OF>
448 where
449 REG: Writable + RegisterSpec<Ux = $U>,
450 FI: Into<bool>,
451 {
452 #[inline(always)]
454 pub fn bit(self, value: bool) -> &'a mut REG::Writer {
455 self.w.bits = (self.w.bits & !(1 << { OF })) | ((<$U>::from(value) & 1) << { OF });
456 self.w
457 }
458 #[inline(always)]
460 pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
461 self.bit(variant.into())
462 }
463 }
464 }
465}
466
467bit_proxy!(BitWriter, BitM);
468bit_proxy!(BitWriter1S, Bit1S);
469bit_proxy!(BitWriter0C, Bit0C);
470bit_proxy!(BitWriter1C, Bit1C);
471bit_proxy!(BitWriter0S, Bit0S);
472bit_proxy!(BitWriter1T, Bit1T);
473bit_proxy!(BitWriter0T, Bit0T);
474
475macro_rules! impl_proxy {
476 ($U:ty) => {
477 impl<'a, REG, N, FI, const WI: u8, const OF: u8> FieldWriter<'a, $U, REG, N, FI, WI, OF>
478 where
479 REG: Writable + RegisterSpec<Ux = $U>,
480 N: Into<$U>,
481 FI: Into<N>,
482 {
483 const MASK: $U = <$U>::MAX >> (<$U>::MAX.leading_ones() as u8 - { WI });
484 #[inline(always)]
490 pub unsafe fn bits(self, value: N) -> &'a mut REG::Writer {
491 self.w.bits =
492 (self.w.bits & !(Self::MASK << { OF })) | ((value.into() & Self::MASK) << { OF });
493 self.w
494 }
495 #[inline(always)]
497 pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
498 unsafe { self.bits(variant.into()) }
499 }
500 }
501 impl<'a, REG, N, FI, const WI: u8, const OF: u8> FieldWriterSafe<'a, $U, REG, N, FI, WI, OF>
502 where
503 REG: Writable + RegisterSpec<Ux = $U>,
504 N: Into<$U>,
505 FI: Into<N>,
506 {
507 const MASK: $U = <$U>::MAX >> (<$U>::MAX.leading_ones() as u8 - { WI });
508 #[inline(always)]
510 pub fn bits(self, value: N) -> &'a mut REG::Writer {
511 self.w.bits =
512 (self.w.bits & !(Self::MASK << { OF })) | ((value.into() & Self::MASK) << { OF });
513 self.w
514 }
515 #[inline(always)]
517 pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
518 self.bits(variant.into())
519 }
520 }
521 impl_bit_proxy!(BitWriter, $U);
522 impl_bit_proxy!(BitWriter1S, $U);
523 impl_bit_proxy!(BitWriter0C, $U);
524 impl_bit_proxy!(BitWriter1C, $U);
525 impl_bit_proxy!(BitWriter0S, $U);
526 impl_bit_proxy!(BitWriter1T, $U);
527 impl_bit_proxy!(BitWriter0T, $U);
528 impl<'a, REG, FI, const OF: u8> BitWriter<'a, $U, REG, FI, OF>
529 where
530 REG: Writable + RegisterSpec<Ux = $U>,
531 FI: Into<bool>,
532 {
533 #[inline(always)]
535 pub fn set_bit(self) -> &'a mut REG::Writer {
536 self.bit(true)
537 }
538 #[inline(always)]
540 pub fn clear_bit(self) -> &'a mut REG::Writer {
541 self.bit(false)
542 }
543 }
544 impl<'a, REG, FI, const OF: u8> BitWriter1S<'a, $U, REG, FI, OF>
545 where
546 REG: Writable + RegisterSpec<Ux = $U>,
547 FI: Into<bool>,
548 {
549 #[inline(always)]
551 pub fn set_bit(self) -> &'a mut REG::Writer {
552 self.bit(true)
553 }
554 }
555 impl<'a, REG, FI, const OF: u8> BitWriter0C<'a, $U, REG, FI, OF>
556 where
557 REG: Writable + RegisterSpec<Ux = $U>,
558 FI: Into<bool>,
559 {
560 #[inline(always)]
562 pub fn clear_bit(self) -> &'a mut REG::Writer {
563 self.bit(false)
564 }
565 }
566 impl<'a, REG, FI, const OF: u8> BitWriter1C<'a, $U, REG, FI, OF>
567 where
568 REG: Writable + RegisterSpec<Ux = $U>,
569 FI: Into<bool>,
570 {
571 #[inline(always)]
573 pub fn clear_bit_by_one(self) -> &'a mut REG::Writer {
574 self.bit(true)
575 }
576 }
577 impl<'a, REG, FI, const OF: u8> BitWriter0S<'a, $U, REG, FI, OF>
578 where
579 REG: Writable + RegisterSpec<Ux = $U>,
580 FI: Into<bool>,
581 {
582 #[inline(always)]
584 pub fn set_bit_by_zero(self) -> &'a mut REG::Writer {
585 self.bit(false)
586 }
587 }
588 impl<'a, REG, FI, const OF: u8> BitWriter1T<'a, $U, REG, FI, OF>
589 where
590 REG: Writable + RegisterSpec<Ux = $U>,
591 FI: Into<bool>,
592 {
593 #[inline(always)]
595 pub fn toggle_bit(self) -> &'a mut REG::Writer {
596 self.bit(true)
597 }
598 }
599 impl<'a, REG, FI, const OF: u8> BitWriter0T<'a, $U, REG, FI, OF>
600 where
601 REG: Writable + RegisterSpec<Ux = $U>,
602 FI: Into<bool>,
603 {
604 #[inline(always)]
606 pub fn toggle_bit(self) -> &'a mut REG::Writer {
607 self.bit(false)
608 }
609 }
610 }
611}
612
613impl_proxy!(u32);