device_register_async/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3#![deny(unsafe_code, missing_docs)]
4#![allow(async_fn_in_trait)]
5
6pub use device_register;
7use device_register::{EditableRegister, ReadableRegister, Register, WritableRegister};
8
9/// Traits that define how to read and write the registers.
10/// Note that those functions should mostly just be implemented and not used since they are not bound by Read/Write/Edit permission.
11pub trait RegisterInterface<R, A>
12where
13    R: Register<Address = A>,
14{
15    /// The error type returned by the interface
16    type Error;
17
18    /// Reads a register and returns it
19    async fn read_register(&mut self) -> Result<R, Self::Error>;
20
21    /// Writes a register to the device
22    async fn write_register(&mut self, register: &R) -> Result<(), Self::Error>;
23}
24
25/// Trait to safely read a register. Only a readable register can be read.
26pub trait ReadRegister<R, A>
27where
28    R: ReadableRegister<Address = A>,
29{
30    /// The error type returned by reading a register
31    type Error;
32
33    /// Read a register
34    async fn read(&mut self) -> Result<R, Self::Error>;
35}
36
37/// Trait to safely write a register. Only a writable register can be written to.
38pub trait WriteRegister<R, A>
39where
40    R: WritableRegister<Address = A>,
41{
42    /// The error type returned by writing a register
43    type Error;
44
45    /// Write a register
46    async fn write(&mut self, register: R) -> Result<(), Self::Error>;
47}
48
49/// Trait to safely read-edit-write a register.
50/// Usefull when a register has reserved values for internal uses.
51/// Avoids writing garbage to the reserved  bits.
52pub trait EditRegister<R, A>
53where
54    for<'a> R: EditableRegister<Address = A> + 'a,
55{
56    /// The error type returned by editing a register
57    type Error;
58
59    /// Edit a register. The closure takes a reference to the register,
60    /// the same register must be edited, then returned.
61    async fn edit<F>(&mut self, f: F) -> Result<(), Self::Error>
62    where
63        for<'w> F: FnOnce(&'w mut R);
64}
65
66impl<I, R, A> ReadRegister<R, A> for I
67where
68    for<'a> R: ReadableRegister<Address = A> + 'a,
69    I: RegisterInterface<R, A>,
70    for<'a> A: 'a,
71{
72    type Error = I::Error;
73
74    async fn read(&mut self) -> Result<R, Self::Error> {
75        self.read_register().await
76    }
77}
78
79impl<I, R, A> WriteRegister<R, A> for I
80where
81    for<'a> R: WritableRegister<Address = A> + 'a,
82    I: RegisterInterface<R, A>,
83    for<'a> A: 'a,
84{
85    type Error = I::Error;
86
87    async fn write(&mut self, register: R) -> Result<(), Self::Error> {
88        self.write_register(&register).await
89    }
90}
91
92impl<I, R, A> EditRegister<R, A> for I
93where
94    for<'a> R: EditableRegister<Address = A> + 'a,
95    I: RegisterInterface<R, A>,
96    for<'a> A: 'a,
97{
98    type Error = I::Error;
99
100    async fn edit<F>(&mut self, f: F) -> Result<(), Self::Error>
101    where
102        for<'w> F: FnOnce(&'w mut R),
103    {
104        let mut val = self.read_register().await?;
105        f(&mut val);
106        self.write_register(&val).await
107    }
108}