ra4e2_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.30.00, with svd2pac 0.4.0 on Sat, 12 Apr 2025 22:15:35 +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 #[inline(always)]
254 #[must_use]
255 pub(crate) const fn from_ptr(ptr: *mut u8) -> &'static Self {
256 unsafe { &*(ptr as *const Self) }
257 }
258
259 #[inline(always)]
260 #[must_use]
261 pub const fn ptr(&self) -> *mut T::DataType {
262 self as *const _ as *mut T::DataType
263 }
264
265 /// Returns the address of the register.
266 pub fn addr(&self) -> usize {
267 unsafe { (self as *const _) as usize }
268 }
269}
270
271impl<T, A> Reg<T, A>
272where
273 T: RegSpec,
274 A: Read,
275{
276 /// Read register and return a register value
277 ///
278 /// # Safety
279 /// Read operation could cause undefined behavior for some peripheral. Developer shall read device user manual.
280 /// Register is Send and Sync to allow complete freedom. Developer is responsible of proper use in interrupt and thread.
281 ///
282 /// # Example
283 /// ```rust,ignore
284 /// // example with generic names
285 /// let reg = unsafe { TIMER.bitfield_reg().read() };
286 /// if reg.boolr().get() { /* ... */ }
287 /// ```
288 #[inline(always)]
289 #[must_use]
290 pub unsafe fn read(&self) -> RegValueT<T> {
291 #[cfg(feature = "tracing")]
292 let val = {
293 let mut buf: u64 = 0x0;
294 tracing::READ_FN.with(|rf| {
295 if let Some(rf) = rf.get() {
296 buf = rf(self.addr(), std::mem::size_of::<T::DataType>());
297 } else {
298 #[cfg(not(feature = "tracing_dummy"))]
299 panic!(
300 "Please, provide an handler for read with tracing::set_read_fn(callback);"
301 );
302 }
303 });
304 T::DataType::cast_from(buf)
305 };
306 #[cfg(not(feature = "tracing"))]
307 let val = self.ptr().read_volatile();
308 RegValueT::<T>::new(val)
309 }
310}
311
312impl<T, A> Reg<T, A>
313where
314 T: RegSpec,
315 A: Write,
316{
317 /// Write register value back to register
318 ///
319 /// # Arguments
320 ///
321 /// * `reg_value` - A string slice that holds the name of the person
322 ///
323 /// # Safety
324 /// Write operation could cause undefined behavior for some peripheral. Developers shall read the device user manual.
325 /// Register is Send and Sync to allow complete freedom. Developers are responsible of proper use in interrupt and thread.
326 ///
327 /// # Example
328 /// ```rust,ignore
329 /// // example with generic names
330 /// // write with a previously read value
331 /// let reg = unsafe { TIMER.bitfield_reg().read() };
332 /// // or start with a known value
333 /// let reg = timer::BitfieldReg::new(0).bitfieldw().set(0x55);
334 /// // or start with the register default
335 /// let reg = timer::BitfieldReg::default();
336 ///
337 /// let reg = reg.bitfieldrw().set(0x77);
338 ///
339 /// // no change has taken place to the register due to `set` calls - do that now by writing back the result
340 /// unsafe { TIMER.bitfield_reg().write(reg) }
341 /// ```
342 /// See also: [`Reg<T, A>::init`] which provides the default value to a closure
343 #[inline(always)]
344 pub unsafe fn write(&self, reg_value: RegValueT<T>) {
345 #[cfg(feature = "tracing")]
346 tracing::WRITE_FN.with(|wf| {
347 if let Some(wf) = wf.get() {
348 wf(
349 self.addr(),
350 std::mem::size_of::<T::DataType>(),
351 reg_value.data.into(),
352 )
353 } else {
354 #[cfg(not(feature = "tracing_dummy"))]
355 panic!("Please, provide an handler for read with tracing::set_read_fn(callback);");
356 }
357 });
358 #[cfg(not(feature = "tracing"))]
359 self.ptr().write_volatile(reg_value.data);
360 }
361
362 /// Write an arbitrary integer to register
363 ///
364 /// Use this function when e.g. loading data to be written from a config-page.
365 /// For normal use prefer either [`Reg<T, A>::write`] if the value was read before, or [`Reg<T, A>::init`],
366 /// both of which provide some restrictions available register fields, enums, etc.
367 ///
368 /// # Arguments
369 ///
370 /// * `value` - The unchecked value to be written to the register
371 ///
372 /// # Safety
373 ///
374 /// Write operation could cause undefined behavior for some peripheral. Developers shall read the device user manual.
375 /// Register is Send and Sync to allow complete freedom. Developers are responsible of proper use in interrupt and thread.
376 ///
377 /// # Example
378 /// ```rust,ignore
379 /// // example with generic names
380 /// unsafe { TIMER.bitfield_reg().write_raw(0xdead) }
381 /// ```
382 /// See also [`Reg<T, A>::init`] and [`Reg<T, A>::write`] both of which are the safe, preferred functions.
383 #[inline(always)]
384 pub unsafe fn write_raw(&self, value: T::DataType) {
385 #[cfg(feature = "tracing")]
386 tracing::WRITE_FN.with(|wf| {
387 if let Some(wf) = wf.get() {
388 wf(
389 self.addr(),
390 std::mem::size_of::<T::DataType>(),
391 value.into(),
392 )
393 } else {
394 #[cfg(not(feature = "tracing_dummy"))]
395 panic!("Please, provide an handler for read with tracing::set_read_fn(callback);");
396 }
397 });
398 #[cfg(not(feature = "tracing"))]
399 self.ptr().write_volatile(value);
400 }
401}
402
403impl<T, A> Reg<T, A>
404where
405 T: RegSpec,
406 A: Write,
407 RegValueT<T>: Default,
408{
409 /// Write register with register value built from default register value
410 ///
411 /// # Arguments
412 ///
413 /// * `f` - Closure that receive as input a register value initialized with register value at Power On Reset.
414 ///
415 /// # Safety
416 /// Write operation could cause undefined behavior for some peripheral. Developer shall read device user manual.
417 /// Register is Send and Sync to allow complete freedom. Developer is responsible of proper use in interrupt and thread.
418 ///
419 /// # Example
420 /// ```rust,ignore
421 /// // example with generic names
422 /// TIMER
423 /// .bitfield_reg()
424 /// .init(|r| r.bitfieldw().set(0b1010).boolw().set(true));
425 /// ```
426 #[inline(always)]
427 /// Write value computed by closure that receive as input the reset value of register
428 pub unsafe fn init(&self, f: impl FnOnce(RegValueT<T>) -> RegValueT<T>) {
429 let val = RegValueT::<T>::default();
430 let res = f(val);
431 self.write(res);
432 }
433}
434
435impl<T, A> Reg<T, A>
436where
437 T: RegSpec,
438 A: Read + Write,
439{
440 /// Read/modify/write register
441 ///
442 /// # Arguments
443 ///
444 /// * `f` - Closure that receive as input a register value read from register. The result of the closure
445 /// is written back to the register.
446 ///
447 /// # Safety
448 /// Write operation could cause undefined behavior for some peripheral. Developer shall read device user manual.
449 /// Register is Send and Sync to allow complete freedom. Developer is responsible of proper use in interrupt and thread.
450 ///
451 /// # Example
452 /// ```rust,ignore
453 /// // example with generic names
454 /// TIMER
455 /// .bitfield_reg()
456 /// .modify(|r| r.boolrw().set(!r.boolrw().get()));
457 /// ```
458 #[inline(always)]
459 pub unsafe fn modify(&self, f: impl FnOnce(RegValueT<T>) -> RegValueT<T>) {
460 let val = self.read();
461 let res = f(val);
462 self.write(res);
463 }
464}
465
466/// Proxy struct for enumerated bitfields
467#[repr(transparent)]
468#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
469pub struct EnumBitfieldStruct<Q: RegNumberT, T>(pub Q, PhantomData<T>);
470
471impl<Q: RegNumberT, T> EnumBitfieldStruct<Q, T> {
472 pub const fn new(value: Q) -> Self {
473 Self(value, PhantomData)
474 }
475}
476
477impl<Q: RegNumberT, T> From<EnumBitfieldStruct<Q, T>> for u64 {
478 #[inline(always)]
479 fn from(value: EnumBitfieldStruct<Q, T>) -> Self {
480 value.0.into()
481 }
482}
483impl<Q: RegNumberT, T> CastFrom<u64> for EnumBitfieldStruct<Q, T> {
484 #[inline(always)]
485 fn cast_from(val: u64) -> Self {
486 Self(Q::cast_from(val), PhantomData)
487 }
488}
489
490impl<Q: RegNumberT, T> From<Q> for EnumBitfieldStruct<Q, T> {
491 #[inline(always)]
492 fn from(value: Q) -> Self {
493 Self(value, PhantomData)
494 }
495}
496
497/// Proxy struct for numeric bitfields
498pub struct RegisterField<
499 const START_OFFSET: usize,
500 const MASK: u64,
501 const DIM: u8,
502 const DIM_INCREMENT: u8,
503 ValueType,
504 T,
505 A,
506> where
507 T: RegSpec,
508 A: Access,
509{
510 data: RegValueT<T>,
511 index: u8,
512 marker: PhantomData<(ValueType, A)>,
513}
514
515impl<
516 const START_OFFSET: usize,
517 const MASK: u64,
518 const DIM: u8,
519 const DIM_INCREMENT: u8,
520 ValueType,
521 T,
522 A,
523 > RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>
524where
525 T: RegSpec,
526 A: Access,
527{
528 #[allow(dead_code)]
529 #[inline(always)]
530 pub(crate) fn from_register(data: RegValueT<T>, index: u8) -> Self {
531 Self {
532 data,
533 index,
534 marker: PhantomData,
535 }
536 }
537
538 /// Get mask for bitfield, the mask is unshifted and at offset 0
539 ///
540 /// Prefer the use of [`RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>::get()`] to
541 /// extract a bitfield value.
542 #[inline(always)]
543 #[must_use]
544 pub fn mask(&self) -> T::DataType {
545 T::DataType::cast_from(MASK)
546 }
547
548 /// Get offset of bitfield in containing register
549 ///
550 /// Prefer the use of [`RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>::get()`] to
551 /// extract a bitfield value.
552 #[inline(always)]
553 #[must_use]
554 pub const fn offset(&self) -> usize {
555 START_OFFSET + (self.index * DIM_INCREMENT) as usize
556 }
557}
558
559impl<
560 const START_OFFSET: usize,
561 const MASK: u64,
562 const DIM: u8,
563 const DIM_INCREMENT: u8,
564 ValueType,
565 T,
566 A,
567 > RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>
568where
569 T: RegSpec,
570 A: Read,
571 ValueType: CastFrom<u64>,
572{
573 /// Extract bitfield from read register value
574 #[inline(always)]
575 pub fn get(&self) -> ValueType {
576 let offset = START_OFFSET + (self.index * DIM_INCREMENT) as usize;
577 let filtered: T::DataType = (self.data.data >> offset) & T::DataType::cast_from(MASK);
578 ValueType::cast_from(filtered.into())
579 }
580}
581
582impl<
583 const START_OFFSET: usize,
584 const MASK: u64,
585 const DIM: u8,
586 const DIM_INCREMENT: u8,
587 ValueType,
588 T,
589 A,
590 > RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>
591where
592 T: RegSpec,
593 A: Write,
594 u64: From<ValueType>,
595{
596 /// Prepare bitfield value that could be written to register
597 ///
598 /// # Example
599 /// ```rust,ignore
600 /// // example with generic names
601 /// // get an instance by reading
602 /// let values = TIMER.bitfield_reg().read();
603 /// // or by starting with a known value
604 /// let value = timer::BitfieldReg::new(0);
605 /// // or by starting with the default
606 /// let value = timer::BitfieldReg::default();
607 ///
608 /// // set bitfields
609 /// let value = value
610 /// // set numeric bitfield
611 /// .bitfieldw()
612 /// .set(0x55)
613 /// // set enumerated bitfield with enumeration
614 /// .bitfieldenumerated()
615 /// .set(timer::bitfield_reg::BitfieldEnumerated::GPIOA_0)
616 /// // set enumerated bitfield from integer
617 /// .bitfieldenumerated()
618 /// .set(1.into());
619 ///
620 /// // up until now no hardware change has taken place, do that now by writing
621 /// TIMER.bitfield_reg().write(value);
622 /// ```
623 #[inline(always)]
624 #[must_use]
625 pub fn set(mut self, value: ValueType) -> RegValueT<T> {
626 let mask = T::DataType::cast_from(MASK);
627 let value: T::DataType = T::DataType::cast_from(Into::<u64>::into(value)) & mask;
628 let offset = START_OFFSET + (self.index * DIM_INCREMENT) as usize;
629 let masked_offset: T::DataType = mask << offset;
630 self.data.mask |= masked_offset;
631 self.data.data &= !masked_offset;
632 self.data.data |= value << offset;
633 self.data
634 }
635}
636
637/// Proxy struct for boolean bitfields
638pub struct RegisterFieldBool<
639 const START_OFFSET: usize,
640 const DIM: u8,
641 const DIM_INCREMENT: u8,
642 T,
643 A,
644> where
645 T: RegSpec,
646 A: Access,
647{
648 data: RegValueT<T>,
649 index: u8,
650 marker: PhantomData<A>,
651}
652
653impl<const START_OFFSET: usize, const DIM: u8, const DIM_INCREMENT: u8, T, A>
654 RegisterFieldBool<START_OFFSET, DIM, DIM_INCREMENT, T, A>
655where
656 T: RegSpec,
657 A: Read,
658{
659 /// Extract bitfield from read register value
660 #[inline(always)]
661 pub fn get(&self) -> bool {
662 let offset = START_OFFSET + (self.index * DIM_INCREMENT) as usize;
663 let filtered = (self.data.data.into() >> offset) & 1;
664 filtered == 1
665 }
666}
667
668impl<const START_OFFSET: usize, const DIM: u8, const DIM_INCREMENT: u8, T, A>
669 RegisterFieldBool<START_OFFSET, DIM, DIM_INCREMENT, T, A>
670where
671 T: RegSpec,
672 A: Write,
673{
674 /// Prepare bitfield value to be written to register
675 ///
676 /// # Example
677 /// ```rust,ignore
678 /// // example with generic names
679 /// // get an instance by reading
680 /// let values = TIMER.bitfield_reg().read();
681 /// // or by starting with a known value
682 /// let value = timer::BitfieldReg::new(0);
683 /// // or by starting with the default
684 /// let value = timer::BitfieldReg::default();
685 ///
686 /// // set bitfield
687 /// let value = value
688 /// .boolrw()
689 /// .set(true);
690 ///
691 /// // up until now no hardware change has taken place, do that now by writing
692 /// TIMER.bitfield_reg().write(value);
693 /// ```
694 #[inline(always)]
695 #[must_use]
696 pub fn set(mut self, value: bool) -> RegValueT<T> {
697 let value: T::DataType = if value {
698 T::DataType::cast_from(1u64)
699 } else {
700 T::DataType::cast_from(0u64)
701 };
702 let offset = START_OFFSET + (self.index * DIM_INCREMENT) as usize;
703 let masked_offset = T::DataType::cast_from(0x1u64) << offset;
704 self.data.mask |= masked_offset;
705 self.data.data &= !masked_offset;
706 self.data.data |= value << offset;
707 self.data
708 }
709}
710
711impl<const START_OFFSET: usize, const DIM: u8, const DIM_INCREMENT: u8, T, A>
712 RegisterFieldBool<START_OFFSET, DIM, DIM_INCREMENT, T, A>
713where
714 T: RegSpec,
715 A: Access,
716{
717 #[inline(always)]
718 #[allow(dead_code)]
719 pub(crate) fn from_register(data: RegValueT<T>, index: u8) -> Self {
720 Self {
721 data,
722 index,
723 marker: PhantomData,
724 }
725 }
726
727 /// Get mask for bitfield, the mask is unshifted and at offset 0
728 ///
729 /// Prefer the use of [`RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>::get()`] to
730 /// extract a bitfield value.
731 #[inline(always)]
732 #[must_use]
733 pub fn mask(&self) -> T::DataType {
734 T::DataType::cast_from(1)
735 }
736
737 /// Get offset of bitfield in containing register
738 ///
739 /// Prefer the use of [`RegisterField<START_OFFSET, MASK, DIM, DIM_INCREMENT, ValueType, T, A>::get()`] to
740 /// extract a bitfield value.
741 #[inline(always)]
742 #[must_use]
743 pub const fn offset(&self) -> usize {
744 START_OFFSET + (self.index * DIM_INCREMENT) as usize
745 }
746}
747
748/// An array of identical register clusters.
749pub struct ClusterRegisterArray<T: Sized, const DIM: usize, const DIM_INCREMENT: usize> {
750 _t: ::core::marker::PhantomData<T>,
751}
752
753impl<T: Sized, const DIM: usize, const DIM_INCREMENT: usize>
754 ClusterRegisterArray<T, DIM, DIM_INCREMENT>
755{
756 /// Returns the number of register blocks in the cluster.
757 #[inline(always)]
758 pub const fn len(&self) -> usize {
759 DIM
760 }
761
762 /// Returns whether the cluster is empty (DIM == 0).
763 #[inline(always)]
764 pub const fn is_empty(&self) -> bool {
765 DIM == 0
766 }
767
768 /// Returns an iterator over the elements of this cluster.
769 #[inline(always)]
770 pub fn iter(&self) -> impl ::core::iter::ExactSizeIterator<Item = &T> {
771 self.into_iter()
772 }
773
774 /// Returns the cluster element with the specified index.
775 ///
776 /// Panics if the index is out of bounds.
777 #[inline]
778 pub const fn get(&self, index: usize) -> &T {
779 assert!(index < DIM);
780 unsafe { self.get_unchecked(index) }
781 }
782
783 /// Returns the cluster element with the specified index.
784 ///
785 /// # Safety
786 ///
787 /// `index` must be less than `DIM`.
788 #[inline(always)]
789 pub const unsafe fn get_unchecked(&self, index: usize) -> &T {
790 &*(self.as_ptr().add(index * DIM_INCREMENT) as *const _)
791 }
792
793 #[inline(always)]
794 pub(crate) const unsafe fn from_ptr(ptr: *mut u8) -> &'static Self {
795 &*(ptr as *const Self)
796 }
797
798 #[inline(always)]
799 const fn as_ptr(&self) -> *mut u8 {
800 self as *const _ as *mut _
801 }
802}
803
804impl<T: Sized, const DIM: usize, const DIM_INCREMENT: usize> ::core::ops::Index<usize>
805 for ClusterRegisterArray<T, DIM, DIM_INCREMENT>
806{
807 type Output = T;
808
809 #[inline(always)]
810 fn index(&self, index: usize) -> &T {
811 self.get(index)
812 }
813}
814
815impl<'a, T: Sized, const DIM: usize, const DIM_INCREMENT: usize> IntoIterator
816 for &'a ClusterRegisterArray<T, DIM, DIM_INCREMENT>
817{
818 type Item = &'a T;
819 type IntoIter = ClusterRegisterArrayIterator<'a, T, DIM, DIM_INCREMENT>;
820
821 #[inline(always)]
822 fn into_iter(self) -> Self::IntoIter {
823 ClusterRegisterArrayIterator {
824 array: self,
825 index: 0,
826 }
827 }
828}
829
830pub struct ClusterRegisterArrayIterator<'a, T: Sized, const DIM: usize, const DIM_INCREMENT: usize>
831{
832 array: &'a ClusterRegisterArray<T, DIM, DIM_INCREMENT>,
833 index: usize,
834}
835
836impl<'a, T: Sized, const DIM: usize, const DIM_INCREMENT: usize> Iterator
837 for ClusterRegisterArrayIterator<'a, T, DIM, DIM_INCREMENT>
838{
839 type Item = &'a T;
840 #[inline(always)]
841 fn next(&mut self) -> Option<&'a T> {
842 if self.index < self.array.len() {
843 let result = &self.array[self.index];
844 self.index += 1;
845 Some(result)
846 } else {
847 None
848 }
849 }
850
851 #[inline(always)]
852 fn size_hint(&self) -> (usize, Option<usize>) {
853 let len = self.array.len() - self.index;
854 (len, Some(len))
855 }
856}
857
858impl<T: Sized, const DIM: usize, const DIM_INCREMENT: usize> ExactSizeIterator
859 for ClusterRegisterArrayIterator<'_, T, DIM, DIM_INCREMENT>
860{
861}