263 lines
6.8 KiB
Rust
263 lines
6.8 KiB
Rust
use core::ops::{Index, IndexMut};
|
|
|
|
use arduino_hal::{
|
|
hal::port::{PB0, PB1, PB2, PC0, PC4, PC5, PD5, PD6},
|
|
port::{mode::Output, Pin},
|
|
};
|
|
|
|
use crate::DISPLAY_SEGMENTS;
|
|
|
|
pub struct SegmentPins {
|
|
kd_seg_a: Pin<Output, PD5>,
|
|
kd_seg_b: Pin<Output, PB0>,
|
|
kd_seg_c: Pin<Output, PB2>,
|
|
kd_seg_d: Pin<Output, PC5>,
|
|
kd_seg_e: Pin<Output, PB1>,
|
|
kd_seg_f: Pin<Output, PD6>,
|
|
kd_seg_g: Pin<Output, PC0>,
|
|
kd_seg_dp: Pin<Output, PC4>,
|
|
}
|
|
|
|
impl SegmentPins {
|
|
pub fn new(
|
|
kd_seg_a: Pin<Output, PD5>,
|
|
kd_seg_b: Pin<Output, PB0>,
|
|
kd_seg_c: Pin<Output, PB2>,
|
|
kd_seg_d: Pin<Output, PC5>,
|
|
kd_seg_e: Pin<Output, PB1>,
|
|
kd_seg_f: Pin<Output, PD6>,
|
|
kd_seg_g: Pin<Output, PC0>,
|
|
kd_seg_dp: Pin<Output, PC4>,
|
|
) -> SegmentPins {
|
|
let mut out = SegmentPins {
|
|
kd_seg_a,
|
|
kd_seg_b,
|
|
kd_seg_c,
|
|
kd_seg_d,
|
|
kd_seg_e,
|
|
kd_seg_f,
|
|
kd_seg_g,
|
|
kd_seg_dp,
|
|
};
|
|
|
|
out.set_off();
|
|
out
|
|
}
|
|
|
|
pub fn set_off(&mut self) {
|
|
self.kd_seg_a.set_high();
|
|
self.kd_seg_b.set_high();
|
|
self.kd_seg_c.set_high();
|
|
self.kd_seg_d.set_high();
|
|
self.kd_seg_e.set_high();
|
|
self.kd_seg_f.set_high();
|
|
self.kd_seg_g.set_high();
|
|
self.kd_seg_dp.set_high();
|
|
}
|
|
|
|
pub fn set_a(&mut self) {
|
|
self.kd_seg_a.set_low();
|
|
}
|
|
pub fn set_b(&mut self) {
|
|
self.kd_seg_b.set_low();
|
|
}
|
|
pub fn set_c(&mut self) {
|
|
self.kd_seg_c.set_low();
|
|
}
|
|
pub fn set_d(&mut self) {
|
|
self.kd_seg_d.set_low();
|
|
}
|
|
pub fn set_e(&mut self) {
|
|
self.kd_seg_e.set_low();
|
|
}
|
|
pub fn set_f(&mut self) {
|
|
self.kd_seg_f.set_low();
|
|
}
|
|
pub fn set_g(&mut self) {
|
|
self.kd_seg_g.set_low();
|
|
}
|
|
pub fn set_dp(&mut self) {
|
|
self.kd_seg_dp.set_low();
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
|
pub enum SegmentState {
|
|
Num(u8, bool),
|
|
Minus,
|
|
Prompt(bool),
|
|
Dot,
|
|
Off,
|
|
}
|
|
|
|
impl SegmentState {
|
|
pub fn apply(&self, seg: &mut SegmentPins) {
|
|
seg.set_off();
|
|
match self {
|
|
SegmentState::Num(no, dp) => {
|
|
match no {
|
|
0 => {
|
|
seg.set_a();
|
|
seg.set_b();
|
|
seg.set_c();
|
|
seg.set_d();
|
|
seg.set_e();
|
|
seg.set_f();
|
|
}
|
|
1 => {
|
|
seg.set_b();
|
|
seg.set_c();
|
|
}
|
|
2 => {
|
|
seg.set_a();
|
|
seg.set_b();
|
|
seg.set_g();
|
|
seg.set_e();
|
|
seg.set_d();
|
|
}
|
|
3 => {
|
|
seg.set_a();
|
|
seg.set_b();
|
|
seg.set_g();
|
|
seg.set_c();
|
|
seg.set_d();
|
|
}
|
|
4 => {
|
|
seg.set_f();
|
|
seg.set_g();
|
|
seg.set_b();
|
|
seg.set_c();
|
|
}
|
|
5 => {
|
|
seg.set_a();
|
|
seg.set_f();
|
|
seg.set_g();
|
|
seg.set_c();
|
|
seg.set_d();
|
|
}
|
|
6 => {
|
|
seg.set_a();
|
|
seg.set_f();
|
|
seg.set_g();
|
|
seg.set_c();
|
|
seg.set_d();
|
|
seg.set_e();
|
|
}
|
|
7 => {
|
|
seg.set_a();
|
|
seg.set_b();
|
|
seg.set_c();
|
|
}
|
|
8 => {
|
|
seg.set_a();
|
|
seg.set_b();
|
|
seg.set_c();
|
|
seg.set_d();
|
|
seg.set_e();
|
|
seg.set_f();
|
|
seg.set_g();
|
|
}
|
|
9 => {
|
|
seg.set_a();
|
|
seg.set_b();
|
|
seg.set_c();
|
|
seg.set_d();
|
|
seg.set_f();
|
|
seg.set_g();
|
|
}
|
|
_ => panic!("SegmentState::Num out of range"),
|
|
}
|
|
if *dp {
|
|
seg.set_dp()
|
|
}
|
|
}
|
|
SegmentState::Minus => seg.set_g(),
|
|
SegmentState::Dot => seg.set_dp(),
|
|
SegmentState::Prompt(dot) => {
|
|
seg.set_d();
|
|
if *dot {
|
|
seg.set_dp()
|
|
}
|
|
}
|
|
SegmentState::Off => (),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct DispalyState([SegmentState; DISPLAY_SEGMENTS]);
|
|
|
|
impl Default for DispalyState {
|
|
fn default() -> DispalyState {
|
|
DispalyState([
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
])
|
|
}
|
|
}
|
|
|
|
impl Index<usize> for DispalyState {
|
|
type Output = SegmentState;
|
|
|
|
fn index(&self, index: usize) -> &Self::Output {
|
|
&self.0[index]
|
|
}
|
|
}
|
|
|
|
impl IndexMut<usize> for DispalyState {
|
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
|
&mut self.0[index]
|
|
}
|
|
}
|
|
|
|
impl DispalyState {
|
|
pub fn iter_segments(&self) -> impl Iterator<Item = &SegmentState> {
|
|
self.0.iter()
|
|
}
|
|
}
|
|
|
|
impl DispalyState {
|
|
fn set(&mut self, seg: [SegmentState; DISPLAY_SEGMENTS]) {
|
|
self.0 = seg;
|
|
}
|
|
|
|
pub fn prompt(&mut self) {
|
|
self.set([
|
|
SegmentState::Prompt(false),
|
|
SegmentState::Prompt(true),
|
|
SegmentState::Prompt(false),
|
|
SegmentState::Prompt(false),
|
|
SegmentState::Prompt(false),
|
|
SegmentState::Prompt(false),
|
|
SegmentState::Prompt(false),
|
|
SegmentState::Prompt(false),
|
|
SegmentState::Prompt(false),
|
|
])
|
|
}
|
|
|
|
pub fn error(&mut self) {
|
|
self.set([
|
|
SegmentState::Off,
|
|
SegmentState::Dot,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
SegmentState::Off,
|
|
])
|
|
}
|
|
}
|
|
|
|
// Show data on segment display
|
|
pub trait Show {
|
|
fn show(&self, display: &mut DispalyState);
|
|
}
|