display_interface_i2c/
lib.rs

1//! Generic I2C interface for display drivers
2
3#![no_std]
4
5mod asynch;
6
7use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand};
8
9/// I2C communication interface
10pub struct I2CInterface<I2C> {
11    i2c: I2C,
12    addr: u8,
13    data_byte: u8,
14}
15
16impl<I2C> I2CInterface<I2C> {
17    /// Create new I2C interface for communication with a display driver
18    pub fn new(i2c: I2C, addr: u8, data_byte: u8) -> Self {
19        Self {
20            i2c,
21            addr,
22            data_byte,
23        }
24    }
25
26    /// Consume the display interface and return
27    /// the underlying peripheral driver
28    pub fn release(self) -> I2C {
29        self.i2c
30    }
31}
32
33impl<I2C> WriteOnlyDataCommand for I2CInterface<I2C>
34where
35    I2C: embedded_hal::i2c::I2c,
36{
37    fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> {
38        // Copy over given commands to new aray to prefix with command identifier
39        match cmds {
40            DataFormat::U8(slice) => {
41                let mut writebuf: [u8; 8] = [0; 8];
42                writebuf[1..=slice.len()].copy_from_slice(&slice[0..slice.len()]);
43
44                self.i2c
45                    .write(self.addr, &writebuf[..=slice.len()])
46                    .map_err(|_| DisplayError::BusWriteError)
47            }
48            _ => Err(DisplayError::DataFormatNotImplemented),
49        }
50    }
51
52    fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> {
53        match buf {
54            DataFormat::U8(slice) => {
55                // No-op if the data buffer is empty
56                if slice.is_empty() {
57                    return Ok(());
58                }
59
60                let mut writebuf = [0; 17];
61
62                // Data mode
63                writebuf[0] = self.data_byte;
64
65                slice
66                    .chunks(16)
67                    .try_for_each(|c| {
68                        let chunk_len = c.len();
69
70                        // Copy over all data from buffer, leaving the data command byte intact
71                        writebuf[1..=chunk_len].copy_from_slice(c);
72
73                        self.i2c.write(self.addr, &writebuf[0..=chunk_len])
74                    })
75                    .map_err(|_| DisplayError::BusWriteError)
76            }
77            DataFormat::U8Iter(iter) => {
78                let mut writebuf = [0; 17];
79                let mut i = 1;
80                let len = writebuf.len();
81
82                // Data mode
83                writebuf[0] = self.data_byte;
84
85                for byte in iter.into_iter() {
86                    writebuf[i] = byte;
87                    i += 1;
88
89                    if i == len {
90                        self.i2c
91                            .write(self.addr, &writebuf[0..=len])
92                            .map_err(|_| DisplayError::BusWriteError)?;
93                        i = 1;
94                    }
95                }
96
97                if i > 1 {
98                    self.i2c
99                        .write(self.addr, &writebuf[0..=i])
100                        .map_err(|_| DisplayError::BusWriteError)?;
101                }
102
103                Ok(())
104            }
105            _ => Err(DisplayError::DataFormatNotImplemented),
106        }
107    }
108}