diff --git a/Cargo.toml b/Cargo.toml index 2e46d0c..49b8353 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,9 @@ defmt = {version="1.0.1", optional= true} defmt-rtt = {version="1.0.0", optional=true} panic-probe = { version = "0.3", features = ["print-defmt"], optional=true } +[profile.release] +debug = "full" # those are not on the board + [features] logging = ["dep:defmt", "dep:defmt-rtt", "dep:panic-probe"] @@ -40,3 +43,13 @@ required-features = ["logging"] name = "aes_ecb" path = "examples/aes_ecb.rs" required-features = ["logging"] + +[[example]] +name = "lcd" +path = "examples/lcd.rs" +required-features = ["logging"] + +[[example]] +name = "lcd-clock" +path = "examples/lcd-clock.rs" +required-features = ["logging"] diff --git a/examples/lcd-clock.rs b/examples/lcd-clock.rs new file mode 100755 index 0000000..c4104ae --- /dev/null +++ b/examples/lcd-clock.rs @@ -0,0 +1,131 @@ +#![no_main] +#![no_std] + +use heapless::String; +use panic_probe as _; + +use defmt_rtt as _; // global logger + +use core::fmt::Write; + +use cortex_m_rt::entry; +use hal::{ + delay::Delay, + gpio::{Output, PushPull, gpioa::*, gpiob::*, gpioc::*}, + pac, + prelude::*, + pwr::PWR, + rcc::Config, + rtc::{Datelike, Rtc, Timelike}, +}; +use hd44780_driver::HD44780; + +#[defmt::panic_handler] +fn panic() -> ! { + cortex_m::asm::udf() +} + +type Lcd = HD44780< + hd44780_driver::bus::FourBitBus< + PA9>, + PC7>, + PB5>, + PB4>, + PB10>, + PA8>, + >, +>; + +#[entry] +fn main() -> ! { + let dp = pac::Peripherals::take().unwrap(); + let cp = cortex_m::Peripherals::take().unwrap(); + + let mut rcc = dp.RCC.freeze(Config::hsi16()); + let pwr = PWR::new(dp.PWR, &mut rcc); + + let gpioa = dp.GPIOA.split(&mut rcc); + let gpiob = dp.GPIOB.split(&mut rcc); + let gpioc = dp.GPIOC.split(&mut rcc); + + // 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 D9 + let en = gpioc.pc7.into_push_pull_output(); + // register select on D8, the lib wants that but I'd just put it on ground otherwise + let rs = gpioa.pa9.into_push_pull_output(); + + // See https://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller#Interface + // for the pins of the LCD + + let mut delay = cp.SYST.delay(rcc.clocks); + + let mut rtc = Rtc::new(dp.RTC, &mut rcc, &pwr, None).unwrap(); + let mut led = gpioa.pa5.into_push_pull_output(); + + let mut lcd: 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::Invisible, + cursor_blink: hd44780_driver::CursorBlink::Off, + 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"); + + let mut buf: String<20> = String::new(); + loop { + led.set_high().unwrap(); + + display_time(&mut rtc, &mut lcd, &mut delay, &mut buf); + + led.set_low().unwrap(); + + delay.delay_ms(1000_u16); + } +} + +fn display_time(rtc: &mut Rtc, lcd: &mut Lcd, delay: &mut Delay, buf: &mut String<20>) { + let timestamp = rtc.now(); + + lcd.clear(delay).expect("could not clear the display"); + + lcd.set_cursor_pos(0, delay) + .expect("could not move cursor to start"); + + buf.clear(); + write!( + buf, + " {:02}:{:02}:{:02} ", + timestamp.hour(), + timestamp.minute(), + timestamp.second() + ) + .expect("could not format text content for display"); + lcd.write_str(buf, delay).expect("could not write to LCD"); + + lcd.set_cursor_pos(20, delay) + .expect("could not move cursor to line 2"); + + buf.clear(); + write!( + buf, + " {:04}-{:02}-{:02} ", + timestamp.year(), + timestamp.month(), + timestamp.day() + ) + .expect("could not format text content for display"); + + lcd.write_str(buf, delay).expect("could not write to LCD"); +} diff --git a/examples/lcd.rs b/examples/lcd.rs index 3b83aab..4c84770 100755 --- a/examples/lcd.rs +++ b/examples/lcd.rs @@ -72,14 +72,14 @@ fn main() -> ! { lcd.set_cursor_pos(0, &mut delay) .expect("could not move cursor to start"); - lcd.write_str("Hello world!", &mut delay) + lcd.write_str(" Hello world! ", &mut delay) .expect("could not write to LCD"); lcd.set_cursor_pos(20, &mut delay) .expect("could not move cursor to line 2"); buf.clear(); - write!(&mut buf, "Iteration: {i}").expect("could not format text content for display"); + write!(&mut buf, " Iteration: {i:07} ").expect("could not format text content for display"); lcd.write_str(&buf, &mut delay) .expect("could not write to LCD");