ag_lcd/
i2c.rs

1//! Allows interacting  with an lcd display via I2C using a digital port expander
2
3use crate::LcdDisplay;
4use core::fmt::Debug;
5use embedded_hal::delay::DelayNs;
6use port_expander::{dev::pcf8574, mode::QuasiBidirectional, I2cBus, Pcf8574, Pcf8574a, Pin, PortMutex};
7
8impl<'a, D, M, I2C> LcdDisplay<Pin<'a, QuasiBidirectional, M>, D>
9where
10    D: DelayNs + Sized,
11    M: PortMutex<Port = pcf8574::Driver<I2C>>,
12    I2C: I2cBus,
13    <I2C as I2cBus>::BusError: Debug,
14{
15    /// Descructs pin collection from port expander and constructs LcdDisplay using pins that are
16    /// available. For example usage see [`new_pcf8574`] or [`new_pcf8574a`].
17    fn from_parts(parts: pcf8574::Parts<'a, I2C, M>, delay: D) -> Self {
18        let pcf8574::Parts {
19            p0,
20            p1,
21            p2,
22            p3,
23            p4,
24            p5,
25            p6,
26            p7,
27        } = parts;
28        LcdDisplay::new(p0, p2, delay)
29            .with_backlight(p3)
30            .with_rw(p1)
31            .with_half_bus(p4, p5, p6, p7)
32    }
33
34    /// Creates a new [`LcdDisplay`] using PCF8572A for interfacing
35    ///
36    /// Refer to [Pcf8574a docs] from crate `port-expander` for more information about setup of the
37    /// port expander
38    ///
39    /// This method is only available if the `i2c` feature is enabled.
40    ///
41    /// # Examples
42    ///
43    /// ```
44    /// let peripherals = arduino_hal::Peripherals::take().unwrap();
45    /// let pins = arduino_hal::pins!(peripherals);
46    /// let delay = arduino_hal::Delay::new();
47    ///
48    /// let sda = pins.a4.into_pull_up_input();
49    /// let scl = pins.a5.into_pull_up_input();
50    ///
51    /// let i2c_bus = arduino_hal::i2c::I2c::new(peripherals.TWI, sda, scl, 50000);
52    /// let mut i2c_expander = Pcf8574a::new(i2c_bus, true, true, true);
53    ///
54    /// let mut lcd: LcdDisplay<_,_> = LcdDisplay::new_pcf8574a(&mut i2c_expander, delay)
55    ///     .with_blink(Blink::On)
56    ///     .with_cursor(Cursor::Off)
57    ///     .build();
58    /// ```
59    ///
60    /// [Pcf8574a docs]: https://docs.rs/port-expander/latest/port_expander/dev/pcf8574/struct.Pcf8574a.html
61    #[inline]
62    pub fn new_pcf8574a(expander: &'a mut Pcf8574a<M>, delay: D) -> Self {
63        Self::from_parts(expander.split(), delay)
64    }
65
66    /// Creates a new [`LcdDisplay`] using PCF8572 for interfacing
67    ///
68    /// Refer to [Pcf8574a docs] from crate `port-expander` for more information about setup of the
69    /// port expander
70    ///
71    /// This method is only available if the `i2c` feature is enabled.
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// let peripherals = arduino_hal::Peripherals::take().unwrap();
77    /// let pins = arduino_hal::pins!(peripherals);
78    /// let delay = arduino_hal::Delay::new();
79    ///
80    /// let sda = pins.a4.into_pull_up_input();
81    /// let scl = pins.a5.into_pull_up_input();
82    ///
83    /// let i2c_bus = arduino_hal::i2c::I2c::new(peripherals.TWI, sda, scl, 50000);
84    /// let mut i2c_expander = Pcf8574::new(i2c_bus, true, true, true);
85    ///
86    /// let mut lcd: LcdDisplay<_,_> = LcdDisplay::new_pcf8574a(&mut i2c_expander, delay)
87    ///     .with_blink(Blink::On)
88    ///     .with_cursor(Cursor::Off)
89    ///     .build();
90    /// ```
91    ///
92    /// [Pcf8574a docs]: https://docs.rs/port-expander/latest/port_expander/dev/pcf8574/struct.Pcf8574a.html
93    #[inline]
94    pub fn new_pcf8574(expander: &'a mut Pcf8574<M>, delay: D) -> Self {
95        Self::from_parts(expander.split(), delay)
96    }
97}