From 7d8f5f68700eba0650277ed0efa63f30b8b6425e Mon Sep 17 00:00:00 2001 From: finga Date: Sat, 19 Mar 2022 18:40:18 +0100 Subject: [PATCH] fw-rust: Create a print `u8` function for setup Create `print_u8()` helper function to print `u8` primitives to lcd. Refactor contrast and backlight variables to also keep them in a global `AtomicU8`. --- firmware/rust/src/lcd.rs | 34 +++++++++++++++++++++++++++++++ firmware/rust/src/main.rs | 17 +++++++++------- firmware/rust/src/screen/setup.rs | 18 +++++++++------- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/firmware/rust/src/lcd.rs b/firmware/rust/src/lcd.rs index 9ac6564..55b8f86 100644 --- a/firmware/rust/src/lcd.rs +++ b/firmware/rust/src/lcd.rs @@ -5,6 +5,7 @@ use atmega_hal::{ Spi, }; use avr_device::interrupt; +use core::convert::TryInto; use embedded_hal::{blocking::delay::DelayMs, spi::FullDuplex}; use nb::block; @@ -161,6 +162,39 @@ impl Lcd { } } + pub fn print_u8(&mut self, segment: u8, page: u8, digits: u8, data: u8) { + assert!(digits <= 3); + let mut delay = Delay::::new(); + + let mut array = [0usize; 3]; + for (i, item) in array.iter_mut().enumerate() { + *item = ((data / 10_u8.pow(i.try_into().unwrap())) % 10).into(); + } + array.reverse(); + + for i in 0..2 { + self.move_cursor(segment, page + i); + + // TODO: This delay fixes issues, try find a better solution + delay.delay_ms(1_u8); + self.cd.set_high(); + + block!(self.spi.send(0x00)).unwrap(); + block!(self.spi.send(0x00)).unwrap(); + for j in 3 - digits..3 { + for segment in SYMBOL_TABLE[array[j as usize]][i as usize] { + block!(self.spi.send(*segment)).unwrap(); + } + block!(self.spi.send(0x00)).unwrap(); + } + block!(self.spi.send(0x00)).unwrap(); + + // TODO: This delay fixes issues, try find a better solution + delay.delay_ms(1_u8); + self.cd.set_low(); + } + } + pub fn draw(&mut self, screen: &Screens) { interrupt::free(|_cs| { self.clear(); diff --git a/firmware/rust/src/main.rs b/firmware/rust/src/main.rs index cffdd0f..a5ac1fc 100644 --- a/firmware/rust/src/main.rs +++ b/firmware/rust/src/main.rs @@ -11,7 +11,7 @@ use atmega_hal::{ }; use avr_device::interrupt; use avr_eeprom::{eeprom, Eeprom}; -use core::sync::atomic::{AtomicBool, Ordering}; +use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use embedded_hal::{ blocking::delay::DelayMs, spi::{Mode, Phase, Polarity}, @@ -28,8 +28,8 @@ use rotary::{Direction, Rotary}; use screen::Screens; eeprom! { - static eeprom CONTRAST: u8 = 8; - static eeprom BACKLIGHT: u8 = 1; + static eeprom EEPROM_CONTRAST: u8 = 8; + static eeprom EEPROM_BACKLIGHT: u8 = 1; } pub enum Input { @@ -42,6 +42,8 @@ pub enum Input { static UPDATE_ENCODER: AtomicBool = AtomicBool::new(false); static UPDATE_BUTTON: AtomicBool = AtomicBool::new(false); static UPDATE_TIMER: AtomicBool = AtomicBool::new(false); +static CONTRAST: AtomicU8 = AtomicU8::new(0); +static BACKLIGHT: AtomicU8 = AtomicU8::new(0); #[interrupt(atmega328p)] #[allow(non_snake_case)] @@ -76,8 +78,8 @@ fn main() -> ! { let mut delay = Delay::::new(); // Get contrast and backlight from EEPROM - let contrast = eeprom.read_value(&CONTRAST); - let backlight = eeprom.read_value(&BACKLIGHT); + CONTRAST.store(eeprom.read_value(&EEPROM_CONTRAST), Ordering::SeqCst); + BACKLIGHT.store(eeprom.read_value(&EEPROM_BACKLIGHT), Ordering::SeqCst); // Init display backlight let tc0 = dp.TC0; @@ -92,7 +94,8 @@ fn main() -> ! { w }); tc0.ocr0a.write(|w| unsafe { w.bits(255) }); - tc0.ocr0b.write(|w| unsafe { w.bits(backlight) }); + tc0.ocr0b + .write(|w| unsafe { w.bits(BACKLIGHT.load(Ordering::SeqCst)) }); pins.pd5.into_output(); // Init SPI @@ -114,7 +117,7 @@ fn main() -> ! { // Init LCD let mut lcd = Lcd::new(spi, pins.pb0.into_output(), pins.pb1.into_output()); - lcd.init(contrast); + lcd.init(CONTRAST.load(Ordering::SeqCst)); // Init encoder let mut encoder = Rotary::new(pins.pb6.into_pull_up_input(), pins.pb7.into_pull_up_input()); diff --git a/firmware/rust/src/screen/setup.rs b/firmware/rust/src/screen/setup.rs index 5f3358d..a3a61bc 100644 --- a/firmware/rust/src/screen/setup.rs +++ b/firmware/rust/src/screen/setup.rs @@ -1,5 +1,6 @@ use super::{Home, Screen, Screens, Splash}; -use crate::{lcd::Lcd, Input}; +use crate::{lcd::Lcd, Input, BACKLIGHT, CONTRAST}; +use core::sync::atomic::Ordering; enum Selection { Contrast, @@ -46,15 +47,18 @@ impl Setup { impl Screen for Setup { fn draw(&self, lcd: &mut Lcd) { + let contrast = CONTRAST.load(Ordering::SeqCst); + let backlight = BACKLIGHT.load(Ordering::SeqCst); + match &self.active { Selection::Contrast => { lcd.fill_area(0, 0, 33, 2, 0xFF); lcd.print_inverted(33, 0, "SETUP"); lcd.fill_area(69, 0, 33, 2, 0xFF); lcd.print_inverted(0, 2, "CONTRAST:"); - lcd.print(89, 2, "00"); + lcd.print_u8(89, 2, 2, contrast); lcd.print(0, 4, "BACKLIGHT:"); - lcd.print(83, 4, "000"); + lcd.print_u8(83, 2, 3, backlight); lcd.print(36, 6, "BACK"); } Selection::Backlight => { @@ -62,9 +66,9 @@ impl Screen for Setup { lcd.print_inverted(33, 0, "SETUP"); lcd.fill_area(69, 0, 33, 2, 0xFF); lcd.print(0, 2, "CONTRAST:"); - lcd.print(89, 2, "00"); + lcd.print_u8(89, 2, 2, contrast); lcd.print_inverted(0, 4, "BACKLIGHT:"); - lcd.print(83, 4, "000"); + lcd.print_u8(83, 2, 3, backlight); lcd.print(36, 6, "BACK"); } Selection::Back => { @@ -72,9 +76,9 @@ impl Screen for Setup { lcd.print_inverted(33, 0, "SETUP"); lcd.fill_area(69, 0, 33, 2, 0xFF); lcd.print(0, 2, "CONTRAST:"); - lcd.print(89, 2, "00"); + lcd.print_u8(89, 2, 2, contrast); lcd.print(0, 4, "BACKLIGHT:"); - lcd.print(83, 4, "000"); + lcd.print_u8(83, 2, 3, backlight); lcd.print_inverted(36, 6, "BACK"); } }