From 5d1cff57f9f5acd740a8b5f8c941beefdcc00176 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 28 Jun 2020 16:42:21 +0200 Subject: sw: configure si5351 --- sw/deps/hd44780-driver/src/bus/i2c_mcp23008.rs | 102 +++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 sw/deps/hd44780-driver/src/bus/i2c_mcp23008.rs (limited to 'sw/deps/hd44780-driver/src/bus/i2c_mcp23008.rs') diff --git a/sw/deps/hd44780-driver/src/bus/i2c_mcp23008.rs b/sw/deps/hd44780-driver/src/bus/i2c_mcp23008.rs new file mode 100644 index 0000000..1ccb479 --- /dev/null +++ b/sw/deps/hd44780-driver/src/bus/i2c_mcp23008.rs @@ -0,0 +1,102 @@ +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 MCP23008 IC, like +/// the one from adafruit. +/// Connections as follows: +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +///
MCP23008 pinnameLCD pin
0N/C
1RS4
2E6
3DB411
4DB512
5DB613
6DB714
7Backlight
+ +pub struct I2CMCP23008Bus { + i2c_bus: I2C, + address: u8, +} + +const REG_IODIR : u8 = 0x00; +const REG_GPIO : u8 = 0x09; + +impl I2CMCP23008Bus { + + /// Create a new instance of the MCP23008 I2C driver. The address of those + /// devices is 0b010_0xxx where x is configured by bootstrap pins. + pub fn new(i2c_bus: I2C, address: u8) -> Result> { + let mut mcp23008 = I2CMCP23008Bus { i2c_bus, address }; + // Set to reset values according to datasheet + mcp23008.write_reg(REG_IODIR, 0b1111_1111)?; + for reg in 0x01usize..0x0A { + mcp23008.write_reg(reg as u8, 0)?; + } + // Configure pins 1..=7 as outputs, see pin mapping above + mcp23008.write_reg(REG_IODIR, 0b0000_0001)?; + Ok(mcp23008) + } + + fn write_reg(&mut self, reg: u8, value: u8) -> Result<()> { + let data = [reg, value]; + self.i2c_bus.write(self.address, &data) + .map_err(|_| crate::error::Error) + } + + fn set_pins(&mut self, pins: u8) -> Result<()> { + self.write_reg(REG_GPIO, pins) + } + +} + +impl DataBus for I2CMCP23008Bus { + fn write + DelayMs>( + &mut self, + byte: u8, + data: bool, + delay: &mut D, + ) -> Result<()> { + let rs = if data { 0b10 } else { 0b00 }; + let en = 0b0000_0100; + let backlight = 0b1000_0000; // always enable backlight + + let upper_nibble = (byte & 0xF0) >> 4; + let lower_nibble = byte & 0x0F; + + // upper nibble: [d7 d6 d5 d4] + // Pulse EN + // lower nibble: [d3 d2 d1 d0] + // Pulse EN + + let pins = rs | backlight | (upper_nibble << 3); + self.set_pins(pins)?; + + delay.delay_ms(1); + + let pins = rs | en | backlight | (upper_nibble << 3); + self.set_pins(pins)?; + + delay.delay_ms(1); + + let pins = rs | backlight | (lower_nibble << 3); + self.set_pins(pins)?; + + delay.delay_ms(1); + + let pins = rs | en | backlight | (lower_nibble << 3); + self.set_pins(pins)?; + + delay.delay_ms(1); + + let pins = backlight | (lower_nibble << 3); + self.set_pins(pins)?; + + Ok(()) + } +} -- cgit v1.2.3