device_register/
lib.rs

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