mini_oled/interface/
i2c.rs

1use embedded_hal::i2c::{Error, I2c};
2
3use crate::{command::CommandBuffer, error::MiniOledError};
4
5use super::CommunicationInterface;
6
7/// I2C communication interface.
8///
9/// # Example
10///
11/// ```rust,ignore
12/// use mini_oled::interface::i2c::I2cInterface;
13///
14/// // Verify that your I2C driver implements embedded_hal::i2c::I2c
15/// // let i2c_driver = ...;
16/// let interface = I2cInterface::new(i2c_driver, 0x3C);
17/// ```
18pub struct I2cInterface<IC: I2c> {
19    i2c: IC,
20    address: u8,
21}
22
23impl<IC: I2c> I2cInterface<IC> {
24    /// Creates a new I2C interface.
25    ///
26    /// # Arguments
27    ///
28    /// * `i2c` - The I2C peripheral.
29    /// * `address` - The I2C address of the display.
30    pub fn new(i2c: IC, address: u8) -> Self {
31        I2cInterface { i2c, address }
32    }
33}
34
35impl<IC: I2c> CommunicationInterface for I2cInterface<IC> {
36    fn init(&mut self) -> Result<(), MiniOledError> {
37        Ok(())
38    }
39
40    fn write_data(&mut self, data_buf: &[u8]) -> Result<(), MiniOledError> {
41        let mut send_buf = [0u8; 130];
42        if data_buf.len() > 128 {
43            return Err(MiniOledError::DataBufferSizeError);
44        }
45        send_buf[0] = 0x40;
46        send_buf[1..data_buf.len() + 1].copy_from_slice(data_buf);
47        self.i2c
48            .write(self.address, &send_buf[..data_buf.len() + 1])
49            .map_err(|e| MiniOledError::I2cError(e.kind()))
50    }
51
52    fn write_command<const N: usize>(
53        &mut self,
54        command_buf: &CommandBuffer<N>,
55    ) -> Result<(), MiniOledError> {
56        let mut send_buf = [0u8; 30];
57        let command_buf_bytes = command_buf.to_bytes(&mut send_buf[1..])?;
58        let len = command_buf_bytes.len();
59
60        self.i2c
61            .write(self.address, &send_buf[..len + 1])
62            .map_err(|e| MiniOledError::I2cError(e.kind()))
63    }
64}