use embedded_hal::blocking::delay::{DelayMs, DelayUs}; use embedded_hal::blocking::i2c::Write; use crate::{bus::DataBus, error::Result}; /// This module supports I2C backpacks with a PCF8574 IC. /// Connections as follows: /// /// /// /// /// /// /// /// /// /// /// ///
PCF8574 pinnameLCD pin
P0RS4
P1RW5
P2E6
P3Backlight
P4DB411
P5DB512
P6DB613
P7DB714
pub struct I2CBus { i2c_bus: I2C, address: u8, } const BACKLIGHT: u8 = 0b0000_1000; const ENABLE: u8 = 0b0000_0100; // const READ_WRITE: u8 = 0b0000_0010; // Not used as no reading of the `HD44780` is done const REGISTER_SELECT: u8 = 0b0000_0001; impl I2CBus { pub fn new(i2c_bus: I2C, address: u8) -> I2CBus { I2CBus { i2c_bus, address } } /// Write a nibble to the lcd /// The nibble should be in the upper part of the byte fn write_nibble + DelayMs>( &mut self, nibble: u8, data: bool, delay: &mut D, ) { let rs = match data { false => 0u8, true => REGISTER_SELECT, }; let byte = nibble | rs | BACKLIGHT; let _ = self.i2c_bus.write(self.address, &[byte, byte | ENABLE]); delay.delay_ms(2u8); let _ = self.i2c_bus.write(self.address, &[byte]); } } impl DataBus for I2CBus { fn write + DelayMs>( &mut self, byte: u8, data: bool, delay: &mut D, ) -> Result<()> { let upper_nibble = byte & 0xF0; self.write_nibble(upper_nibble, data, delay); let lower_nibble = (byte & 0x0F) << 4; self.write_nibble(lower_nibble, data, delay); Ok(()) } }