firmware: Refactor dealing with EEPROM
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
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:
parent
d1faf584c5
commit
46bd28b46c
5 changed files with 40 additions and 78 deletions
|
@ -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(())
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ use core::{convert::TryInto, iter};
|
||||||
use embedded_hal::{blocking::delay::DelayUs, spi::FullDuplex};
|
use embedded_hal::{blocking::delay::DelayUs, spi::FullDuplex};
|
||||||
use nb::block;
|
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
|
// TODO: Make `cd` and `rst` pins generic pins
|
||||||
pub struct Lcd {
|
pub struct Lcd {
|
||||||
|
@ -41,27 +41,27 @@ impl Lcd {
|
||||||
self.cd.set_low();
|
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
|
0x40, // (6) Set Scroll Line: Display start line 0
|
||||||
0xA1, // (13) Set SEG direction: SEG reverse
|
0xA1, // (13) Set SEG direction: SEG reverse
|
||||||
0xC0, // (14) Set COM direction: Normal COM0 - COM63
|
0xC0, // (14) Set COM direction: Normal COM0 - COM63
|
||||||
0xA6, // (11) Set Inverse Display: Display inverse off
|
0xA6, // (11) Set Inverse Display: Display inverse off
|
||||||
0xA2, // (17) Set LCD Bias Ratio: Set Bias 1/9 (Duty 1/65)
|
0xA2, // (17) Set LCD Bias Ratio: Set Bias 1/9 (Duty 1/65)
|
||||||
0x2F, // (5) Set Power Control: Booster, Regulator and Follower on
|
0x2F, // (5) Set Power Control: Booster, Regulator and Follower on
|
||||||
0x27, // (8) Set VLCD Resistor Ratio: Set Contrast
|
0x27, // (8) Set VLCD Resistor Ratio: Set Contrast
|
||||||
0xEE, // (18) Reset Cursor Update Mode
|
0xEE, // (18) Reset Cursor Update Mode
|
||||||
0x81, // (9) Set Electronic Volume: Set Contrast
|
0x81, // (9) Set Electronic Volume: Set Contrast
|
||||||
block!(eeprom::read_byte(&CONTRAST)).unwrap(), // (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
|
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
|
0x90, // (25) Set Adv. Program Control 0: Set Temperature compensation curve to -0.11%/°C
|
||||||
0xAF, // (12) Set Display Enable: Display on
|
0xAF, // (12) Set Display Enable: Display on
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&mut self) {
|
pub fn init(&mut self, contrast: u8) {
|
||||||
self.rst.set_high();
|
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) {
|
pub fn set_contrast(&mut self, contrast: u8) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ use embedded_hal::{
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
mod assets;
|
mod assets;
|
||||||
mod eeprom;
|
|
||||||
mod lcd;
|
mod lcd;
|
||||||
mod rotary;
|
mod rotary;
|
||||||
mod screen;
|
mod screen;
|
||||||
|
@ -80,6 +79,7 @@ impl ClockGenerator {
|
||||||
Self {
|
Self {
|
||||||
screen: Screen::new(
|
screen: Screen::new(
|
||||||
dp.TC0,
|
dp.TC0,
|
||||||
|
dp.EEPROM,
|
||||||
spi,
|
spi,
|
||||||
pins.pd5.into_output(),
|
pins.pd5.into_output(),
|
||||||
pins.pb0.into_output(),
|
pins.pb0.into_output(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use atmega_hal::{
|
use atmega_hal::{
|
||||||
pac::TC0,
|
pac::{EEPROM, TC0},
|
||||||
port::{mode::Output, Pin, PB0, PB1, PD5},
|
port::{mode::Output, Pin, PB0, PB1, PD5},
|
||||||
Spi,
|
Eeprom, Spi,
|
||||||
};
|
};
|
||||||
use si5351::{ClockOutput, Si5351, Si5351Device, PLL};
|
use si5351::{ClockOutput, Si5351, Si5351Device, PLL};
|
||||||
|
|
||||||
|
@ -12,9 +12,8 @@ mod splash;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::{OFF, ON, PLL_A, PLL_B},
|
assets::{OFF, ON, PLL_A, PLL_B},
|
||||||
eeprom,
|
|
||||||
lcd::Lcd,
|
lcd::Lcd,
|
||||||
I2c, Input, BACKLIGHT,
|
I2c, Input, BACKLIGHT, CONTRAST,
|
||||||
};
|
};
|
||||||
pub use channel::Channel;
|
pub use channel::Channel;
|
||||||
pub use home::Home;
|
pub use home::Home;
|
||||||
|
@ -83,6 +82,7 @@ impl Screens {
|
||||||
pub struct Screen {
|
pub struct Screen {
|
||||||
lcd: Lcd,
|
lcd: Lcd,
|
||||||
tc0: TC0,
|
tc0: TC0,
|
||||||
|
eeprom: Eeprom,
|
||||||
pwm: Pin<Output, PD5>,
|
pwm: Pin<Output, PD5>,
|
||||||
screen: Screens,
|
screen: Screens,
|
||||||
si5351: Si5351Device<I2c>,
|
si5351: Si5351Device<I2c>,
|
||||||
|
@ -92,6 +92,7 @@ pub struct Screen {
|
||||||
impl Screen {
|
impl Screen {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
tc0: TC0,
|
tc0: TC0,
|
||||||
|
eeprom: EEPROM,
|
||||||
spi: Spi,
|
spi: Spi,
|
||||||
pwm: Pin<Output, PD5>,
|
pwm: Pin<Output, PD5>,
|
||||||
cd: Pin<Output, PB0>,
|
cd: Pin<Output, PB0>,
|
||||||
|
@ -101,6 +102,7 @@ impl Screen {
|
||||||
Self {
|
Self {
|
||||||
lcd: Lcd::new(spi, cd, rst),
|
lcd: Lcd::new(spi, cd, rst),
|
||||||
tc0,
|
tc0,
|
||||||
|
eeprom: Eeprom::new(eeprom),
|
||||||
pwm,
|
pwm,
|
||||||
screen: Screens::Splash(Splash),
|
screen: Screens::Splash(Splash),
|
||||||
si5351: Si5351Device::new_adafruit_module(i2c),
|
si5351: Si5351Device::new_adafruit_module(i2c),
|
||||||
|
@ -134,10 +136,11 @@ impl Screen {
|
||||||
w.wgm0().pwm_fast();
|
w.wgm0().pwm_fast();
|
||||||
w.com0b().match_clear()
|
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
|
// Init lcd display controller
|
||||||
self.lcd.init();
|
self.lcd
|
||||||
|
.init(self.eeprom.read_byte(&CONTRAST as *const _ as u16));
|
||||||
self.draw();
|
self.draw();
|
||||||
|
|
||||||
// Init Si5351
|
// Init Si5351
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{Event, Home, Screens};
|
use super::{Event, Home, Screens};
|
||||||
use crate::{eeprom, lcd::Lcd, Input, BACKLIGHT, CONTRAST};
|
use crate::{lcd::Lcd, Input, BACKLIGHT, CONTRAST};
|
||||||
use nb::block;
|
use atmega_hal::{Eeprom, Peripherals};
|
||||||
|
|
||||||
enum Selection {
|
enum Selection {
|
||||||
Backlight,
|
Backlight,
|
||||||
|
@ -14,14 +14,19 @@ pub struct Setup {
|
||||||
active: Selection,
|
active: Selection,
|
||||||
backlight: u8,
|
backlight: u8,
|
||||||
contrast: u8,
|
contrast: u8,
|
||||||
|
eeprom: Eeprom,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Setup {
|
impl Setup {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
let dp = unsafe { Peripherals::steal() };
|
||||||
|
let ep = Eeprom::new(dp.EEPROM);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
active: Selection::Backlight,
|
active: Selection::Backlight,
|
||||||
backlight: block!(eeprom::read_byte(&BACKLIGHT)).unwrap(),
|
backlight: ep.read_byte(&BACKLIGHT as *const _ as u16),
|
||||||
contrast: block!(eeprom::read_byte(&CONTRAST)).unwrap(),
|
contrast: ep.read_byte(&CONTRAST as *const _ as u16),
|
||||||
|
eeprom: ep,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +58,13 @@ impl Setup {
|
||||||
return Event::Backlight(self.backlight);
|
return Event::Backlight(self.backlight);
|
||||||
}
|
}
|
||||||
Input::Select => {
|
Input::Select => {
|
||||||
block!(eeprom::write_byte(&BACKLIGHT, self.backlight)).unwrap();
|
self.eeprom
|
||||||
|
.write_byte(&BACKLIGHT as *const _ as u16, self.backlight);
|
||||||
Selection::Backlight
|
Selection::Backlight
|
||||||
}
|
}
|
||||||
Input::Back => {
|
Input::Back => {
|
||||||
self.active = Selection::Backlight;
|
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);
|
return Event::Backlight(self.backlight);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -88,12 +94,13 @@ impl Setup {
|
||||||
return Event::Contrast(self.contrast);
|
return Event::Contrast(self.contrast);
|
||||||
}
|
}
|
||||||
Input::Select => {
|
Input::Select => {
|
||||||
block!(eeprom::write_byte(&CONTRAST, self.contrast)).unwrap();
|
self.eeprom
|
||||||
|
.write_byte(&CONTRAST as *const _ as u16, self.contrast);
|
||||||
Selection::Contrast
|
Selection::Contrast
|
||||||
}
|
}
|
||||||
Input::Back => {
|
Input::Back => {
|
||||||
self.active = Selection::Contrast;
|
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);
|
return Event::Contrast(self.contrast);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue