fw-rust: Refactor printing to the LCD
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Pass iterators for control and display data to the printing function instead of just printing it.
This commit is contained in:
parent
d73d5126dd
commit
343b95dc78
4 changed files with 127 additions and 198 deletions
|
@ -3,7 +3,7 @@ use atmega_hal::{
|
|||
port::{mode::Output, Pin, PB0, PB1},
|
||||
Spi,
|
||||
};
|
||||
use core::convert::TryInto;
|
||||
use core::{convert::TryInto, iter};
|
||||
use embedded_hal::{blocking::delay::DelayUs, spi::FullDuplex};
|
||||
use nb::block;
|
||||
|
||||
|
@ -21,10 +21,28 @@ impl Lcd {
|
|||
Self { spi, cd, rst }
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
self.rst.set_high();
|
||||
pub fn control<'a>(&mut self, data: impl Iterator<Item = &'a u8>) {
|
||||
data.for_each(|d| block!(self.spi.send(*d)).unwrap());
|
||||
}
|
||||
|
||||
let init_sequence = [
|
||||
pub fn display<'a>(&mut self, invert: bool, data: impl Iterator<Item = &'a u8>) {
|
||||
let mut delay = Delay::<DefaultClock>::new();
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_high();
|
||||
|
||||
if invert {
|
||||
data.for_each(|d| block!(self.spi.send(!*d)).unwrap());
|
||||
} else {
|
||||
data.for_each(|d| block!(self.spi.send(*d)).unwrap());
|
||||
}
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_low();
|
||||
}
|
||||
|
||||
fn init_sequence() -> [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
|
||||
|
@ -38,47 +56,36 @@ impl Lcd {
|
|||
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
|
||||
];
|
||||
]
|
||||
}
|
||||
|
||||
for i in init_sequence.iter() {
|
||||
block!(self.spi.send(*i)).unwrap();
|
||||
}
|
||||
pub fn init(&mut self) {
|
||||
self.rst.set_high();
|
||||
self.control(Lcd::init_sequence().iter());
|
||||
}
|
||||
|
||||
pub fn set_contrast(&mut self, contrast: u8) {
|
||||
assert!(contrast <= 63);
|
||||
|
||||
block!(self.spi.send(0x81)).unwrap(); // (9) Set Electronic Volume: Set Contrast
|
||||
block!(self.spi.send(contrast)).unwrap(); // (9) Set Electronic Volume: Set Contrast
|
||||
self.control([0x81, contrast].iter());
|
||||
}
|
||||
|
||||
pub fn move_cursor(&mut self, segment: u8, page: u8) {
|
||||
assert!(segment < 102);
|
||||
assert!(page < 8);
|
||||
|
||||
block!(self.spi.send(0x0F & segment)).unwrap();
|
||||
block!(self.spi.send(0x10 + (segment >> 4))).unwrap();
|
||||
block!(self.spi.send(0xB0 + page)).unwrap();
|
||||
self.control([0x0F & segment, 0x10 + (segment >> 4), 0xB0 + page].iter());
|
||||
}
|
||||
|
||||
fn fill(&mut self, segment: u8, page: u8, width: u8, data: u8) {
|
||||
assert!(segment + width <= 102);
|
||||
let mut delay = Delay::<DefaultClock>::new();
|
||||
|
||||
self.move_cursor(segment, page);
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_high();
|
||||
|
||||
for _ in 0..width {
|
||||
block!(self.spi.send(data)).unwrap();
|
||||
}
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_low();
|
||||
self.display(false, iter::repeat(&data).take(width.into()));
|
||||
}
|
||||
|
||||
pub fn fill_area(&mut self, segment: u8, page: u8, width: u8, height: u8, data: u8) {
|
||||
assert!(segment + width <= 102);
|
||||
assert!(page + height <= 8);
|
||||
|
||||
for i in 0..height {
|
||||
|
@ -86,57 +93,25 @@ impl Lcd {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn print(&mut self, segment: u8, page: u8, string: &str) {
|
||||
let mut delay = Delay::<DefaultClock>::new();
|
||||
|
||||
pub fn print(&mut self, segment: u8, page: u8, invert: bool, string: &str) {
|
||||
for i in 0..2 {
|
||||
self.move_cursor(segment, page + i);
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_high();
|
||||
|
||||
block!(self.spi.send(0x00)).unwrap();
|
||||
block!(self.spi.send(0x00)).unwrap();
|
||||
for c in string.chars() {
|
||||
for segment in SYMBOL_TABLE[c as usize - 46][i as usize] {
|
||||
block!(self.spi.send(*segment)).unwrap();
|
||||
}
|
||||
block!(self.spi.send(0x00)).unwrap();
|
||||
}
|
||||
block!(self.spi.send(0x00)).unwrap();
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_low();
|
||||
self.display(
|
||||
invert,
|
||||
[0x00, 0x00]
|
||||
.iter()
|
||||
.chain(string.chars().flat_map(|c| {
|
||||
SYMBOL_TABLE[c as usize - 46][i as usize]
|
||||
.iter()
|
||||
.chain(&[0x00])
|
||||
}))
|
||||
.chain(&[0x00]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_inverted(&mut self, segment: u8, page: u8, string: &str) {
|
||||
let mut delay = Delay::<DefaultClock>::new();
|
||||
|
||||
for i in 0..2 {
|
||||
self.move_cursor(segment, page + i);
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_high();
|
||||
|
||||
block!(self.spi.send(0xFF)).unwrap();
|
||||
block!(self.spi.send(0xFF)).unwrap();
|
||||
for c in string.chars() {
|
||||
for segment in SYMBOL_TABLE[c as usize - 46][i as usize] {
|
||||
block!(self.spi.send(!*segment)).unwrap();
|
||||
}
|
||||
block!(self.spi.send(0xFF)).unwrap();
|
||||
}
|
||||
block!(self.spi.send(0xFF)).unwrap();
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_low();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_u8(&mut self, segment: u8, page: u8, digits: u8, data: u8) {
|
||||
pub fn print_u8(&mut self, segment: u8, page: u8, digits: u8, invert: bool, data: u8) {
|
||||
assert!(digits <= 3);
|
||||
let mut delay = Delay::<DefaultClock>::new();
|
||||
|
||||
let mut array = [0_usize; 3];
|
||||
for (i, item) in array.iter_mut().enumerate() {
|
||||
|
@ -146,53 +121,17 @@ impl Lcd {
|
|||
|
||||
for i in 0..2 {
|
||||
self.move_cursor(segment, page + i);
|
||||
|
||||
delay.delay_us(5_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();
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_low();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_u8_inverted(&mut self, segment: u8, page: u8, digits: u8, data: u8) {
|
||||
assert!(digits <= 3);
|
||||
let mut delay = Delay::<DefaultClock>::new();
|
||||
|
||||
let mut array = [0usize; 3];
|
||||
for (i, item) in array.iter_mut().enumerate() {
|
||||
*item = (((data / 10_u8.pow(i.try_into().unwrap())) % 10) + 2).into();
|
||||
}
|
||||
array.reverse();
|
||||
|
||||
for i in 0..2 {
|
||||
self.move_cursor(segment, page + i);
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_high();
|
||||
|
||||
block!(self.spi.send(0xFF)).unwrap();
|
||||
block!(self.spi.send(0xFF)).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(0xFF)).unwrap();
|
||||
}
|
||||
block!(self.spi.send(0xFF)).unwrap();
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_low();
|
||||
self.display(
|
||||
invert,
|
||||
[0x00, 0x00]
|
||||
.iter()
|
||||
.chain(array.iter().flat_map(|c| {
|
||||
SYMBOL_TABLE[array[*c as usize]][i as usize]
|
||||
.iter()
|
||||
.chain(&[0x00])
|
||||
}))
|
||||
.chain(&[0x00]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,17 +259,7 @@ impl Lcd {
|
|||
}
|
||||
|
||||
pub fn print_icon(&mut self, segment: u8, page: u8, symbol: &[u8]) {
|
||||
let mut delay = Delay::<DefaultClock>::new();
|
||||
self.move_cursor(segment, page);
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_high();
|
||||
|
||||
for c in symbol {
|
||||
block!(self.spi.send(*c)).unwrap();
|
||||
}
|
||||
|
||||
delay.delay_us(5_u8);
|
||||
self.cd.set_low();
|
||||
self.display(false, symbol.iter());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,13 +111,13 @@ impl Channel {
|
|||
fn draw_enabled(&self, lcd: &mut Lcd, inverted: bool) {
|
||||
if inverted {
|
||||
match self.channel.enabled {
|
||||
false => lcd.print_inverted(13, 4, "OFF"),
|
||||
true => lcd.print_inverted(16, 4, "ON"),
|
||||
false => lcd.print(13, 4, true, "OFF"),
|
||||
true => lcd.print(16, 4, true, "ON"),
|
||||
}
|
||||
} else {
|
||||
match self.channel.enabled {
|
||||
false => lcd.print(13, 4, "OFF"),
|
||||
true => lcd.print(16, 4, "ON"),
|
||||
false => lcd.print(13, 4, false, "OFF"),
|
||||
true => lcd.print(16, 4, false, "ON"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,66 +125,66 @@ impl Channel {
|
|||
pub fn draw(&self, lcd: &mut Lcd) {
|
||||
lcd.fill_area(0, 0, 19, 2, 0xFF);
|
||||
match self.channel.output {
|
||||
ClockOutput::Clk0 => lcd.print_inverted(19, 0, "CHANNEL_1"),
|
||||
ClockOutput::Clk1 => lcd.print_inverted(19, 0, "CHANNEL_2"),
|
||||
ClockOutput::Clk2 => lcd.print_inverted(19, 0, "CHANNEL_3"),
|
||||
ClockOutput::Clk0 => lcd.print(19, 0, true, "CHANNEL_1"),
|
||||
ClockOutput::Clk1 => lcd.print(19, 0, true, "CHANNEL_2"),
|
||||
ClockOutput::Clk2 => lcd.print(19, 0, true, "CHANNEL_3"),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
lcd.fill_area(83, 0, 19, 2, 0xFF);
|
||||
|
||||
match &self.active {
|
||||
Selection::Frequency => {
|
||||
lcd.print_inverted(0, 2, "FREQ:");
|
||||
lcd.print(0, 2, true, "FREQ:");
|
||||
lcd.print_freq(39, 2, self.channel.freq);
|
||||
self.draw_enabled(lcd, false);
|
||||
match self.channel.pll {
|
||||
PLL::A => lcd.print(59, 4, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, "PLL_B"),
|
||||
PLL::A => lcd.print(59, 4, false, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, false, "PLL_B"),
|
||||
}
|
||||
lcd.print(36, 6, "BACK");
|
||||
lcd.print(36, 6, false, "BACK");
|
||||
}
|
||||
Selection::FrequencyDigit(digit) | Selection::Digit(digit) => {
|
||||
lcd.print(0, 2, "FREQ:");
|
||||
lcd.print(0, 2, false, "FREQ:");
|
||||
lcd.print_freq_digit(39, 2, self.channel.freq, *digit);
|
||||
self.draw_enabled(lcd, false);
|
||||
match self.channel.pll {
|
||||
PLL::A => lcd.print(59, 4, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, "PLL_B"),
|
||||
PLL::A => lcd.print(59, 4, false, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, false, "PLL_B"),
|
||||
}
|
||||
lcd.print(36, 6, "BACK");
|
||||
lcd.print(36, 6, false, "BACK");
|
||||
}
|
||||
Selection::Enabled => {
|
||||
lcd.print(0, 2, "FREQ:");
|
||||
lcd.print(0, 2, false, "FREQ:");
|
||||
lcd.print_freq(39, 2, self.channel.freq);
|
||||
self.draw_enabled(lcd, true);
|
||||
match self.channel.pll {
|
||||
PLL::A => lcd.print(59, 4, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, "PLL_B"),
|
||||
PLL::A => lcd.print(59, 4, false, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, false, "PLL_B"),
|
||||
}
|
||||
lcd.print(36, 6, "BACK");
|
||||
lcd.print(36, 6, false, "BACK");
|
||||
}
|
||||
Selection::Pll => {
|
||||
lcd.print(0, 2, "FREQ:");
|
||||
lcd.print(0, 2, false, "FREQ:");
|
||||
lcd.print_freq(39, 2, self.channel.freq);
|
||||
self.draw_enabled(lcd, false);
|
||||
match self.channel.pll {
|
||||
PLL::A => lcd.print_inverted(59, 4, "PLL_A"),
|
||||
PLL::B => lcd.print_inverted(59, 4, "PLL_B"),
|
||||
PLL::A => lcd.print(59, 4, true, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, true, "PLL_B"),
|
||||
}
|
||||
lcd.print(36, 6, "BACK");
|
||||
lcd.print(36, 6, false, "BACK");
|
||||
}
|
||||
Selection::Back => {
|
||||
lcd.print(0, 2, "FREQ:");
|
||||
lcd.print(0, 2, false, "FREQ:");
|
||||
lcd.print_freq(39, 2, self.channel.freq);
|
||||
match self.channel.enabled {
|
||||
false => lcd.print(13, 4, "OFF"),
|
||||
true => lcd.print(16, 4, "ON"),
|
||||
false => lcd.print(13, 4, false, "OFF"),
|
||||
true => lcd.print(16, 4, false, "ON"),
|
||||
}
|
||||
match self.channel.pll {
|
||||
PLL::A => lcd.print(59, 4, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, "PLL_B"),
|
||||
PLL::A => lcd.print(59, 4, false, "PLL_A"),
|
||||
PLL::B => lcd.print(59, 4, false, "PLL_B"),
|
||||
}
|
||||
lcd.print_inverted(36, 6, "BACK");
|
||||
lcd.print(36, 6, true, "BACK");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,40 +53,40 @@ impl Home {
|
|||
pub fn draw(&self, lcd: &mut Lcd, channels: [ClockChannel; 3]) {
|
||||
match &self.active {
|
||||
Selection::Ch1 => {
|
||||
lcd.print_inverted(0, 0, "CH1");
|
||||
lcd.print(0, 0, true, "CH1");
|
||||
channels[0].print(lcd, 0);
|
||||
lcd.print(0, 2, "CH2");
|
||||
lcd.print(0, 2, false, "CH2");
|
||||
channels[1].print(lcd, 2);
|
||||
lcd.print(0, 4, "CH3");
|
||||
lcd.print(0, 4, false, "CH3");
|
||||
channels[2].print(lcd, 4);
|
||||
lcd.print(33, 6, "SETUP");
|
||||
lcd.print(33, 6, false, "SETUP");
|
||||
}
|
||||
Selection::Ch2 => {
|
||||
lcd.print(0, 0, "CH1");
|
||||
lcd.print(0, 0, false, "CH1");
|
||||
channels[0].print(lcd, 0);
|
||||
lcd.print_inverted(0, 2, "CH2");
|
||||
lcd.print(0, 2, true, "CH2");
|
||||
channels[1].print(lcd, 2);
|
||||
lcd.print(0, 4, "CH3");
|
||||
lcd.print(0, 4, false, "CH3");
|
||||
channels[2].print(lcd, 4);
|
||||
lcd.print(33, 6, "SETUP");
|
||||
lcd.print(33, 6, false, "SETUP");
|
||||
}
|
||||
Selection::Ch3 => {
|
||||
lcd.print(0, 0, "CH1");
|
||||
lcd.print(0, 0, false, "CH1");
|
||||
channels[0].print(lcd, 0);
|
||||
lcd.print(0, 2, "CH2");
|
||||
lcd.print(0, 2, false, "CH2");
|
||||
channels[1].print(lcd, 2);
|
||||
lcd.print_inverted(0, 4, "CH3");
|
||||
lcd.print(0, 4, true, "CH3");
|
||||
channels[2].print(lcd, 4);
|
||||
lcd.print(33, 6, "SETUP");
|
||||
lcd.print(33, 6, false, "SETUP");
|
||||
}
|
||||
Selection::Setup => {
|
||||
lcd.print(0, 0, "CH1");
|
||||
lcd.print(0, 0, false, "CH1");
|
||||
channels[0].print(lcd, 0);
|
||||
lcd.print(0, 2, "CH2");
|
||||
lcd.print(0, 2, false, "CH2");
|
||||
channels[1].print(lcd, 2);
|
||||
lcd.print(0, 4, "CH3");
|
||||
lcd.print(0, 4, false, "CH3");
|
||||
channels[2].print(lcd, 4);
|
||||
lcd.print_inverted(33, 6, "SETUP");
|
||||
lcd.print(33, 6, true, "SETUP");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,44 +109,44 @@ impl Setup {
|
|||
|
||||
pub fn draw(&self, lcd: &mut Lcd) {
|
||||
lcd.fill_area(0, 0, 33, 2, 0xFF);
|
||||
lcd.print_inverted(33, 0, "SETUP");
|
||||
lcd.print(33, 0, true, "SETUP");
|
||||
lcd.fill_area(69, 0, 33, 2, 0xFF);
|
||||
|
||||
match &self.active {
|
||||
Selection::Contrast => {
|
||||
lcd.print(0, 2, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, self.backlight);
|
||||
lcd.print_inverted(0, 4, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, self.contrast);
|
||||
lcd.print(36, 6, "BACK");
|
||||
lcd.print(0, 2, false, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, false, self.backlight);
|
||||
lcd.print(0, 4, true, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, false, self.contrast);
|
||||
lcd.print(36, 6, false, "BACK");
|
||||
}
|
||||
Selection::ContrastEdit => {
|
||||
lcd.print(0, 2, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, self.backlight);
|
||||
lcd.print(0, 4, "CONTRAST:");
|
||||
lcd.print_u8_inverted(87, 4, 2, self.contrast);
|
||||
lcd.print(36, 6, "BACK");
|
||||
lcd.print(0, 2, false, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, false, self.backlight);
|
||||
lcd.print(0, 4, false, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, true, self.contrast);
|
||||
lcd.print(36, 6, false, "BACK");
|
||||
}
|
||||
Selection::Backlight => {
|
||||
lcd.print_inverted(0, 2, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, self.backlight);
|
||||
lcd.print(0, 4, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, self.contrast);
|
||||
lcd.print(36, 6, "BACK");
|
||||
lcd.print(0, 2, true, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, false, self.backlight);
|
||||
lcd.print(0, 4, false, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, false, self.contrast);
|
||||
lcd.print(36, 6, false, "BACK");
|
||||
}
|
||||
Selection::BacklightEdit => {
|
||||
lcd.print(0, 2, "BACKLIGHT:");
|
||||
lcd.print_u8_inverted(81, 2, 3, self.backlight);
|
||||
lcd.print(0, 4, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, self.contrast);
|
||||
lcd.print(36, 6, "BACK");
|
||||
lcd.print(0, 2, false, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, true, self.backlight);
|
||||
lcd.print(0, 4, false, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, false, self.contrast);
|
||||
lcd.print(36, 6, false, "BACK");
|
||||
}
|
||||
Selection::Back => {
|
||||
lcd.print(0, 2, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, self.backlight);
|
||||
lcd.print(0, 4, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, self.contrast);
|
||||
lcd.print_inverted(36, 6, "BACK");
|
||||
lcd.print(0, 2, false, "BACKLIGHT:");
|
||||
lcd.print_u8(81, 2, 3, false, self.backlight);
|
||||
lcd.print(0, 4, false, "CONTRAST:");
|
||||
lcd.print_u8(87, 4, 2, false, self.contrast);
|
||||
lcd.print(36, 6, true, "BACK");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue