ra6e1_pac/
common.rs

1/*
2DISCLAIMER
3This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products.
4No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
5applicable laws, including copyright laws.
6THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED
7OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
8NON-INFRINGEMENT.  ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY
9LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT,
10INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR
11ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
12Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability
13of this software. By using this software, you agree to the additional terms and conditions found by accessing the
14following link:
15http://www.renesas.com/disclaimer
16
17*/
18// Generated from SVD 1.20.00, with svd2pac 0.6.0 on Thu, 24 Jul 2025 04:50:30 +0000
19
20use core::convert::From;
21use core::marker::PhantomData;
22
23#[cfg(feature = "tracing")]
24use crate::tracing;
25
26#[derive(Copy, Clone, PartialEq, Eq)]
27pub struct RW;
28#[derive(Copy, Clone, PartialEq, Eq)]
29pub struct R;
30#[derive(Copy, Clone, PartialEq, Eq)]
31pub struct W;
32
33pub(crate) mod sealed {
34    use super::*;
35    pub trait Access {}
36    impl Access for R {}
37    impl Access for W {}
38    impl Access for RW {}
39    use core::ops::{BitAnd, BitAndAssign, BitOrAssign, Not, Shl, Shr};
40
41    // It would be better with const fn
42    // waiting for RFC: const functions in traits #3490
43    pub trait CastFrom<A> {
44        fn cast_from(val: A) -> Self;
45    }
46
47    impl CastFrom<u64> for u8 {
48        #[inline(always)]
49        fn cast_from(val: u64) -> Self {
50            val as Self
51        }
52    }
53
54    impl CastFrom<u64> for u16 {
55        #[inline(always)]
56        fn cast_from(val: u64) -> Self {
57            val as Self
58        }
59    }
60
61    impl CastFrom<u64> for u32 {
62        #[inline(always)]
63        fn cast_from(val: u64) -> Self {
64            val as Self
65        }
66    }
67
68    impl CastFrom<u64> for u64 {
69        #[inline(always)]
70        fn cast_from(val: u64) -> Self {
71            val as Self
72        }
73    }
74
75    pub trait RegNumberT:
76        Copy
77        + From<u8>
78        + Into<u64>
79        + CastFrom<u64>
80        + Shr<usize, Output = Self>
81        + Shl<usize, Output = Self>
82        + BitAndAssign
83        + BitAnd<Output = Self>
84        + Not<Output = Self>
85        + BitOrAssign
86    {
87    }
88    impl RegNumberT for u8 {}
89    impl RegNumberT for u16 {}
90    impl RegNumberT for u32 {}
91    impl RegNumberT for u64 {}
92
93    pub trait RegSpec {
94        type DataType: RegNumberT;
95    }
96}
97
98pub trait Access: sealed::Access + Copy {}
99impl Access for R {}
100impl Access for W {}
101impl Access for RW {}
102
103pub trait Read: Access {}
104impl Read for RW {}
105impl Read for R {}
106
107pub trait Write: Access {}
108impl Write for RW {}
109impl Write for W {}
110
111#[derive(Copy, Clone, PartialEq, Eq)]
112pub struct Reg<T, A: Access> {
113    phantom: PhantomData<*mut (T, A)>,
114}
115unsafe impl<T, A: Access> Send for Reg<T, A> {}
116unsafe impl<T, A: Access> Sync for Reg<T, A> {}
117
118use sealed::CastFrom;
119
120use sealed::{RegNumberT, RegSpec};
121#[doc(hidden)]
122#[derive(Copy, Clone)]
123pub struct RegValueT<Reg: sealed::RegSpec> {
124    pub(crate) data: Reg::DataType,
125    pub(crate) mask: Reg::DataType,
126}
127
128pub trait RegisterValue<T: RegSpec> {
129    /// Create a register value that could be written to a register from raw integer
130    ///
131    /// ```rust, ignore
132    /// // example with generic names
133    /// // needs: use test_pac::{timer, RegisterValue, TIMER}
134    /// let to_write = timer::BitfieldReg::new(0xdeadbeef);
135    /// TIMER.bitfield_reg().write(to_write);
136    /// let to_write = to_write.boolw().set(true);
137    /// TIMER.bitfield_reg().write(to_write);
138    /// ```
139    #[must_use]
140    fn new(data: T::DataType) -> Self;
141
142    /// Get raw integer from value read from register
143    ///
144    /// ```rust,ignore
145    /// // example with generic names
146    /// // needs: use pac::{RegisterValue, TIMER}
147    /// let x = TIMER.bitfield_reg().read().get_raw();
148    /// ```
149    #[must_use]
150    fn get_raw(&self) -> T::DataType;
151
152    /// Prepare a register value that could be written to a register with an arbitrary value
153    ///
154    /// Use this function for setting a register to a custom value, independent
155    /// of bitfields, enumerations, etc. No checks are performed on the passed
156    /// value. The whole register is updated on write.
157    ///
158    /// ```rust,ignore
159    /// // example with generic names
160    /// // needs: use pac::{RegisterValue, TIMER}
161    /// TIMER.bitfield_reg().init(|r| r.set_raw(0xdeadbeef))
162    /// ```
163    #[must_use]
164    fn set_raw(self, value: T::DataType) -> Self;
165}
166
167impl<T: RegSpec> RegisterValue<T> for RegValueT<T> {
168    /// Create a register value that could be written to a register from raw integer
169    ///
170    /// ```rust, ignore
171    /// // example with generic names
172    /// // needs: use pac::{timer, RegisterValue, TIMER}
173    /// let to_write = timer::BitfieldReg::new(0xdeadbeef);
174    /// TIMER.bitfield_reg().write(to_write);
175    /// let to_write = to_write.boolw().set(true);
176    /// TIMER.bitfield_reg().write(to_write);
177    /// ```
178    #[inline(always)]
179    fn new(data: T::DataType) -> RegValueT<T> {
180        Self {
181            data,
182            mask: 0x0u8.into(),
183        }
184    }
185
186    /// Get raw integer from value read from register
187    ///
188    /// ```rust,ignore
189    /// // example with generic names
190    /// // needs: use pac::{RegisterValue, TIMER}
191    /// let x = TIMER.bitfield_reg().read().get_raw();
192    /// ```
193    #[inline(always)]
194    fn get_raw(&self) -> T::DataType {
195        self.data
196    }
197
198    /// Prepare a register value that could be written to a register with an arbitrary value
199    ///
200    /// Use this function for setting a register to a custom value, independent
201    /// of bitfields, enumerations, etc. No checks are performed on the passed
202    /// value.
203    ///
204    /// ```rust,ignore
205    /// // example with generic names
206    /// // needs: use pac::{RegisterValue, TIMER}
207    /// TIMER.bitfield_reg().init(|r| r.set_raw(0xdeadbeef))
208    /// ```
209    #[inline(always)]
210    fn set_raw(mut self, value: T::DataType) -> Self {
211        self.data = value;
212        self.mask = !(Into::<T::DataType>::into(0x0u8));
213        self
214    }
215}
216
217pub trait NoBitfieldReg<Reg: RegSpec>: RegisterValue<Reg>
218where
219    Self: Sized,
220{
221    /// Get value read from register
222    ///
223    /// ```rust,ignore
224    /// // example with generic names
225    /// // needs: use pac::{NoBitfieldReg, TIMER}
226    /// let x = TIMER.nobitfield_reg().read().get();
227    /// ```
228    #[inline(always)]
229    #[must_use]
230    fn get(&self) -> Reg::DataType {
231        self.get_raw()
232    }
233
234    /// Prepare value to be written to register
235    ///
236    /// ```rust,ignore
237    /// // example with generic names
238    /// // needs: use pac::{NoBitfieldReg, TIMER}
239    /// TIMER.nobitfield_reg().init(|r| r.set(0xc0ffee));
240    /// ```
241    #[inline(always)]
242    #[must_use]
243    fn set(self, value: Reg::DataType) -> Self {
244        self.set_raw(value)
245    }
246}
247
248impl<T, A> Reg<T, A>
249where
250    T: RegSpec,
251    A: Access,
252{
253    #[allow(dead_code)]
254    #[inline(always)]
255    #[must_use]
256    #[allow(dead_code)]
257    pub(crate) const fn from_ptr(ptr: *mut u8) -> &'static Self {
258        unsafe { &*(ptr as *const Self) }
259    }
260
261    #[inline(always)]
262    #[must_use]
263    pub const fn ptr(&self) -> *mut T::DataType {
264        self as *const _ as *mut T::DataType
265    }
266
267    /// Returns the address of the register.
268    pub fn addr(&self) -> usize {
269        (self as *const _) as usize
270    }
271}
272
273impl<T, A> Reg<T, A>
274where
275    T: RegSpec,
276    A: Read,
277{
278    /// Read register and return a register value
279    ///
280    /// # Safety
281    /// Read operation could cause undefined behavior for some peripheral. Developer shall read device user manual.
282    /// Register is Send and Sync to allow complete freedom. Developer is responsible of proper use in interrupt and thread.
283    ///
284    /// # Example
285    /// ```rust,ignore
286    /// // example with generic names
287    /// let reg = unsafe { TIMER.bitfield_reg().read() };
288    /// if reg.boolr().get() { /* ... */ }
289    /// ```
290    #[inline(always)]
291    #[must_use]
292    pub unsafe fn read(&self) -> RegValueT<T> {
293        unsafe {
294            #[cfg(feature = "tracing")]
295            let val = {
296                let mut buf: u64 = 0x0;
297                tracing::READ_FN.with(|rf| {
298                if let Some(rf) = rf.get() {
299                    buf = rf(self.addr(), std::mem::size_of::<T::DataType>());
300                } else {
301                    #[cfg(not(feature = "tracing_dummy"))]
302                    panic!(
303                        "Please, provide an handler for read with tracing::set_read_fn(callback);"
304                    );
305                }
306            });
307                T::DataType::cast_from(buf)
308            };
309            #[cfg(not(feature = "tracing"))]
310            let val = self.ptr().read_volatile();
311            RegValueT::<T>::new(val)
312        }
313    }
314}
315
316impl<T, A> Reg<T, A>
317where
318    T: RegSpec,
319    A: Write,
320{
321    /// Write register value back to register
322    ///
323    /// # Arguments
324    ///
325    /// * `reg_value` - A string slice that holds the name of the person
326    ///
327    /// # Safety
328    /// Write operation could cause undefined behavior for some peripheral. Developers shall read the device user manual.
329    /// Register is Send and Sync to allow complete freedom. Developers are responsible of proper use in interrupt and thread.
330    ///
331    /// # Example
332    /// ```rust,ignore
333    /// // example with generic names
334    /// // write with a previously read value
335    /// let reg = unsafe { TIMER.bitfield_reg().read() };
336    /// // or start with a known value
337    /// let reg = timer::BitfieldReg::new(0).bitfieldw().set(0x55);
338    /// // or start with the register default
339    /// let reg = timer::BitfieldReg::default();
340    ///
341    /// let reg = reg.bitfieldrw().set(0x77);
342    ///
343    /// // no change has taken place to the register due to `set` calls - do that now by writing back the result
344    /// unsafe { TIMER.bitfield_reg().write(reg) }
345    /// ```
346    /// See also: [`Reg<T, A>::init`] which provides the default value to a closure
347    #[inline(always)]
348    pub unsafe fn write(&self, reg_value: RegValueT<T>) {
349        unsafe {
350            #[cfg(feature = "tracing")]
351            tracing::WRITE_FN.with(|wf| {
352                if let Some(wf) = wf.get() {
353                    wf(
354                        self.addr(),
355                        std::mem::size_of::<T::DataType>(),
356                        reg_value.data.into(),
357                    )
358                } else {
359                    #[cfg(not(feature = "tracing_dummy"))]
360                    panic!(
361                        "Please, provide an handler for read with tracing::set_read_fn(callback);"
362                    );
363                }
364            });
365            #[cfg(not(feature = "tracing"))]
366            self.ptr().write_volatile(reg_value.data);
367        }
368    }
369
370    /// Write an arbitrary integer to register
371    ///
372    /// Use this function when e.g. loading data to be written from a config-page.
373    /// For normal use prefer either [`Reg<T, A>::write`] if the value was read before, or [`Reg<T, A>::init`],
374    /// both of which provide some restrictions available register fields, enums, etc.
375    ///
376    /// # Arguments
377    ///
378    /// * `value` - The unchecked value to be written to the register
379    ///
380    /// # Safety
381    ///
382    /// Write operation could cause undefined behavior for some peripheral. Developers shall read the device user manual.
383    /// Register is Send and Sync to allow complete freedom. Developers are responsible of proper use in interrupt and thread.
384    ///
385    /// # Example
386    /// ```rust,ignore
387    /// // example with generic names
388    /// unsafe { TIMER.bitfield_reg().write_raw(0xdead) }
389    /// ```
390    /// See also [`Reg<T, A>::init`] and [`Reg<T, A>::write`] both of which are the safe, preferred functions.
391    #[inline(always)]
392    pub unsafe fn write_raw(&self, value: T::DataType) {
393        unsafe {
394            #[cfg(feature = "tracing")]
395            tracing::WRITE_FN.with(|wf| {
396                if let Some(wf) = wf.get() {
397                    wf(
398                        self.addr(),
399                        std::mem::size_of::<T::DataType>(),
400                        value.into(),
401                    )
402                } else {
403                    #[cfg(not(feature = "tracing_dummy"))]
404                    panic!(
405                        "Please, provide an handler for read with tracing::set_read_fn(callback);"
406                    );
407                }
408            });
409            #[cfg(not(feature = "tracing"))]
410            self.ptr().write_volatile(value);
411        }
412    }
413}
414
415impl<T, A> Reg<T, A>
416where
417    T: RegSpec,
418    A: Write,
419    RegValueT<T>: Default,
420{
421    /// Write register with register value built from default register value
422    ///
423    /// # Arguments
424    ///
425    /// * `f` - Closure that receive as input a register value initialized with register value at Power On Reset.
426    ///
427    /// # Safety
428    /// Write operation could cause undefined behavior for some peripheral. Developer shall read device user manual.
429    /// Register is Send and Sync to allow complete freedom. Developer is responsible of proper use in interrupt and thread.
430    ///
431    /// # Example
432    /// ```rust,ignore
433    /// // example with generic names
434    /// TIMER
435    ///     .bitfield_reg()
436    ///     .init(|r| r.bitfieldw().set(0b1010).boolw().set(true));
437    /// ```
438    #[inline(always)]
439    /// Write value computed by closure that receive as input the reset value of register
440    pub unsafe fn init(&self, f: impl FnOnce(RegValueT<T>) -> RegValueT<T>) {
441        unsafe {
442            let val = RegValueT::<T>::default();
443            let res = f(val);
444            self.write(res);
445        }
446    }
447}
448
449impl<T, A> Reg<T, A>
450where
451    T: RegSpec,
452    A: Read + Write,
453{
454    /// Read/modify/write register
455    ///
456    /// # Arguments
457    ///
458    /// * `f` - Closure that receive as input a register value read from register. The result of the closure
459    ///   is written back to the register.
460    ///
461    /// # Safety
462    /// Write operation could cause undefined behavior for some peripheral. Developer shall read device user manual.
463    /// Register is Send and Sync to allow complete freedom. Developer is responsible of proper use in interrupt and thread.
464    ///
465    /// # Example
466    /// ```rust,ignore
467    /// // example with generic names
468    /// TIMER
469    ///     .bitfield_reg()
470    ///     .modify(|r| r.boolrw().set(!r.boolrw().get()));
471    /// ```
472    #[inline(always)]
473    pub unsafe fn modify(&self, f: impl FnOnce(RegValueT<T>) -> RegValueT<T>) {
474        unsafe {
475            let val = self.read();
476            let res = f(val);
477            self.write(res);
478        }
479    }
480}
481
482/// Proxy struct for enumerated bitfields
483#[repr(transparent)]
484#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
485pub struct EnumBitfieldStruct<Q: RegNumberT, T>(pub Q, PhantomData<T>);
486
487impl<Q: RegNumberT, T> EnumBitfieldStruct<Q, T> {
488    pub const fn new(value: Q) -> Self {
489        Self(value, PhantomData)
490    }
491}
492
493impl<Q: RegNumberT, T> From<EnumBitfieldStruct<Q, T>> for u64 {
494    #[inline(always)]
495    fn from(value: EnumBitfieldStruct<Q, T>) -> Self {
496        value.0.into()
497    }
498}
499impl<Q: RegNumberT, T> CastFrom<u64> for EnumBitfieldStruct<Q, T> {
500    #[inline(always)]
501    fn cast_from(val: u64) -> Self {
502        Self(Q::cast_from(val), PhantomData)
503    }
504}
505
506impl<Q: RegNumberT, T> From<Q> for EnumBitfieldStruct<Q, T> {
507    #[inline(always)]
508    fn from(value: Q) -> Self {
509        Self(value, PhantomData)
510    }
511}
512
513/// Proxy struct for numeric bitfields
514pub struct RegisterField<
515    const START_OFFSET: usize,
516    const MASK: u64,
517    const DIM: u8,
518    const DIM_INCREMENT: u8,
519    ValueTypeRead,
520    ValueTypeWrite,
521    T,
522    A,
523> where
524    T: RegSpec,
525    A: Access,
526{
527    data: RegValueT<T>,
528    index: u8,
529    marker: PhantomData<(ValueTypeRead, ValueTypeWrite, A)>,
530}
531
532impl<
533    const START_OFFSET: usize,
534    const MASK: u64,
535    const DIM: u8,
536    const DIM_INCREMENT: u8,
537    ValueTypeRead,
538    ValueTypeWrite,
539    T,
540    A,
541> RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueTypeRead, ValueTypeWrite, T, A>
542where
543    T: RegSpec,
544    A: Access,
545{
546    #[allow(dead_code)]
547    #[inline(always)]
548    pub(crate) fn from_register(data: RegValueT<T>, index: u8) -> Self {
549        Self {
550            data,
551            index,
552            marker: PhantomData,
553        }
554    }
555
556    /// Get mask for bitfield, the mask is unshifted and at offset 0
557    ///
558    /// Prefer the use of [`RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueTypeRead,ValueTypeWrite, T, A>::get()`] to
559    /// extract a bitfield value.
560    #[inline(always)]
561    #[must_use]
562    pub fn mask(&self) -> T::DataType {
563        T::DataType::cast_from(MASK)
564    }
565
566    /// Get offset of bitfield in containing register
567    ///
568    /// Prefer the use of [`RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueTypeRead,ValueTypeWrite, T, A>::get()`] to
569    /// extract a bitfield value.
570    #[inline(always)]
571    #[must_use]
572    pub const fn offset(&self) -> usize {
573        START_OFFSET + (self.index * DIM_INCREMENT) as usize
574    }
575}
576
577impl<
578    const START_OFFSET: usize,
579    const MASK: u64,
580    const DIM: u8,
581    const DIM_INCREMENT: u8,
582    ValueTypeRead,
583    ValueTypeWrite,
584    T,
585    A,
586> RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueTypeRead, ValueTypeWrite, T, A>
587where
588    T: RegSpec,
589    A: Read,
590    ValueTypeRead: CastFrom<u64>,
591{
592    /// Extract bitfield from read register value
593    #[inline(always)]
594    pub fn get(&self) -> ValueTypeRead {
595        let offset = START_OFFSET + (self.index * DIM_INCREMENT) as usize;
596        let filtered: T::DataType = (self.data.data >> offset) & T::DataType::cast_from(MASK);
597        ValueTypeRead::cast_from(filtered.into())
598    }
599}
600
601impl<
602    const START_OFFSET: usize,
603    const MASK: u64,
604    const DIM: u8,
605    const DIM_INCREMENT: u8,
606    ValueTypeRead,
607    ValueTypeWrite,
608    T,
609    A,
610> RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueTypeRead, ValueTypeWrite, T, A>
611where
612    T: RegSpec,
613    A: Write,
614    u64: From<ValueTypeWrite>,
615{
616    /// Prepare bitfield value that could be written to register
617    ///
618    /// # Example
619    /// ```rust,ignore
620    /// // example with generic names
621    /// // get an instance by reading
622    /// let values = TIMER.bitfield_reg().read();
623    /// // or by starting with a known value
624    /// let value = timer::BitfieldReg::new(0);
625    /// // or by starting with the default
626    /// let value = timer::BitfieldReg::default();
627    ///
628    /// // set bitfields
629    /// let value = value
630    ///     // set numeric bitfield
631    ///     .bitfieldw()
632    ///     .set(0x55)
633    ///     // set enumerated bitfield with enumeration
634    ///     .bitfieldenumerated()
635    ///     .set(timer::bitfield_reg::BitfieldEnumerated::GPIOA_0)
636    ///     // set enumerated bitfield from integer
637    ///     .bitfieldenumerated()
638    ///     .set(1.into());
639    ///
640    /// // up until now no hardware change has taken place, do that now by writing
641    /// TIMER.bitfield_reg().write(value);
642    /// ```
643    #[inline(always)]
644    #[must_use]
645    pub fn set(mut self, value: ValueTypeWrite) -> RegValueT<T> {
646        let mask = T::DataType::cast_from(MASK);
647        let value: T::DataType = T::DataType::cast_from(Into::<u64>::into(value)) & mask;
648        let offset = START_OFFSET + (self.index * DIM_INCREMENT) as usize;
649        let masked_offset: T::DataType = mask << offset;
650        self.data.mask |= masked_offset;
651        self.data.data &= !masked_offset;
652        self.data.data |= value << offset;
653        self.data
654    }
655}
656
657/// Proxy struct for boolean bitfields
658pub struct RegisterFieldBool<
659    const START_OFFSET: usize,
660    const DIM: u8,
661    const DIM_INCREMENT: u8,
662    T,
663    A,
664> where
665    T: RegSpec,
666    A: Access,
667{
668    data: RegValueT<T>,
669    index: u8,
670    marker: PhantomData<A>,
671}
672
673impl<const START_OFFSET: usize, const DIM: u8, const DIM_INCREMENT: u8, T, A>
674    RegisterFieldBool<START_OFFSET, DIM, DIM_INCREMENT, T, A>
675where
676    T: RegSpec,
677    A: Read,
678{
679    /// Extract bitfield from read register value
680    #[inline(always)]
681    pub fn get(&self) -> bool {
682        let offset = START_OFFSET + (self.index * DIM_INCREMENT) as usize;
683        let filtered = (self.data.data.into() >> offset) & 1;
684        filtered == 1
685    }
686}
687
688impl<const START_OFFSET: usize, const DIM: u8, const DIM_INCREMENT: u8, T, A>
689    RegisterFieldBool<START_OFFSET, DIM, DIM_INCREMENT, T, A>
690where
691    T: RegSpec,
692    A: Write,
693{
694    /// Prepare bitfield value to be written to register
695    ///
696    /// # Example
697    /// ```rust,ignore
698    /// // example with generic names
699    /// // get an instance by reading
700    /// let values = TIMER.bitfield_reg().read();
701    /// // or by starting with a known value
702    /// let value = timer::BitfieldReg::new(0);
703    /// // or by starting with the default
704    /// let value = timer::BitfieldReg::default();
705    ///
706    /// // set bitfield
707    /// let value = value
708    ///     .boolrw()
709    ///     .set(true);
710    ///
711    /// // up until now no hardware change has taken place, do that now by writing
712    /// TIMER.bitfield_reg().write(value);
713    /// ```
714    #[inline(always)]
715    #[must_use]
716    pub fn set(mut self, value: bool) -> RegValueT<T> {
717        let value: T::DataType = if value {
718            T::DataType::cast_from(1u64)
719        } else {
720            T::DataType::cast_from(0u64)
721        };
722        let offset = START_OFFSET + (self.index * DIM_INCREMENT) as usize;
723        let masked_offset = T::DataType::cast_from(0x1u64) << offset;
724        self.data.mask |= masked_offset;
725        self.data.data &= !masked_offset;
726        self.data.data |= value << offset;
727        self.data
728    }
729}
730
731impl<const START_OFFSET: usize, const DIM: u8, const DIM_INCREMENT: u8, T, A>
732    RegisterFieldBool<START_OFFSET, DIM, DIM_INCREMENT, T, A>
733where
734    T: RegSpec,
735    A: Access,
736{
737    #[inline(always)]
738    #[allow(dead_code)]
739    pub(crate) fn from_register(data: RegValueT<T>, index: u8) -> Self {
740        Self {
741            data,
742            index,
743            marker: PhantomData,
744        }
745    }
746
747    /// Get mask for bitfield, the mask is unshifted and at offset 0
748    ///
749    /// Prefer the use of [`RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>::get()`] to
750    /// extract a bitfield value.
751    #[inline(always)]
752    #[must_use]
753    pub fn mask(&self) -> T::DataType {
754        T::DataType::cast_from(1)
755    }
756
757    /// Get offset of bitfield in containing register
758    ///
759    /// Prefer the use of [`RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>::get()`] to
760    /// extract a bitfield value.
761    #[inline(always)]
762    #[must_use]
763    pub const fn offset(&self) -> usize {
764        START_OFFSET + (self.index * DIM_INCREMENT) as usize
765    }
766}
767
768/// An array of identical register clusters.
769pub struct ClusterRegisterArray<T: Sized, const DIM: usize, const DIM_INCREMENT: usize> {
770    _t: ::core::marker::PhantomData<T>,
771}
772
773impl<T: Sized, const DIM: usize, const DIM_INCREMENT: usize>
774    ClusterRegisterArray<T, DIM, DIM_INCREMENT>
775{
776    /// Returns the number of register blocks in the cluster.
777    #[inline(always)]
778    pub const fn len(&self) -> usize {
779        DIM
780    }
781
782    /// Returns whether the cluster is empty (DIM == 0).
783    #[inline(always)]
784    pub const fn is_empty(&self) -> bool {
785        DIM == 0
786    }
787
788    /// Returns an iterator over the elements of this cluster.
789    #[inline(always)]
790    pub fn iter(&self) -> impl ::core::iter::ExactSizeIterator<Item = &T> {
791        self.into_iter()
792    }
793
794    /// Returns the cluster element with the specified index.
795    ///
796    /// Panics if the index is out of bounds.
797    #[inline]
798    pub const fn get(&self, index: usize) -> &T {
799        assert!(index < DIM);
800        unsafe { self.get_unchecked(index) }
801    }
802
803    /// Returns the cluster element with the specified index.
804    ///
805    /// # Safety
806    ///
807    /// `index` must be less than `DIM`.
808    #[inline(always)]
809    pub const unsafe fn get_unchecked(&self, index: usize) -> &T {
810        unsafe { &*(self.as_ptr().add(index * DIM_INCREMENT) as *const _) }
811    }
812
813    #[allow(dead_code)]
814    #[inline(always)]
815    pub(crate) const unsafe fn from_ptr(ptr: *mut u8) -> &'static Self {
816        unsafe { &*(ptr as *const Self) }
817    }
818
819    #[inline(always)]
820    const fn as_ptr(&self) -> *mut u8 {
821        self as *const _ as *mut _
822    }
823}
824
825impl<T: Sized, const DIM: usize, const DIM_INCREMENT: usize> ::core::ops::Index<usize>
826    for ClusterRegisterArray<T, DIM, DIM_INCREMENT>
827{
828    type Output = T;
829
830    #[inline(always)]
831    fn index(&self, index: usize) -> &T {
832        self.get(index)
833    }
834}
835
836impl<'a, T: Sized, const DIM: usize, const DIM_INCREMENT: usize> IntoIterator
837    for &'a ClusterRegisterArray<T, DIM, DIM_INCREMENT>
838{
839    type Item = &'a T;
840    type IntoIter = ClusterRegisterArrayIterator<'a, T, DIM, DIM_INCREMENT>;
841
842    #[inline(always)]
843    fn into_iter(self) -> Self::IntoIter {
844        ClusterRegisterArrayIterator {
845            array: self,
846            index: 0,
847        }
848    }
849}
850
851pub struct ClusterRegisterArrayIterator<'a, T: Sized, const DIM: usize, const DIM_INCREMENT: usize>
852{
853    array: &'a ClusterRegisterArray<T, DIM, DIM_INCREMENT>,
854    index: usize,
855}
856
857impl<'a, T: Sized, const DIM: usize, const DIM_INCREMENT: usize> Iterator
858    for ClusterRegisterArrayIterator<'a, T, DIM, DIM_INCREMENT>
859{
860    type Item = &'a T;
861    #[inline(always)]
862    fn next(&mut self) -> Option<&'a T> {
863        if self.index < self.array.len() {
864            let result = &self.array[self.index];
865            self.index += 1;
866            Some(result)
867        } else {
868            None
869        }
870    }
871
872    #[inline(always)]
873    fn size_hint(&self) -> (usize, Option<usize>) {
874        let len = self.array.len() - self.index;
875        (len, Some(len))
876    }
877}
878
879impl<T: Sized, const DIM: usize, const DIM_INCREMENT: usize> ExactSizeIterator
880    for ClusterRegisterArrayIterator<'_, T, DIM, DIM_INCREMENT>
881{
882}