commit 77b04071be569a43758fb4ec706ae93a884c93bc Author: Edwin Noorlander Date: Thu Jun 18 18:37:03 2026 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..40c3a7a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,314 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "I2C4002" +version = "0.1.0" +dependencies = [ + "embedded-hal", + "linux-embedded-hal", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal", + "nb", +] + +[[package]] +name = "i2cdev" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b940f7497c4f95b863b21cd34c3737b53a67d80d94cf29055d7f7eeca6ffdb4" +dependencies = [ + "bitflags 2.13.0", + "byteorder", + "libc", + "nix 0.26.4", +] + +[[package]] +name = "io-kit-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +dependencies = [ + "core-foundation-sys", + "mach2", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linux-embedded-hal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a8a605c95f708c78554738a12153b213f107d3bd5323f7ce32d6deb3faafb40" +dependencies = [ + "cast", + "embedded-hal", + "embedded-hal-nb", + "i2cdev", + "nb", + "nix 0.27.1", + "serialport", +] + +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.13.0", + "cfg-if", + "libc", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serialport" +version = "4.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4d91116f97173694f1642263b2ff837f80d933aa837e2314969f6728f661df3" +dependencies = [ + "bitflags 2.13.0", + "cfg-if", + "core-foundation", + "core-foundation-sys", + "io-kit-sys", + "mach2", + "nix 0.26.4", + "scopeguard", + "unescaper", + "windows-sys", +] + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unescaper" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4064ed685c487dbc25bd3f0e9548f2e34bab9d18cefc700f9ec2dba74ba1138e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..23154f2 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "I2C4002" +version = "0.1.0" +edition = "2024" + +[dependencies] +embedded-hal = "1.0" +linux-embedded-hal = { version = "0.4", default-features = false, features = ["i2c"] } + +[profile.dev] +codegen-units = 256 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/incl/lcd.rs b/incl/lcd.rs new file mode 100644 index 0000000..9253d8c --- /dev/null +++ b/incl/lcd.rs @@ -0,0 +1,100 @@ +use embedded_hal::i2c::I2c; +use std::thread::sleep; +use std::time::Duration; + +pub struct Lcd { + i2c: I, + addr: u8, + backlight: bool, +} + +impl Lcd { + const RS: u8 = 0b001; + const EN: u8 = 0b100; + const BL: u8 = 0b1000; + + pub fn new(i2c: I, addr: u8) -> Result { + let mut lcd = Self { i2c, addr, backlight: true }; + lcd.init()?; + Ok(lcd) + } + + fn write_nibble(&mut self, nibble: u8, rs: u8) -> Result<(), I::Error> { + let bl = if self.backlight { Self::BL } else { 0 }; + let data = nibble | rs | bl; + self.i2c.write(self.addr, &[data | Self::EN])?; + sleep(Duration::from_micros(1)); + self.i2c.write(self.addr, &[data & !Self::EN])?; + sleep(Duration::from_micros(50)); + Ok(()) + } + + fn write_byte(&mut self, byte: u8, rs: u8) -> Result<(), I::Error> { + self.write_nibble(byte & 0xF0, rs)?; + self.write_nibble((byte & 0x0F) << 4, rs)?; + Ok(()) + } + + fn cmd(&mut self, c: u8) -> Result<(), I::Error> { + self.write_byte(c, 0)?; + if c <= 0x03 { + sleep(Duration::from_millis(2)); + } + Ok(()) + } + + fn data(&mut self, d: u8) -> Result<(), I::Error> { + self.write_byte(d, Self::RS) + } + + fn init(&mut self) -> Result<(), I::Error> { + sleep(Duration::from_millis(50)); + for _ in 0..3 { + self.write_nibble(0x30, 0)?; + sleep(Duration::from_millis(5)); + } + self.write_nibble(0x20, 0)?; + sleep(Duration::from_millis(1)); + + self.cmd(0x28)?; + self.cmd(0x0C)?; + self.cmd(0x06)?; + self.cmd(0x01)?; + sleep(Duration::from_millis(2)); + Ok(()) + } + + pub fn clear(&mut self) -> Result<(), I::Error> { + self.cmd(0x01)?; + sleep(Duration::from_millis(2)); + Ok(()) + } + + pub fn set_cursor(&mut self, col: u8, row: u8) -> Result<(), I::Error> { + let addr = match row { + 0 => 0x00, + 1 => 0x40, + 2 => 0x14, + 3 => 0x54, + _ => 0x00, + }; + self.cmd(0x80 | (addr + col)) + } + + pub fn create_char(&mut self, location: u8, data: &[u8; 8]) -> Result<(), I::Error> { + self.cmd(0x40 | (location << 3))?; + for &b in data { + self.data(b)?; + } + self.set_cursor(0, 0) + } + + + + pub fn print(&mut self, s: &str) -> Result<(), I::Error> { + for b in s.bytes() { + self.data(b)?; + } + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..23cff85 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,40 @@ +#[path = "../incl/lcd.rs"] +mod lcd; + +use lcd::Lcd; +use std::thread::sleep; +use std::time::Duration; + +fn main() -> Result<(), Box> { + use linux_embedded_hal::I2cdev; + let i2c = I2cdev::new("/dev/i2c-1")?; + let mut lcd = Lcd::new(i2c, 0x27)?; + + let heart = [ 0b00000, + 0b01010, + 0b11111, + 0b11111, + 0b11111, + 0b01110, + 0b00100, + 0b00000 + ]; + + lcd.clear()?; + lcd.create_char(0, &heart)?; + lcd.set_cursor(0, 0)?; + lcd.print("\x00")?; + + lcd.set_cursor(12, 0)?; + lcd.print("Hello from Rust!")?; + lcd.set_cursor(8, 1)?; + lcd.print("40x2 LCD via I2C at 0x27")?; + + let mut nr: i32 = 0; + loop { + lcd.set_cursor(37, 0)?; + lcd.print(&format!("{:>3}", nr))?; + nr = (nr + 1) % 256; + sleep(Duration::from_millis(125)); + } +}