firmware: Refactor dealing with EEPROM
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Use the API that was added to the AVR crate for EEPROM access.
This commit is contained in:
finga 2023-05-27 15:06:18 +02:00
parent d1faf584c5
commit 46bd28b46c
5 changed files with 40 additions and 78 deletions

View file

@ -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<u8, 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));
// 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(())
}

View file

@ -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) {

View file

@ -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(),

View file

@ -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<Output, PD5>,
screen: Screens,
si5351: Si5351Device<I2c>,
@ -92,6 +92,7 @@ pub struct Screen {
impl Screen {
pub fn new(
tc0: TC0,
eeprom: EEPROM,
spi: Spi,
pwm: Pin<Output, PD5>,
cd: Pin<Output, PB0>,
@ -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

View file

@ -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);
}
},