From 6f56f584b68ffe06990594f4adfb2e122be9ea9a Mon Sep 17 00:00:00 2001 From: cscherr Date: Tue, 13 May 2025 12:20:58 +0200 Subject: [PATCH] feat: try and fail to make lcd work wiht another library --- Cargo.lock | 17 ++--- Cargo.toml | 2 +- examples/lcd.rs | 171 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 137 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e3cea80..f922377 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,15 +183,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "hd44780-driver" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aab2b13fdeaed7dde9133a57c28b2cbde4a8fc8c3196b5631428aad114857d3a" -dependencies = [ - "embedded-hal", -] - [[package]] name = "heapless" version = "0.8.0" @@ -202,6 +193,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "lcd" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "971d8fd9a162c0bda137b341493cce134a2f55f3317b8533d992934bc523c325" + [[package]] name = "nb" version = "0.1.3" @@ -225,8 +222,8 @@ dependencies = [ "cortex-m-rt", "defmt 1.0.1", "defmt-rtt", - "hd44780-driver", "heapless", + "lcd", "panic-halt", "panic-probe", "stm32l0xx-hal", diff --git a/Cargo.toml b/Cargo.toml index 38a3552..ee0ecd7 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,8 @@ hal = { package = "stm32l0xx-hal", version = "0.10.0", features = [ cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.5" panic-halt = "1.0.0" -hd44780-driver = "0.4.0" heapless = "0.8.0" defmt = "1.0.1" defmt-rtt = "1.0.0" panic-probe = { version = "0.3", features = ["print-defmt"] } +lcd = "0.4.1" diff --git a/examples/lcd.rs b/examples/lcd.rs index e25e3a1..63fd0a2 100755 --- a/examples/lcd.rs +++ b/examples/lcd.rs @@ -1,8 +1,15 @@ #![no_main] #![no_std] -use defmt::{debug, error, info, println, trace, warn}; -use hal::pwm::Pin; +use defmt::{debug, info}; +use hal::{ + delay::Delay, + gpio::{ + Output, PushPull, + gpioa::{PA8, PA10}, + gpiob::{PB3, PB4, PB5, PB10}, + }, +}; use panic_probe as _; use defmt_rtt as _; // global logger @@ -11,8 +18,108 @@ use core::fmt::Write; use cortex_m_rt::entry; use hal::{pac, prelude::*, rcc::Config}; -use hd44780_driver::HD44780; -use heapless::Vec; + +pub type D2PIN = PA10>; +pub type D3PIN = PB3>; +pub type D4PIN = PB5>; +pub type D5PIN = PB4>; +pub type D6PIN = PB10>; +pub type D7PIN = PA8>; + +struct LCDHardware<'a> { + d4: &'a mut PB5>, + d5: &'a mut PB4>, + d6: &'a mut PB10>, + d7: &'a mut PA8>, + rs: &'a mut PA10>, + en: &'a mut PB3>, + delay: &'a mut Delay, +} + +impl<'a> LCDHardware<'a> { + fn new( + d4: &'a mut D4PIN, + d5: &'a mut D5PIN, + d6: &'a mut D6PIN, + d7: &'a mut D7PIN, + rs: &'a mut D2PIN, + en: &'a mut D3PIN, + delay: &'a mut Delay, + ) -> lcd::Display> { + let hw: LCDHardware<'a> = LCDHardware { + d4, + d5, + d6, + d7, + rs, + en, + delay, + }; + let mut lcd = lcd::Display::new(hw); + lcd.init(lcd::FunctionLine::Line2, lcd::FunctionDots::Dots5x8); + lcd.display( + lcd::DisplayMode::DisplayOn, + lcd::DisplayCursor::CursorOn, + lcd::DisplayBlink::BlinkOn, + ); + lcd.entry_mode( + lcd::EntryModeDirection::EntryRight, + lcd::EntryModeShift::NoShift, + ); + + lcd + } +} + +impl lcd::Delay for LCDHardware<'_> { + fn delay_us(&mut self, delay_usec: u32) { + self.delay.delay_us(delay_usec); + } +} + +impl lcd::Hardware for LCDHardware<'_> { + fn rs(&mut self, bit: bool) { + self.rs + .set_state(PinState::from(bit)) + .expect("could not set LCD RS") + } + + fn enable(&mut self, bit: bool) { + self.en + .set_state(PinState::from(bit)) + .expect("could not set LCD RS") + } + + fn data(&mut self, data: u8) { + let d4 = data & 0b00000001; + let d5 = data & 0b00000010; + let d6 = data & 0b00000100; + let d7 = data & 0b00001000; + + debug!("Writing data: d4:{}, d5:{}, d6:{}, d7:{}", d4, d5, d6, d7); + + self.d4 + .set_state(PinState::from(d4 > 0)) + .expect("could not set LCD D4"); + self.d5 + .set_state(PinState::from(d5 > 0)) + .expect("could not set LCD D5"); + self.d6 + .set_state(PinState::from(d6 > 0)) + .expect("could not set LCD D6"); + self.d7 + .set_state(PinState::from(d7 > 0)) + .expect("could not set LCD D7"); + } + + fn mode(&self) -> lcd::FunctionMode { + lcd::FunctionMode::Bit4 + } + + fn can_read(&self) -> bool { + false + } +} #[defmt::panic_handler] fn panic() -> ! { @@ -28,23 +135,17 @@ fn main() -> ! { let gpioa = dp.GPIOA.split(&mut rcc); let gpiob = dp.GPIOB.split(&mut rcc); - let gpioc = dp.GPIOC.split(&mut rcc); + let _gpioc = dp.GPIOC.split(&mut rcc); - // contrast over A0 analog port - // analog output seems to not be supported somehow? - let mut vO = gpioa.pa0.into_push_pull_output(); + // clock enable on D2 + let mut rs: D2PIN = gpioa.pa10.into_push_pull_output(); + // register select on D3, the lib wants that but I'd just put it on ground otherwise + let mut en: D3PIN = gpiob.pb3.into_push_pull_output(); - // literal D4-D7 ports etc as written on the nucleo board, mapped to the D4-D7 ports of the LCD - // controller - let d4 = gpiob.pb5.into_push_pull_output(); - let d5 = gpiob.pb4.into_push_pull_output(); - let d6 = gpiob.pb10.into_push_pull_output(); - let d7 = gpioa.pa8.into_push_pull_output(); - - // clock enable on D8 - let en = gpioa.pa9.into_push_pull_output(); - // register select on D9, the lib wants that but I'd just put it on ground otherwise - let rs = gpioc.pc7.into_push_pull_output(); + let mut d4: D4PIN = gpiob.pb5.into_push_pull_output(); + let mut d5: D5PIN = gpiob.pb4.into_push_pull_output(); + let mut d6: D6PIN = gpiob.pb10.into_push_pull_output(); + let mut d7: D7PIN = gpioa.pa8.into_push_pull_output(); // See https://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller#Interface // for the pins of the LCD @@ -52,32 +153,18 @@ fn main() -> ! { let mut delay = cp.SYST.delay(rcc.clocks); let mut led = gpioa.pa5.into_push_pull_output(); - let mut lcd = HD44780::new_4bit(rs, en, d4, d5, d6, d7, &mut delay) - .expect("could not init HD44780 driver"); - lcd.set_display_mode( - hd44780_driver::DisplayMode { - cursor_visibility: hd44780_driver::Cursor::Visible, - cursor_blink: hd44780_driver::CursorBlink::On, - display: hd44780_driver::Display::On, - }, - &mut delay, - ) - .expect("could not set display properties"); - lcd.reset(&mut delay).expect("could not reset the lcd"); - lcd.write_str("Hello world!", &mut delay) - .expect("could not write to LCD"); + + led.set_high().unwrap(); + info!("Writing to LCD..."); + let mut lcd = LCDHardware::new( + &mut d4, &mut d5, &mut d6, &mut d7, &mut rs, &mut en, &mut delay, + ); + write!(&mut lcd, "Hello World").expect("could not write to lcd"); + info!("Done!"); + led.set_low().unwrap(); let mut i = 0; loop { - vO.set_low().expect("set contrast low boom?"); - led.set_high().unwrap(); - info!("Writing to LCD..."); - lcd.write_str("Hello world!\nGoing on", &mut delay) - .expect("could not write to LCD"); - - info!("Done!"); - led.set_low().unwrap(); - delay.delay_ms(500_u16); i += 1;