device_driver/
register.rs

1use core::marker::PhantomData;
2
3use crate::{FieldSet, ReadCapability, WriteCapability};
4
5/// A trait to represent the interface to the device.
6///
7/// This is called to write to and read from registers.
8pub trait RegisterInterface {
9    /// The error type
10    type Error;
11    /// The address type used by this interface. Should likely be an integer.
12    type AddressType: Copy;
13
14    /// Write the given data to the register located at the given address
15    fn write_register(
16        &mut self,
17        address: Self::AddressType,
18        size_bits: u32,
19        data: &[u8],
20    ) -> Result<(), Self::Error>;
21
22    /// Read the register located at the given addres to the given data slice
23    fn read_register(
24        &mut self,
25        address: Self::AddressType,
26        size_bits: u32,
27        data: &mut [u8],
28    ) -> Result<(), Self::Error>;
29}
30
31/// A trait to represent the interface to the device.
32///
33/// This is called to asynchronously write to and read from registers.
34pub trait AsyncRegisterInterface {
35    /// The error type
36    type Error;
37    /// The address type used by this interface. Should likely be an integer.
38    type AddressType: Copy;
39
40    /// Write the given data to the register located at the given address
41    async fn write_register(
42        &mut self,
43        address: Self::AddressType,
44        size_bits: u32,
45        data: &[u8],
46    ) -> Result<(), Self::Error>;
47
48    /// Read the register located at the given addres to the given data slice
49    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
57/// Object that performs actions on the device in the context of a register
58pub 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    /// Write to the register.
90    ///
91    /// The closure is given the write object initialized to the reset value of the register.
92    /// If no reset value is specified for this register, this function is the same as [Self::write_with_zero].
93    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    /// Write to the register.
106    ///
107    /// The closure is given the write object initialized to all zero.
108    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    /// Read the register from the device
130    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    /// Modify the existing register value.
149    ///
150    /// The register is read, the value is then passed to the closure for making changes.
151    /// The result is then written back to the device.
152    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    /// Write to the register.
171    ///
172    /// The closure is given the write object initialized to the reset value of the register.
173    /// If no reset value is specified for this register, this function is the same as [Self::write_with_zero].
174    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    /// Write to the register.
192    ///
193    /// The closure is given the write object initialized to all zero.
194    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    /// Read the register from the device
218    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    /// Modify the existing register value.
239    ///
240    /// The register is read, the value is then passed to the closure for making changes.
241    /// The result is then written back to the device.
242    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}