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}