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