i2c_reg/i2c_interface.rs
1//! Interface for I2C communication.
2
3use crate::hal::blocking::i2c;
4use crate::registers::{I2cReadRegister, I2cWriteRegister};
5
6/// I2C interface
7///
8/// # Example
9///
10/// ```
11/// use embedded_hal::blocking::i2c;
12/// use i2c_reg::*;
13/// use i2c_reg_derive::*;
14///
15/// # static mut REGISTER_CACHE: [u8; 4] = [0; 4];
16/// #
17/// # struct MockI2c;
18/// #
19/// # impl i2c::WriteRead for MockI2c {
20/// # type Error = ();
21/// # fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
22/// # for (i, item) in unsafe { REGISTER_CACHE }.iter().enumerate() {
23/// # buffer[i] = *item;
24/// # }
25/// # Ok(())
26/// # }
27/// # }
28/// #
29/// # impl i2c::Write for MockI2c {
30/// # type Error = ();
31/// #
32/// # fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
33/// # for (i, item) in bytes.iter().skip(1).enumerate() {
34/// # unsafe { REGISTER_CACHE [i] = *item; }
35/// # }
36/// # Ok(())
37/// # }
38/// # }
39/// #[derive(Register, I2cReadRegister, I2cWriteRegister)]
40/// #[address = 0b1110]
41/// #[size = 4]
42/// struct ExampleRegister;
43///
44/// type Raw = <ExampleRegister as Register>::Raw;
45///
46/// #[derive(Debug, PartialEq)]
47/// struct Value(u32);
48///
49/// impl Into<Raw> for Value {
50/// fn into(self) -> Raw {
51/// self.0.to_be_bytes()
52/// }
53/// }
54///
55/// impl From<Raw> for Value {
56/// fn from(raw: Raw) -> Self {
57/// Value(u32::from_be_bytes(raw))
58/// }
59/// }
60///
61/// # let i2c = MockI2c;
62/// #
63/// let mut interface = I2cInterface { i2c, address: 0b0110 };
64/// interface.write_register(ExampleRegister, Value(0x89abcdef)).unwrap();
65/// let value: Value = interface.read_register(ExampleRegister).unwrap();
66/// assert_eq!(Value(0x89abcdef), value);
67/// ```
68#[derive(Debug)]
69pub struct I2cInterface<I2C> {
70 /// Slave device I2C
71 pub i2c: I2C,
72
73 /// Slave device address
74 pub address: u8,
75}
76
77impl<I2C> I2cInterface<I2C> {
78 /// Read bytes from register and map output to `Value`
79 pub fn read_register<Raw, Value, Err>(
80 &mut self,
81 register: impl I2cReadRegister<Raw>,
82 ) -> Result<Value, Err>
83 where
84 I2C: i2c::WriteRead<Error = Err>,
85 Raw: Into<Value>,
86 {
87 register
88 .i2c_read(&mut self.i2c, self.address)
89 .map(|v| v.into())
90 }
91
92 /// Map `value` to bytes and write to register
93 pub fn write_register<Raw, Err>(
94 &mut self,
95 register: impl I2cWriteRegister<Raw>,
96 value: impl Into<Raw>,
97 ) -> Result<(), Err>
98 where
99 I2C: i2c::Write<Error = Err>,
100 {
101 register.i2c_write(&mut self.i2c, self.address, value.into())
102 }
103}