162 lines
4.5 KiB
Rust
Executable file
162 lines
4.5 KiB
Rust
Executable file
#![no_main]
|
|
#![no_std]
|
|
|
|
use chrono::NaiveDateTime;
|
|
use defmt::info;
|
|
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<Output<PushPull>>,
|
|
PC7<Output<PushPull>>,
|
|
PB5<Output<PushPull>>,
|
|
PB4<Output<PushPull>>,
|
|
PB10<Output<PushPull>>,
|
|
PA8<Output<PushPull>>,
|
|
>,
|
|
>;
|
|
|
|
const UNIXTIME_OF_COMPILATION: i64 = compile_time::unix_local!();
|
|
const BUF_SIZE: usize = 20;
|
|
|
|
#[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 led = gpioa.pa5.into_push_pull_output();
|
|
|
|
let mut buf: String<BUF_SIZE> = String::new();
|
|
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");
|
|
|
|
let start_time = chrono::DateTime::from_timestamp(UNIXTIME_OF_COMPILATION, 0)
|
|
.expect("The Compilation time was invalid")
|
|
.naive_utc();
|
|
info!("Compiled time: {}", UNIXTIME_OF_COMPILATION);
|
|
let mut rtc = Rtc::new(dp.RTC, &mut rcc, &pwr, Some(start_time)).expect("Could not setup RTC");
|
|
|
|
let mut i: u32 = 0;
|
|
let mut timestamp = rtc.now();
|
|
info!("First RTC time: {}", timestamp.and_utc().timestamp());
|
|
loop {
|
|
led.set_high().unwrap();
|
|
|
|
timestamp = rtc.now();
|
|
display_time(
|
|
×tamp,
|
|
&mut lcd,
|
|
&mut delay,
|
|
&mut buf,
|
|
timestamp.second() == 0 || i == 0,
|
|
);
|
|
|
|
led.set_low().unwrap();
|
|
|
|
delay.delay_us(990_u32);
|
|
i += 1;
|
|
}
|
|
}
|
|
|
|
fn display_time(
|
|
timestamp: &NaiveDateTime,
|
|
lcd: &mut Lcd,
|
|
delay: &mut Delay,
|
|
buf: &mut String<BUF_SIZE>,
|
|
full_update: bool,
|
|
) {
|
|
if full_update {
|
|
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,
|
|
" {: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");
|
|
|
|
lcd.set_cursor_pos(40, delay)
|
|
.expect("could not move cursor to start");
|
|
|
|
buf.clear();
|
|
write!(buf, " (UTC) ",).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,
|
|
" {: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");
|
|
}
|