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}