finga
343b95dc78
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.
192 lines
7.1 KiB
Rust
192 lines
7.1 KiB
Rust
use super::{ClockChannel, Event, Home, Screens};
|
|
use crate::{lcd::Lcd, Input};
|
|
use si5351::{ClockOutput, PLL};
|
|
|
|
enum Selection {
|
|
Frequency,
|
|
FrequencyDigit(u8),
|
|
Digit(u8),
|
|
Enabled,
|
|
Pll,
|
|
Back,
|
|
}
|
|
|
|
pub struct Channel {
|
|
active: Selection,
|
|
channel: ClockChannel,
|
|
}
|
|
|
|
impl Channel {
|
|
pub fn new(channel: ClockChannel) -> Self {
|
|
Self {
|
|
active: Selection::Frequency,
|
|
channel,
|
|
}
|
|
}
|
|
|
|
pub fn input(&mut self, input: &Input) -> Event {
|
|
self.active = match self.active {
|
|
Selection::Frequency => match input {
|
|
Input::Next => Selection::Enabled,
|
|
Input::Previous => Selection::Back,
|
|
Input::Select => Selection::FrequencyDigit(8),
|
|
Input::Back => return Event::Screen(Screens::Home(Home::new())),
|
|
},
|
|
Selection::FrequencyDigit(digit) => match input {
|
|
Input::Next => {
|
|
if digit == u8::MIN {
|
|
Selection::FrequencyDigit(8)
|
|
} else {
|
|
Selection::FrequencyDigit(digit - 1)
|
|
}
|
|
}
|
|
Input::Previous => {
|
|
if digit >= 8 {
|
|
Selection::FrequencyDigit(u8::MIN)
|
|
} else {
|
|
Selection::FrequencyDigit(digit + 1)
|
|
}
|
|
}
|
|
Input::Select => Selection::Digit(digit),
|
|
Input::Back => Selection::Frequency,
|
|
},
|
|
Selection::Digit(digit) => match input {
|
|
Input::Next => {
|
|
let new_freq = self.channel.freq + 10_u32.pow(digit.into());
|
|
if new_freq < 162_000_000 {
|
|
self.channel.freq = new_freq;
|
|
} else {
|
|
self.channel.freq = 162_000_000
|
|
}
|
|
return Event::Channel(self.channel);
|
|
}
|
|
Input::Previous => {
|
|
let difference = 10_u32.pow(digit.into());
|
|
if self.channel.freq > difference {
|
|
let new_freq = self.channel.freq - difference;
|
|
if new_freq > 15_000 {
|
|
self.channel.freq = new_freq;
|
|
} else {
|
|
self.channel.freq = 15_000;
|
|
}
|
|
} else {
|
|
self.channel.freq = 15_000;
|
|
}
|
|
return Event::Channel(self.channel);
|
|
}
|
|
Input::Select => Selection::Frequency,
|
|
Input::Back => Selection::FrequencyDigit(digit),
|
|
},
|
|
Selection::Enabled => match input {
|
|
Input::Next => Selection::Pll,
|
|
Input::Previous => Selection::Frequency,
|
|
Input::Select => {
|
|
self.channel.enabled = !self.channel.enabled;
|
|
return Event::Channel(self.channel);
|
|
}
|
|
Input::Back => return Event::Screen(Screens::Home(Home::new())),
|
|
},
|
|
Selection::Pll => match input {
|
|
Input::Next => Selection::Back,
|
|
Input::Previous => Selection::Enabled,
|
|
Input::Select => {
|
|
self.channel.pll = match self.channel.pll {
|
|
PLL::A => PLL::B,
|
|
PLL::B => PLL::A,
|
|
};
|
|
return Event::Channel(self.channel);
|
|
}
|
|
Input::Back => return Event::Screen(Screens::Home(Home::new())),
|
|
},
|
|
Selection::Back => match input {
|
|
Input::Next => Selection::Frequency,
|
|
Input::Previous => Selection::Pll,
|
|
_ => return Event::Screen(Screens::Home(Home::new())),
|
|
},
|
|
};
|
|
|
|
Event::None
|
|
}
|
|
|
|
fn draw_enabled(&self, lcd: &mut Lcd, inverted: bool) {
|
|
if inverted {
|
|
match self.channel.enabled {
|
|
false => lcd.print(13, 4, true, "OFF"),
|
|
true => lcd.print(16, 4, true, "ON"),
|
|
}
|
|
} else {
|
|
match self.channel.enabled {
|
|
false => lcd.print(13, 4, false, "OFF"),
|
|
true => lcd.print(16, 4, false, "ON"),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn draw(&self, lcd: &mut Lcd) {
|
|
lcd.fill_area(0, 0, 19, 2, 0xFF);
|
|
match self.channel.output {
|
|
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(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, false, "PLL_A"),
|
|
PLL::B => lcd.print(59, 4, false, "PLL_B"),
|
|
}
|
|
lcd.print(36, 6, false, "BACK");
|
|
}
|
|
Selection::FrequencyDigit(digit) | Selection::Digit(digit) => {
|
|
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, false, "PLL_A"),
|
|
PLL::B => lcd.print(59, 4, false, "PLL_B"),
|
|
}
|
|
lcd.print(36, 6, false, "BACK");
|
|
}
|
|
Selection::Enabled => {
|
|
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, false, "PLL_A"),
|
|
PLL::B => lcd.print(59, 4, false, "PLL_B"),
|
|
}
|
|
lcd.print(36, 6, false, "BACK");
|
|
}
|
|
Selection::Pll => {
|
|
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(59, 4, true, "PLL_A"),
|
|
PLL::B => lcd.print(59, 4, true, "PLL_B"),
|
|
}
|
|
lcd.print(36, 6, false, "BACK");
|
|
}
|
|
Selection::Back => {
|
|
lcd.print(0, 2, false, "FREQ:");
|
|
lcd.print_freq(39, 2, self.channel.freq);
|
|
match self.channel.enabled {
|
|
false => lcd.print(13, 4, false, "OFF"),
|
|
true => lcd.print(16, 4, false, "ON"),
|
|
}
|
|
match self.channel.pll {
|
|
PLL::A => lcd.print(59, 4, false, "PLL_A"),
|
|
PLL::B => lcd.print(59, 4, false, "PLL_B"),
|
|
}
|
|
lcd.print(36, 6, true, "BACK");
|
|
}
|
|
}
|
|
}
|
|
}
|