From 46bd28b46cf9b098cf28f87cb4417a1870224038 Mon Sep 17 00:00:00 2001 From: finga Date: Sat, 27 May 2023 15:06:18 +0200 Subject: [PATCH] firmware: Refactor dealing with EEPROM Use the API that was added to the AVR crate for EEPROM access. --- firmware/rust/src/eeprom.rs | 48 ------------------------------- firmware/rust/src/lcd.rs | 28 +++++++++--------- firmware/rust/src/main.rs | 2 +- firmware/rust/src/screen/mod.rs | 17 ++++++----- firmware/rust/src/screen/setup.rs | 23 +++++++++------ 5 files changed, 40 insertions(+), 78 deletions(-) delete mode 100644 firmware/rust/src/eeprom.rs diff --git a/firmware/rust/src/eeprom.rs b/firmware/rust/src/eeprom.rs deleted file mode 100644 index 5a0c54f..0000000 --- a/firmware/rust/src/eeprom.rs +++ /dev/null @@ -1,48 +0,0 @@ -use atmega_hal::Peripherals; -use avr_device::interrupt; -use core::convert::Infallible; -use nb::Error::WouldBlock; - -pub fn read_byte(p_addr: *const u8) -> nb::Result { - let dp = unsafe { Peripherals::steal() }; - let eeprom = dp.EEPROM; - - // Wait for completion of previous access - if eeprom.eecr.read().eepe().bit_is_set() { - return Err(WouldBlock); - } - - interrupt::free(|_cs| { - // Write address into EEPROM address register - eeprom.eear.write(|w| w.bits(p_addr as u16)); - // Start to read from EEPROM by setting EERE - eeprom.eecr.write(|w| w.eere().set_bit()); - }); - - // Return data from EEPROM data register - Ok(eeprom.eedr.read().bits()) -} - -pub fn write_byte(p_addr: *const u8, data: u8) -> nb::Result<(), Infallible> { - let dp = unsafe { Peripherals::steal() }; - let eeprom = dp.EEPROM; - - // Wait for completion of previous access - if eeprom.eecr.read().eepe().bit_is_set() { - return Err(WouldBlock); - } - - interrupt::free(|_cs| { - // Write address into EEPROM address register - eeprom.eear.write(|w| w.bits(p_addr as u16)); - // Write data into EEPROM data register - eeprom.eedr.write(|w| w.bits(data)); - // Enable writing to the EEPROM by setting EEMPE - eeprom.eecr.write(|w| w.eempe().set_bit()); - // Start to write to EEPROM by setting EEPE - eeprom.eecr.write(|w| w.eepe().set_bit()); - }); - - // Return data from EEPROM data register - Ok(()) -} diff --git a/firmware/rust/src/lcd.rs b/firmware/rust/src/lcd.rs index 81dd163..afc1b23 100644 --- a/firmware/rust/src/lcd.rs +++ b/firmware/rust/src/lcd.rs @@ -7,7 +7,7 @@ use core::{convert::TryInto, iter}; use embedded_hal::{blocking::delay::DelayUs, spi::FullDuplex}; use nb::block; -use crate::{assets::SYMBOL_TABLE, eeprom, DefaultClock, CONTRAST}; +use crate::{assets::SYMBOL_TABLE, DefaultClock}; // TODO: Make `cd` and `rst` pins generic pins pub struct Lcd { @@ -41,27 +41,27 @@ impl Lcd { self.cd.set_low(); } - fn init_sequence() -> [u8; 13] { + fn init_sequence(contrast: u8) -> [u8; 13] { [ - 0x40, // (6) Set Scroll Line: Display start line 0 - 0xA1, // (13) Set SEG direction: SEG reverse - 0xC0, // (14) Set COM direction: Normal COM0 - COM63 - 0xA6, // (11) Set Inverse Display: Display inverse off - 0xA2, // (17) Set LCD Bias Ratio: Set Bias 1/9 (Duty 1/65) - 0x2F, // (5) Set Power Control: Booster, Regulator and Follower on - 0x27, // (8) Set VLCD Resistor Ratio: Set Contrast - 0xEE, // (18) Reset Cursor Update Mode - 0x81, // (9) Set Electronic Volume: Set Contrast - block!(eeprom::read_byte(&CONTRAST)).unwrap(), // (9) Set Electronic Volume: Set Contrast + 0x40, // (6) Set Scroll Line: Display start line 0 + 0xA1, // (13) Set SEG direction: SEG reverse + 0xC0, // (14) Set COM direction: Normal COM0 - COM63 + 0xA6, // (11) Set Inverse Display: Display inverse off + 0xA2, // (17) Set LCD Bias Ratio: Set Bias 1/9 (Duty 1/65) + 0x2F, // (5) Set Power Control: Booster, Regulator and Follower on + 0x27, // (8) Set VLCD Resistor Ratio: Set Contrast + 0xEE, // (18) Reset Cursor Update Mode + 0x81, // (9) Set Electronic Volume: Set Contrast + contrast, // (9) Set Electronic Volume: Set Contrast 0xFA, // (25) Set Adv. Program Control 0: Set Temperature compensation curve to -0.11%/°C 0x90, // (25) Set Adv. Program Control 0: Set Temperature compensation curve to -0.11%/°C 0xAF, // (12) Set Display Enable: Display on ] } - pub fn init(&mut self) { + pub fn init(&mut self, contrast: u8) { self.rst.set_high(); - self.control(Lcd::init_sequence().iter()); + self.control(Lcd::init_sequence(contrast).iter()); } pub fn set_contrast(&mut self, contrast: u8) { diff --git a/firmware/rust/src/main.rs b/firmware/rust/src/main.rs index 105875c..bd2298a 100644 --- a/firmware/rust/src/main.rs +++ b/firmware/rust/src/main.rs @@ -20,7 +20,6 @@ use embedded_hal::{ use panic_halt as _; mod assets; -mod eeprom; mod lcd; mod rotary; mod screen; @@ -80,6 +79,7 @@ impl ClockGenerator { Self { screen: Screen::new( dp.TC0, + dp.EEPROM, spi, pins.pd5.into_output(), pins.pb0.into_output(), diff --git a/firmware/rust/src/screen/mod.rs b/firmware/rust/src/screen/mod.rs index 636cf41..065278c 100644 --- a/firmware/rust/src/screen/mod.rs +++ b/firmware/rust/src/screen/mod.rs @@ -1,7 +1,7 @@ use atmega_hal::{ - pac::TC0, + pac::{EEPROM, TC0}, port::{mode::Output, Pin, PB0, PB1, PD5}, - Spi, + Eeprom, Spi, }; use si5351::{ClockOutput, Si5351, Si5351Device, PLL}; @@ -12,9 +12,8 @@ mod splash; use crate::{ assets::{OFF, ON, PLL_A, PLL_B}, - eeprom, lcd::Lcd, - I2c, Input, BACKLIGHT, + I2c, Input, BACKLIGHT, CONTRAST, }; pub use channel::Channel; pub use home::Home; @@ -83,6 +82,7 @@ impl Screens { pub struct Screen { lcd: Lcd, tc0: TC0, + eeprom: Eeprom, pwm: Pin, screen: Screens, si5351: Si5351Device, @@ -92,6 +92,7 @@ pub struct Screen { impl Screen { pub fn new( tc0: TC0, + eeprom: EEPROM, spi: Spi, pwm: Pin, cd: Pin, @@ -101,6 +102,7 @@ impl Screen { Self { lcd: Lcd::new(spi, cd, rst), tc0, + eeprom: Eeprom::new(eeprom), pwm, screen: Screens::Splash(Splash), si5351: Si5351Device::new_adafruit_module(i2c), @@ -134,10 +136,11 @@ impl Screen { w.wgm0().pwm_fast(); w.com0b().match_clear() }); - self.set_backlight(nb::block!(eeprom::read_byte(&BACKLIGHT)).unwrap()); + self.set_backlight(self.eeprom.read_byte(&BACKLIGHT as *const _ as u16)); - // Init lcd display - self.lcd.init(); + // Init lcd display controller + self.lcd + .init(self.eeprom.read_byte(&CONTRAST as *const _ as u16)); self.draw(); // Init Si5351 diff --git a/firmware/rust/src/screen/setup.rs b/firmware/rust/src/screen/setup.rs index 7e5ce82..b9260a6 100644 --- a/firmware/rust/src/screen/setup.rs +++ b/firmware/rust/src/screen/setup.rs @@ -1,6 +1,6 @@ use super::{Event, Home, Screens}; -use crate::{eeprom, lcd::Lcd, Input, BACKLIGHT, CONTRAST}; -use nb::block; +use crate::{lcd::Lcd, Input, BACKLIGHT, CONTRAST}; +use atmega_hal::{Eeprom, Peripherals}; enum Selection { Backlight, @@ -14,14 +14,19 @@ pub struct Setup { active: Selection, backlight: u8, contrast: u8, + eeprom: Eeprom, } impl Setup { pub fn new() -> Self { + let dp = unsafe { Peripherals::steal() }; + let ep = Eeprom::new(dp.EEPROM); + Self { active: Selection::Backlight, - backlight: block!(eeprom::read_byte(&BACKLIGHT)).unwrap(), - contrast: block!(eeprom::read_byte(&CONTRAST)).unwrap(), + backlight: ep.read_byte(&BACKLIGHT as *const _ as u16), + contrast: ep.read_byte(&CONTRAST as *const _ as u16), + eeprom: ep, } } @@ -53,12 +58,13 @@ impl Setup { return Event::Backlight(self.backlight); } Input::Select => { - block!(eeprom::write_byte(&BACKLIGHT, self.backlight)).unwrap(); + self.eeprom + .write_byte(&BACKLIGHT as *const _ as u16, self.backlight); Selection::Backlight } Input::Back => { self.active = Selection::Backlight; - self.backlight = block!(eeprom::read_byte(&BACKLIGHT)).unwrap(); + self.backlight = self.eeprom.read_byte(&BACKLIGHT as *const _ as u16); return Event::Backlight(self.backlight); } }, @@ -88,12 +94,13 @@ impl Setup { return Event::Contrast(self.contrast); } Input::Select => { - block!(eeprom::write_byte(&CONTRAST, self.contrast)).unwrap(); + self.eeprom + .write_byte(&CONTRAST as *const _ as u16, self.contrast); Selection::Contrast } Input::Back => { self.active = Selection::Contrast; - self.contrast = block!(eeprom::read_byte(&CONTRAST)).unwrap(); + self.contrast = self.eeprom.read_byte(&CONTRAST as *const _ as u16); return Event::Contrast(self.contrast); } },