1use core::marker::PhantomData;
2
3use crate::{FieldSet, ReadCapability, WriteCapability};
4
5pub trait RegisterInterface {
9 type Error;
11 type AddressType: Copy;
13
14 fn write_register(
16 &mut self,
17 address: Self::AddressType,
18 size_bits: u32,
19 data: &[u8],
20 ) -> Result<(), Self::Error>;
21
22 fn read_register(
24 &mut self,
25 address: Self::AddressType,
26 size_bits: u32,
27 data: &mut [u8],
28 ) -> Result<(), Self::Error>;
29}
30
31pub trait AsyncRegisterInterface {
35 type Error;
37 type AddressType: Copy;
39
40 async fn write_register(
42 &mut self,
43 address: Self::AddressType,
44 size_bits: u32,
45 data: &[u8],
46 ) -> Result<(), Self::Error>;
47
48 async fn read_register(
50 &mut self,
51 address: Self::AddressType,
52 size_bits: u32,
53 data: &mut [u8],
54 ) -> Result<(), Self::Error>;
55}
56
57pub struct RegisterOperation<'i, Interface, AddressType: Copy, Register: FieldSet, Access> {
59 interface: &'i mut Interface,
60 address: AddressType,
61 register_new_with_reset: fn() -> Register,
62 _phantom: PhantomData<(Register, Access)>,
63}
64
65impl<'i, Interface, AddressType: Copy, Register: FieldSet, Access>
66 RegisterOperation<'i, Interface, AddressType, Register, Access>
67{
68 #[doc(hidden)]
69 pub fn new(
70 interface: &'i mut Interface,
71 address: AddressType,
72 register_new_with_reset: fn() -> Register,
73 ) -> Self {
74 Self {
75 interface,
76 address,
77 register_new_with_reset,
78 _phantom: PhantomData,
79 }
80 }
81}
82
83impl<Interface, AddressType: Copy, Register: FieldSet, Access>
84 RegisterOperation<'_, Interface, AddressType, Register, Access>
85where
86 Interface: RegisterInterface<AddressType = AddressType>,
87 Access: WriteCapability,
88{
89 pub fn write<R>(&mut self, f: impl FnOnce(&mut Register) -> R) -> Result<R, Interface::Error> {
94 let mut register = (self.register_new_with_reset)();
95 let returned = f(&mut register);
96
97 self.interface.write_register(
98 self.address,
99 Register::SIZE_BITS,
100 register.get_inner_buffer(),
101 )?;
102 Ok(returned)
103 }
104
105 pub fn write_with_zero<R>(
109 &mut self,
110 f: impl FnOnce(&mut Register) -> R,
111 ) -> Result<R, Interface::Error> {
112 let mut register = Register::new_with_zero();
113 let returned = f(&mut register);
114 self.interface.write_register(
115 self.address,
116 Register::SIZE_BITS,
117 register.get_inner_buffer_mut(),
118 )?;
119 Ok(returned)
120 }
121}
122
123impl<Interface, AddressType: Copy, Register: FieldSet, Access>
124 RegisterOperation<'_, Interface, AddressType, Register, Access>
125where
126 Interface: RegisterInterface<AddressType = AddressType>,
127 Access: ReadCapability,
128{
129 pub fn read(&mut self) -> Result<Register, Interface::Error> {
131 let mut register = Register::new_with_zero();
132
133 self.interface.read_register(
134 self.address,
135 Register::SIZE_BITS,
136 register.get_inner_buffer_mut(),
137 )?;
138 Ok(register)
139 }
140}
141
142impl<Interface, AddressType: Copy, Register: FieldSet, Access>
143 RegisterOperation<'_, Interface, AddressType, Register, Access>
144where
145 Interface: RegisterInterface<AddressType = AddressType>,
146 Access: ReadCapability + WriteCapability,
147{
148 pub fn modify<R>(&mut self, f: impl FnOnce(&mut Register) -> R) -> Result<R, Interface::Error> {
153 let mut register = self.read()?;
154 let returned = f(&mut register);
155 self.interface.write_register(
156 self.address,
157 Register::SIZE_BITS,
158 register.get_inner_buffer_mut(),
159 )?;
160 Ok(returned)
161 }
162}
163
164impl<Interface, AddressType: Copy, Register: FieldSet, Access>
165 RegisterOperation<'_, Interface, AddressType, Register, Access>
166where
167 Interface: AsyncRegisterInterface<AddressType = AddressType>,
168 Access: WriteCapability,
169{
170 pub async fn write_async<R>(
175 &mut self,
176 f: impl FnOnce(&mut Register) -> R,
177 ) -> Result<R, Interface::Error> {
178 let mut register = (self.register_new_with_reset)();
179 let returned = f(&mut register);
180
181 self.interface
182 .write_register(
183 self.address,
184 Register::SIZE_BITS,
185 register.get_inner_buffer(),
186 )
187 .await?;
188 Ok(returned)
189 }
190
191 pub async fn write_with_zero_async<R>(
195 &mut self,
196 f: impl FnOnce(&mut Register) -> R,
197 ) -> Result<R, Interface::Error> {
198 let mut register = Register::new_with_zero();
199 let returned = f(&mut register);
200 self.interface
201 .write_register(
202 self.address,
203 Register::SIZE_BITS,
204 register.get_inner_buffer_mut(),
205 )
206 .await?;
207 Ok(returned)
208 }
209}
210
211impl<Interface, AddressType: Copy, Register: FieldSet, Access>
212 RegisterOperation<'_, Interface, AddressType, Register, Access>
213where
214 Interface: AsyncRegisterInterface<AddressType = AddressType>,
215 Access: ReadCapability,
216{
217 pub async fn read_async(&mut self) -> Result<Register, Interface::Error> {
219 let mut register = Register::new_with_zero();
220
221 self.interface
222 .read_register(
223 self.address,
224 Register::SIZE_BITS,
225 register.get_inner_buffer_mut(),
226 )
227 .await?;
228 Ok(register)
229 }
230}
231
232impl<Interface, AddressType: Copy, Register: FieldSet, Access>
233 RegisterOperation<'_, Interface, AddressType, Register, Access>
234where
235 Interface: AsyncRegisterInterface<AddressType = AddressType>,
236 Access: ReadCapability + WriteCapability,
237{
238 pub async fn modify_async<R>(
243 &mut self,
244 f: impl FnOnce(&mut Register) -> R,
245 ) -> Result<R, Interface::Error> {
246 let mut register = self.read_async().await?;
247 let returned = f(&mut register);
248 self.interface
249 .write_register(
250 self.address,
251 Register::SIZE_BITS,
252 register.get_inner_buffer(),
253 )
254 .await?;
255 Ok(returned)
256 }
257}