1use core::marker::PhantomData;
2
3use crate::{
4 Address, AddressMode, Append, ArrayRepeating, Block, Fieldset, FieldsetMetadata, NotRepeating,
5 RO, RW, ReadCapability, Repeating, ToTuple, WO, WriteCapability,
6};
7
8#[cfg(feature = "defmt")]
9use defmt::panic;
10
11pub trait RegisterInterfaceBase {
13 type Error;
15 type AddressType: Address;
17}
18
19impl<T: RegisterInterfaceBase> RegisterInterfaceBase for &mut T {
20 type Error = T::Error;
21 type AddressType = T::AddressType;
22}
23
24#[diagnostic::on_unimplemented(
25 label = "cannot use blocking register operations when the device interface doesn't know how to read and write registers",
26 note = "to enable register operations, implement the trait on this type"
27)]
28pub trait RegisterInterface: RegisterInterfaceBase {
32 fn write_register(
34 &mut self,
35 address: Self::AddressType,
36 data: &mut [u8],
37 _metadata: &FieldsetMetadata,
38 ) -> Result<(), Self::Error>;
39
40 fn read_register(
42 &mut self,
43 address: Self::AddressType,
44 data: &mut [u8],
45 _metadata: &FieldsetMetadata,
46 ) -> Result<(), Self::Error>;
47}
48
49#[diagnostic::do_not_recommend]
50impl<T: RegisterInterface> RegisterInterface for &mut T {
51 fn write_register(
52 &mut self,
53 address: Self::AddressType,
54 data: &mut [u8],
55 metadata: &FieldsetMetadata,
56 ) -> Result<(), Self::Error> {
57 (*self).write_register(address, data, metadata)
58 }
59
60 fn read_register(
61 &mut self,
62 address: Self::AddressType,
63 data: &mut [u8],
64 metadata: &FieldsetMetadata,
65 ) -> Result<(), Self::Error> {
66 (*self).read_register(address, data, metadata)
67 }
68}
69
70#[diagnostic::on_unimplemented(
71 label = "cannot use async register operations when the device interface doesn't know how to read and write registers",
72 note = "to enable register operations, implement the trait on this type"
73)]
74pub trait AsyncRegisterInterface: RegisterInterfaceBase {
78 async fn write_register(
80 &mut self,
81 address: Self::AddressType,
82 data: &mut [u8],
83 _metadata: &FieldsetMetadata,
84 ) -> Result<(), Self::Error>;
85
86 async fn read_register(
88 &mut self,
89 address: Self::AddressType,
90 data: &mut [u8],
91 _metadata: &FieldsetMetadata,
92 ) -> Result<(), Self::Error>;
93}
94
95#[diagnostic::do_not_recommend]
96impl<T: AsyncRegisterInterface> AsyncRegisterInterface for &mut T {
97 fn write_register(
98 &mut self,
99 address: Self::AddressType,
100 data: &mut [u8],
101 metadata: &FieldsetMetadata,
102 ) -> impl Future<Output = Result<(), Self::Error>> {
103 (*self).write_register(address, data, metadata)
104 }
105
106 fn read_register(
107 &mut self,
108 address: Self::AddressType,
109 data: &mut [u8],
110 metadata: &FieldsetMetadata,
111 ) -> impl Future<Output = Result<(), Self::Error>> {
112 (*self).read_register(address, data, metadata)
113 }
114}
115
116pub struct RegisterOperation<'b, B, RegisterFs, AddressType, Access, Repeat>
118where
119 B: Block,
120 B::Interface: RegisterInterfaceBase<AddressType = AddressType>,
121 RegisterFs: Fieldset,
122 AddressType: Address,
123{
124 block: &'b mut B,
125 address: AddressType,
126 register_new_with_reset: fn() -> RegisterFs,
127 _phantom: PhantomData<(RegisterFs, Access, Repeat)>,
128}
129
130impl<'b, B, RegisterFs, AddressType, Access, Repeat>
131 RegisterOperation<'b, B, RegisterFs, AddressType, Access, Repeat>
132where
133 RegisterFs: Fieldset,
134 B: Block,
135 B::Interface: RegisterInterfaceBase<AddressType = AddressType>,
136 AddressType: Address,
137{
138 #[doc(hidden)]
139 pub fn new(
140 block: &'b mut B,
141 address: AddressType,
142 register_new_with_reset: fn() -> RegisterFs,
143 ) -> Self {
144 Self {
145 block,
146 address,
147 register_new_with_reset,
148 _phantom: PhantomData,
149 }
150 }
151
152 pub fn address(&self) -> AddressType {
154 self.address
155 }
156
157 pub fn reset_value(&self) -> RegisterFs {
159 (self.register_new_with_reset)()
160 }
161
162 pub fn plan(&self) -> Plan<AddressType, RegisterFs, Access>
164 where
165 Repeat: NotRepeating,
166 {
167 Plan {
168 address: self.address(),
169 value: self.reset_value(),
170 _phantom: PhantomData,
171 }
172 }
173
174 #[track_caller]
176 pub fn plan_at(&self, index: Repeat::Index) -> Plan<AddressType, RegisterFs, Access>
177 where
178 Repeat: Repeating,
179 {
180 Plan {
181 address: Repeat::calc_address(self.address, index),
182 value: self.reset_value(),
183 _phantom: PhantomData,
184 }
185 }
186
187 #[track_caller]
189 pub fn plan_with_zero(&self) -> Plan<AddressType, RegisterFs, Access>
190 where
191 Repeat: NotRepeating,
192 Access: WriteCapability,
193 {
194 Plan {
195 address: self.address(),
196 value: RegisterFs::ZERO,
197 _phantom: PhantomData,
198 }
199 }
200
201 #[track_caller]
203 pub fn plan_with_zero_at(&self, index: Repeat::Index) -> Plan<AddressType, RegisterFs, Access>
204 where
205 Repeat: Repeating,
206 Access: WriteCapability,
207 {
208 Plan {
209 address: Repeat::calc_address(self.address, index),
210 value: RegisterFs::ZERO,
211 _phantom: PhantomData,
212 }
213 }
214
215 #[track_caller]
217 pub fn plan_array_at<const N: usize>(
218 self,
219 index: Repeat::Index,
220 ) -> Plan<AddressType, [RegisterFs; N], Access>
221 where
222 Repeat: ArrayRepeating,
223 B::RegisterAddressMode: AddressMode,
224 {
225 Repeat::assert_len_and_index(N, index.clone());
226
227 let address = Repeat::calc_address(self.address, index);
228 Self::assert_array_op_legal(address);
229
230 Plan {
231 address,
232 value: core::array::from_fn(|_| self.reset_value()),
233 _phantom: PhantomData,
234 }
235 }
236
237 #[track_caller]
239 pub fn plan_array_with_zero_at<const N: usize>(
240 self,
241 index: Repeat::Index,
242 ) -> Plan<AddressType, [RegisterFs; N], Access>
243 where
244 Repeat: ArrayRepeating,
245 B::RegisterAddressMode: AddressMode,
246 Access: WriteCapability,
247 {
248 Repeat::assert_len_and_index(N, index.clone());
249
250 let address = Repeat::calc_address(self.address, index);
251 Self::assert_array_op_legal(address);
252
253 Plan {
254 address,
255 value: Fieldset::ZERO,
256 _phantom: PhantomData,
257 }
258 }
259
260 #[track_caller]
265 pub fn write(
266 self,
267 f: impl FnOnce(&mut RegisterFs),
268 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
269 where
270 Repeat: NotRepeating,
271 B::Interface: RegisterInterface,
272 Access: WriteCapability,
273 {
274 let mut register = (self.register_new_with_reset)();
275 f(&mut register);
276
277 self.block.interface().write_register(
278 self.address,
279 register.as_slice_mut(),
280 &RegisterFs::METADATA,
281 )
282 }
283
284 #[track_caller]
289 pub fn write_at(
290 self,
291 index: Repeat::Index,
292 f: impl FnOnce(&mut RegisterFs),
293 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
294 where
295 Repeat: Repeating,
296 B::Interface: RegisterInterface,
297 Access: WriteCapability,
298 {
299 let mut register = (self.register_new_with_reset)();
300 f(&mut register);
301
302 self.block.interface().write_register(
303 Repeat::calc_address(self.address, index),
304 register.as_slice_mut(),
305 &RegisterFs::METADATA,
306 )
307 }
308
309 #[track_caller]
314 pub fn write_array_at<const N: usize>(
315 self,
316 index: Repeat::Index,
317 f: impl FnOnce(&mut [RegisterFs; N]),
318 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
319 where
320 Repeat: ArrayRepeating,
321 B::Interface: RegisterInterface,
322 B::RegisterAddressMode: AddressMode,
323 Access: WriteCapability,
324 {
325 Repeat::assert_len_and_index(N, index.clone());
326
327 let mut register = core::array::from_fn(|_| (self.register_new_with_reset)());
328 f(&mut register);
329
330 let address = Repeat::calc_address(self.address, index);
331 Self::assert_array_op_legal(address);
332
333 self.block.interface().write_register(
334 address,
335 register.as_slice_mut(),
336 &RegisterFs::METADATA,
337 )
338 }
339
340 #[track_caller]
345 pub fn write_async(
346 self,
347 f: impl FnOnce(&mut RegisterFs),
348 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
349 where
350 Repeat: NotRepeating,
351 B::Interface: AsyncRegisterInterface,
352 Access: WriteCapability,
353 {
354 let mut register = (self.register_new_with_reset)();
355 f(&mut register);
356
357 async move {
358 self.block
359 .interface()
360 .write_register(self.address, register.as_slice_mut(), &RegisterFs::METADATA)
361 .await
362 }
363 }
364
365 #[track_caller]
370 pub fn write_at_async(
371 self,
372 index: Repeat::Index,
373 f: impl FnOnce(&mut RegisterFs),
374 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
375 where
376 Repeat: Repeating,
377 B::Interface: AsyncRegisterInterface,
378 Access: WriteCapability,
379 {
380 let mut register = (self.register_new_with_reset)();
381 f(&mut register);
382
383 let address = Repeat::calc_address(self.address, index);
384
385 async move {
386 self.block
387 .interface()
388 .write_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
389 .await
390 }
391 }
392
393 #[track_caller]
398 pub fn write_array_at_async<const N: usize>(
399 self,
400 index: Repeat::Index,
401 f: impl FnOnce(&mut [RegisterFs; N]),
402 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
403 where
404 Repeat: ArrayRepeating,
405 B::Interface: AsyncRegisterInterface,
406 B::RegisterAddressMode: AddressMode,
407 Access: WriteCapability,
408 {
409 Repeat::assert_len_and_index(N, index.clone());
410
411 let mut register = core::array::from_fn(|_| (self.register_new_with_reset)());
412 f(&mut register);
413
414 let address = Repeat::calc_address(self.address, index);
415 Self::assert_array_op_legal(address);
416
417 async move {
418 self.block
419 .interface()
420 .write_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
421 .await
422 }
423 }
424
425 #[track_caller]
429 pub fn write_with_zero(
430 self,
431 f: impl FnOnce(&mut RegisterFs),
432 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
433 where
434 Repeat: NotRepeating,
435 B::Interface: RegisterInterface,
436 Access: WriteCapability,
437 {
438 let mut register = RegisterFs::ZERO;
439 f(&mut register);
440
441 self.block.interface().write_register(
442 self.address,
443 register.as_slice_mut(),
444 &RegisterFs::METADATA,
445 )
446 }
447
448 #[track_caller]
452 pub fn write_with_zero_at(
453 self,
454 index: Repeat::Index,
455 f: impl FnOnce(&mut RegisterFs),
456 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
457 where
458 Repeat: Repeating,
459 B::Interface: RegisterInterface,
460 Access: WriteCapability,
461 {
462 let mut register = RegisterFs::ZERO;
463 f(&mut register);
464
465 self.block.interface().write_register(
466 Repeat::calc_address(self.address, index),
467 register.as_slice_mut(),
468 &RegisterFs::METADATA,
469 )
470 }
471
472 #[track_caller]
476 pub fn write_array_with_zero_at<const N: usize>(
477 self,
478 index: Repeat::Index,
479 f: impl FnOnce(&mut [RegisterFs; N]),
480 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
481 where
482 Repeat: ArrayRepeating,
483 B::Interface: RegisterInterface,
484 B::RegisterAddressMode: AddressMode,
485 Access: WriteCapability,
486 {
487 Repeat::assert_len_and_index(N, index.clone());
488
489 let mut register = <[RegisterFs; N] as Fieldset>::ZERO;
490 f(&mut register);
491
492 let address = Repeat::calc_address(self.address, index);
493 Self::assert_array_op_legal(address);
494
495 self.block.interface().write_register(
496 address,
497 register.as_slice_mut(),
498 &RegisterFs::METADATA,
499 )
500 }
501
502 #[track_caller]
506 pub fn write_with_zero_async(
507 self,
508 f: impl FnOnce(&mut RegisterFs),
509 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
510 where
511 Repeat: NotRepeating,
512 B::Interface: AsyncRegisterInterface,
513 Access: WriteCapability,
514 {
515 let mut register = RegisterFs::ZERO;
516 f(&mut register);
517
518 async move {
519 self.block
520 .interface()
521 .write_register(self.address, register.as_slice_mut(), &RegisterFs::METADATA)
522 .await
523 }
524 }
525
526 #[track_caller]
530 pub fn write_with_zero_at_async(
531 self,
532 index: Repeat::Index,
533 f: impl FnOnce(&mut RegisterFs),
534 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
535 where
536 Repeat: Repeating,
537 B::Interface: AsyncRegisterInterface,
538 Access: WriteCapability,
539 {
540 let mut register = RegisterFs::ZERO;
541 f(&mut register);
542
543 let address = Repeat::calc_address(self.address, index);
544
545 async move {
546 self.block
547 .interface()
548 .write_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
549 .await
550 }
551 }
552
553 #[track_caller]
557 pub fn write_array_with_zero_at_async<const N: usize>(
558 self,
559 index: Repeat::Index,
560 f: impl FnOnce(&mut [RegisterFs; N]),
561 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
562 where
563 Repeat: ArrayRepeating,
564 B::Interface: AsyncRegisterInterface,
565 B::RegisterAddressMode: AddressMode,
566 Access: WriteCapability,
567 {
568 Repeat::assert_len_and_index(N, index.clone());
569
570 let mut register = <[RegisterFs; N] as Fieldset>::ZERO;
571 f(&mut register);
572
573 let address = Repeat::calc_address(self.address, index);
574 Self::assert_array_op_legal(address);
575
576 async move {
577 self.block
578 .interface()
579 .write_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
580 .await
581 }
582 }
583
584 #[track_caller]
586 pub fn read(self) -> Result<RegisterFs, <B::Interface as RegisterInterfaceBase>::Error>
587 where
588 Repeat: NotRepeating,
589 B::Interface: RegisterInterface,
590 Access: ReadCapability,
591 {
592 let mut register = RegisterFs::ZERO;
593
594 self.block
595 .interface()
596 .read_register(self.address, register.as_slice_mut(), &RegisterFs::METADATA)
597 .map(|_| register)
598 }
599
600 #[track_caller]
602 pub fn read_at(
603 self,
604 index: Repeat::Index,
605 ) -> Result<RegisterFs, <B::Interface as RegisterInterfaceBase>::Error>
606 where
607 Repeat: Repeating,
608 B::Interface: RegisterInterface,
609 Access: ReadCapability,
610 {
611 let mut register = RegisterFs::ZERO;
612
613 self.block
614 .interface()
615 .read_register(
616 Repeat::calc_address(self.address, index),
617 register.as_slice_mut(),
618 &RegisterFs::METADATA,
619 )
620 .map(|_| register)
621 }
622
623 #[track_caller]
625 pub fn read_array_at<const N: usize>(
626 self,
627 index: Repeat::Index,
628 ) -> Result<[RegisterFs; N], <B::Interface as RegisterInterfaceBase>::Error>
629 where
630 Repeat: ArrayRepeating,
631 B::Interface: RegisterInterface,
632 B::RegisterAddressMode: AddressMode,
633 Access: ReadCapability,
634 {
635 Repeat::assert_len_and_index(N, index.clone());
636
637 let mut register = <[RegisterFs; N] as Fieldset>::ZERO;
638 let address = Repeat::calc_address(self.address, index);
639 Self::assert_array_op_legal(address);
640
641 self.block
642 .interface()
643 .read_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
644 .map(|_| register)
645 }
646
647 #[track_caller]
649 pub fn read_async(
650 self,
651 ) -> impl Future<Output = Result<RegisterFs, <B::Interface as RegisterInterfaceBase>::Error>>
652 where
653 Repeat: NotRepeating,
654 B::Interface: AsyncRegisterInterface,
655 Access: ReadCapability,
656 {
657 let mut register = RegisterFs::ZERO;
658
659 async move {
660 self.block
661 .interface()
662 .read_register(self.address, register.as_slice_mut(), &RegisterFs::METADATA)
663 .await
664 .map(|_| register)
665 }
666 }
667
668 pub fn read_at_async(
670 self,
671 index: Repeat::Index,
672 ) -> impl Future<Output = Result<RegisterFs, <B::Interface as RegisterInterfaceBase>::Error>>
673 where
674 Repeat: Repeating,
675 B::Interface: AsyncRegisterInterface,
676 B::RegisterAddressMode: AddressMode,
677 Access: ReadCapability,
678 {
679 let mut register = RegisterFs::ZERO;
680 let address = Repeat::calc_address(self.address, index);
681
682 async move {
683 self.block
684 .interface()
685 .read_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
686 .await
687 .map(|_| register)
688 }
689 }
690
691 pub fn read_array_at_async<const N: usize>(
693 self,
694 index: Repeat::Index,
695 ) -> impl Future<Output = Result<[RegisterFs; N], <B::Interface as RegisterInterfaceBase>::Error>>
696 where
697 Repeat: ArrayRepeating,
698 B::Interface: AsyncRegisterInterface,
699 B::RegisterAddressMode: AddressMode,
700 Access: ReadCapability,
701 {
702 Repeat::assert_len_and_index(N, index.clone());
703
704 let mut register = <[RegisterFs; N] as Fieldset>::ZERO;
705 let address = Repeat::calc_address(self.address, index);
706 Self::assert_array_op_legal(address);
707
708 async move {
709 self.block
710 .interface()
711 .read_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
712 .await
713 .map(|_| register)
714 }
715 }
716
717 #[track_caller]
722 pub fn modify(
723 self,
724 f: impl FnOnce(&mut RegisterFs),
725 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
726 where
727 Repeat: NotRepeating,
728 B::Interface: RegisterInterface,
729 Access: ReadCapability + WriteCapability,
730 {
731 let mut register = RegisterFs::ZERO;
732
733 self.block.interface().read_register(
734 self.address,
735 register.as_slice_mut(),
736 &RegisterFs::METADATA,
737 )?;
738
739 f(&mut register);
740
741 self.block.interface().write_register(
742 self.address,
743 register.as_slice_mut(),
744 &RegisterFs::METADATA,
745 )
746 }
747
748 #[track_caller]
753 pub fn modify_at(
754 self,
755 index: Repeat::Index,
756 f: impl FnOnce(&mut RegisterFs),
757 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
758 where
759 Repeat: Repeating,
760 B::Interface: RegisterInterface,
761 Access: ReadCapability + WriteCapability,
762 {
763 let mut register = RegisterFs::ZERO;
764 let address = Repeat::calc_address(self.address, index);
765
766 self.block.interface().read_register(
767 address,
768 register.as_slice_mut(),
769 &RegisterFs::METADATA,
770 )?;
771
772 f(&mut register);
773
774 self.block.interface().write_register(
775 address,
776 register.as_slice_mut(),
777 &RegisterFs::METADATA,
778 )
779 }
780
781 #[track_caller]
786 pub fn modify_array_at<const N: usize>(
787 self,
788 index: Repeat::Index,
789 f: impl FnOnce(&mut [RegisterFs; N]),
790 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
791 where
792 Repeat: ArrayRepeating,
793 B::Interface: RegisterInterface,
794 B::RegisterAddressMode: AddressMode,
795 Access: ReadCapability + WriteCapability,
796 {
797 Repeat::assert_len_and_index(N, index.clone());
798
799 let mut register = <[RegisterFs; N] as Fieldset>::ZERO;
800
801 let address = Repeat::calc_address(self.address, index);
802 Self::assert_array_op_legal(address);
803
804 self.block.interface().read_register(
805 address,
806 register.as_slice_mut(),
807 &RegisterFs::METADATA,
808 )?;
809
810 f(&mut register);
811
812 self.block.interface().write_register(
813 address,
814 register.as_slice_mut(),
815 &RegisterFs::METADATA,
816 )
817 }
818
819 #[track_caller]
824 pub fn modify_async(
825 self,
826 f: impl FnOnce(&mut RegisterFs),
827 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
828 where
829 Repeat: NotRepeating,
830 B::Interface: AsyncRegisterInterface,
831 Access: ReadCapability + WriteCapability,
832 {
833 let mut register = RegisterFs::ZERO;
834
835 async move {
836 self.block
837 .interface()
838 .read_register(self.address, register.as_slice_mut(), &RegisterFs::METADATA)
839 .await?;
840
841 f(&mut register);
842
843 self.block
844 .interface()
845 .write_register(self.address, register.as_slice_mut(), &RegisterFs::METADATA)
846 .await
847 }
848 }
849
850 #[track_caller]
855 pub fn modify_at_async(
856 self,
857 index: Repeat::Index,
858 f: impl FnOnce(&mut RegisterFs),
859 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
860 where
861 Repeat: Repeating,
862 B::Interface: AsyncRegisterInterface,
863 Access: ReadCapability + WriteCapability,
864 {
865 let mut register = RegisterFs::ZERO;
866 let address = Repeat::calc_address(self.address, index);
867
868 async move {
869 self.block
870 .interface()
871 .read_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
872 .await?;
873
874 f(&mut register);
875
876 self.block
877 .interface()
878 .write_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
879 .await
880 }
881 }
882
883 #[track_caller]
888 pub fn modify_array_at_async<const N: usize>(
889 self,
890 index: Repeat::Index,
891 f: impl FnOnce(&mut [RegisterFs; N]),
892 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
893 where
894 Repeat: ArrayRepeating,
895 B::Interface: AsyncRegisterInterface,
896 B::RegisterAddressMode: AddressMode,
897 Access: ReadCapability + WriteCapability,
898 {
899 Repeat::assert_len_and_index(N, index.clone());
900
901 let mut register = <[RegisterFs; N] as Fieldset>::ZERO;
902
903 let address = Repeat::calc_address(self.address, index);
904 Self::assert_array_op_legal(address);
905
906 async move {
907 self.block
908 .interface()
909 .read_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
910 .await?;
911
912 f(&mut register);
913
914 self.block
915 .interface()
916 .write_register(address, register.as_slice_mut(), &RegisterFs::METADATA)
917 .await
918 }
919 }
920
921 #[track_caller]
922 fn assert_array_op_legal(address: AddressType)
923 where
924 B::RegisterAddressMode: AddressMode,
925 Repeat: ArrayRepeating,
926 {
927 if address.add(Repeat::STRIDE)
928 != B::RegisterAddressMode::next_address(address, core::mem::size_of::<RegisterFs>())
929 {
930 panic!(
931 "array operations can't be used with this register due to the `register-address-map` rule. Used stride: {}, accepted stride: {}",
932 Repeat::STRIDE,
933 B::RegisterAddressMode::next_address(
934 AddressType::ZERO,
935 core::mem::size_of::<RegisterFs>()
936 )
937 );
938 }
939 }
940}
941
942pub struct Plan<AddressType: Copy, FS, Access> {
944 pub address: AddressType,
946 pub value: FS,
948 _phantom: PhantomData<Access>,
949}
950
951pub struct BulkRegisterOperation<'b, B, AddressType: Address, Fieldsets, Access> {
953 pub(crate) block: &'b mut B,
954 pub(crate) start_address: Option<AddressType>,
955 pub(crate) next_address: Option<AddressType>,
956 pub(crate) field_sets: Fieldsets,
957 pub(crate) _phantom: PhantomData<Access>,
958}
959
960impl<B, AddressType, FieldSets, Access> BulkRegisterOperation<'_, B, AddressType, FieldSets, Access>
961where
962 B: Block,
963 B::RegisterAddressMode: AddressMode,
964 AddressType: Address,
965{
966 #[track_caller]
967 fn assert_legal(&self, address: AddressType) {
968 if let Some(next_address) = self.next_address
969 && address != next_address
970 {
971 panic!(
972 "order of registers not valid according to the address mode rules. Expected address: {}, got: {}",
973 next_address, address
974 );
975 }
976 }
977}
978
979impl<'b, B, AddressType, FieldSets> BulkRegisterOperation<'b, B, AddressType, FieldSets, WO>
980where
981 B: Block,
982 B::RegisterAddressMode: AddressMode,
983 AddressType: Address,
984{
985 #[track_caller]
992 #[inline]
993 pub fn with<FS: Fieldset, LocalAccess: WriteCapability>(
994 self,
995 f: impl FnOnce(&mut B) -> Plan<AddressType, FS, LocalAccess>,
996 ) -> BulkRegisterOperation<'b, B, AddressType, FieldSets::Appended, WO>
997 where
998 FieldSets: Append<FS>,
999 {
1000 let Plan { address, value, .. } = f(self.block);
1001 self.assert_legal(address);
1002
1003 BulkRegisterOperation {
1004 block: self.block,
1005 start_address: self.start_address.or(Some(address)),
1006 next_address: Some(B::RegisterAddressMode::next_address(
1007 address,
1008 core::mem::size_of::<FS>(),
1009 )),
1010 field_sets: self.field_sets.append(value),
1011 _phantom: PhantomData,
1012 }
1013 }
1014}
1015
1016impl<'b, B, AddressType, FieldSets> BulkRegisterOperation<'b, B, AddressType, FieldSets, RO>
1017where
1018 B: Block,
1019 B::RegisterAddressMode: AddressMode,
1020 AddressType: Address,
1021{
1022 #[track_caller]
1029 #[inline]
1030 pub fn with<FS: Fieldset, LocalAccess: ReadCapability>(
1031 self,
1032 f: impl FnOnce(&mut B) -> Plan<AddressType, FS, LocalAccess>,
1033 ) -> BulkRegisterOperation<'b, B, AddressType, FieldSets::Appended, RO>
1034 where
1035 FieldSets: Append<FS>,
1036 {
1037 let Plan { address, value, .. } = f(self.block);
1038 self.assert_legal(address);
1039
1040 BulkRegisterOperation {
1041 block: self.block,
1042 start_address: self.start_address.or(Some(address)),
1043 next_address: Some(B::RegisterAddressMode::next_address(
1044 address,
1045 core::mem::size_of::<FS>(),
1046 )),
1047 field_sets: self.field_sets.append(value),
1048 _phantom: PhantomData,
1049 }
1050 }
1051}
1052
1053impl<'b, B, AddressType, FieldSets> BulkRegisterOperation<'b, B, AddressType, FieldSets, RW>
1054where
1055 B: Block,
1056 B::RegisterAddressMode: AddressMode,
1057 AddressType: Address,
1058{
1059 #[track_caller]
1066 #[inline]
1067 pub fn with<FS: Fieldset, LocalAccess: ReadCapability + WriteCapability>(
1068 self,
1069 f: impl FnOnce(&mut B) -> Plan<AddressType, FS, LocalAccess>,
1070 ) -> BulkRegisterOperation<'b, B, AddressType, FieldSets::Appended, RW>
1071 where
1072 FieldSets: Append<FS>,
1073 {
1074 let Plan { address, value, .. } = f(self.block);
1075 self.assert_legal(address);
1076
1077 BulkRegisterOperation {
1078 block: self.block,
1079 start_address: self.start_address.or(Some(address)),
1080 next_address: Some(B::RegisterAddressMode::next_address(
1081 address,
1082 core::mem::size_of::<FS>(),
1083 )),
1084 field_sets: self.field_sets.append(value),
1085 _phantom: PhantomData,
1086 }
1087 }
1088}
1089
1090impl<B, Fieldsets>
1091 BulkRegisterOperation<
1092 '_,
1093 B,
1094 <B::Interface as RegisterInterfaceBase>::AddressType,
1095 Fieldsets,
1096 RO,
1097 >
1098where
1099 B: Block,
1100 B::Interface: RegisterInterfaceBase,
1101 Fieldsets: Fieldset + ToTuple,
1102{
1103 #[inline]
1108 pub fn execute(
1109 mut self,
1110 ) -> Result<Fieldsets::Tuple, <B::Interface as RegisterInterfaceBase>::Error>
1111 where
1112 B::Interface: RegisterInterface,
1113 {
1114 self.block
1115 .interface()
1116 .read_register(
1117 self.start_address.unwrap(),
1118 self.field_sets.as_slice_mut(),
1119 &Fieldsets::METADATA,
1120 )
1121 .map(|_| self.field_sets.to_tuple())
1122 }
1123
1124 #[inline]
1129 pub async fn execute_async(
1130 mut self,
1131 ) -> Result<Fieldsets::Tuple, <B::Interface as RegisterInterfaceBase>::Error>
1132 where
1133 B::Interface: AsyncRegisterInterface,
1134 {
1135 self.block
1136 .interface()
1137 .read_register(
1138 self.start_address.unwrap(),
1139 self.field_sets.as_slice_mut(),
1140 &Fieldsets::METADATA,
1141 )
1142 .await
1143 .map(|_| self.field_sets.to_tuple())
1144 }
1145}
1146
1147impl<B, Fieldsets>
1148 BulkRegisterOperation<
1149 '_,
1150 B,
1151 <B::Interface as RegisterInterfaceBase>::AddressType,
1152 Fieldsets,
1153 WO,
1154 >
1155where
1156 B: Block,
1157 B::Interface: RegisterInterfaceBase,
1158 Fieldsets: Fieldset,
1159 for<'a> &'a mut Fieldsets: ToTuple,
1160{
1161 #[inline]
1169 pub fn execute(
1170 mut self,
1171 f: impl FnOnce(<&mut Fieldsets as ToTuple>::Tuple),
1172 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
1173 where
1174 B::Interface: RegisterInterface,
1175 {
1176 f(self.field_sets.to_tuple());
1177
1178 self.block.interface().write_register(
1179 self.start_address.unwrap(),
1180 self.field_sets.as_slice_mut(),
1181 &Fieldsets::METADATA,
1182 )
1183 }
1184
1185 #[inline]
1193 pub fn execute_async(
1194 mut self,
1195 f: impl FnOnce(<&mut Fieldsets as ToTuple>::Tuple),
1196 ) -> impl Future<Output = Result<(), <B::Interface as RegisterInterfaceBase>::Error>>
1197 where
1198 B::Interface: AsyncRegisterInterface,
1199 {
1200 f(self.field_sets.to_tuple());
1201
1202 async move {
1203 self.block
1204 .interface()
1205 .write_register(
1206 self.start_address.unwrap(),
1207 self.field_sets.as_slice_mut(),
1208 &Fieldsets::METADATA,
1209 )
1210 .await
1211 }
1212 }
1213}
1214
1215impl<B, Fieldsets>
1216 BulkRegisterOperation<
1217 '_,
1218 B,
1219 <B::Interface as RegisterInterfaceBase>::AddressType,
1220 Fieldsets,
1221 RW,
1222 >
1223where
1224 B: Block,
1225 B::Interface: RegisterInterfaceBase,
1226 Fieldsets: Fieldset,
1227 for<'a> &'a mut Fieldsets: ToTuple,
1228{
1229 #[inline]
1237 pub fn execute(
1238 mut self,
1239 f: impl FnOnce(<&mut Fieldsets as ToTuple>::Tuple),
1240 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
1241 where
1242 B::Interface: RegisterInterface,
1243 {
1244 self.block.interface().read_register(
1245 self.start_address.unwrap(),
1246 self.field_sets.as_slice_mut(),
1247 &Fieldsets::METADATA,
1248 )?;
1249
1250 f(self.field_sets.to_tuple());
1251
1252 self.block.interface().write_register(
1253 self.start_address.unwrap(),
1254 self.field_sets.as_slice_mut(),
1255 &Fieldsets::METADATA,
1256 )
1257 }
1258
1259 #[inline]
1267 pub async fn execute_async(
1268 mut self,
1269 f: impl FnOnce(<&mut Fieldsets as ToTuple>::Tuple),
1270 ) -> Result<(), <B::Interface as RegisterInterfaceBase>::Error>
1271 where
1272 B::Interface: AsyncRegisterInterface,
1273 {
1274 self.block
1275 .interface()
1276 .read_register(
1277 self.start_address.unwrap(),
1278 self.field_sets.as_slice_mut(),
1279 &Fieldsets::METADATA,
1280 )
1281 .await?;
1282
1283 f(self.field_sets.to_tuple());
1284
1285 self.block
1286 .interface()
1287 .write_register(
1288 self.start_address.unwrap(),
1289 self.field_sets.as_slice_mut(),
1290 &Fieldsets::METADATA,
1291 )
1292 .await
1293 }
1294}