use crate::{
chip::{ChipBuilder, ChipRunner, ChipSet, Pin, PinType},
generate_chip, State,
};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SevenSegmentsDecoder {
pub vcc: Pin,
pub gnd: Pin,
pub bi: Pin,
pub ia: Pin,
pub ib: Pin,
pub ic: Pin,
pub id: Pin,
pub oa: Pin,
pub ob: Pin,
pub oc: Pin,
pub od: Pin,
pub oe: Pin,
pub of: Pin,
pub og: Pin,
}
impl SevenSegmentsDecoder {
pub const VCC: usize = 14;
pub const GND: usize = 7;
pub const BI: usize = 3;
pub const IA: usize = 5;
pub const IB: usize = 1;
pub const IC: usize = 2;
pub const ID: usize = 4;
pub const OA: usize = 11;
pub const OB: usize = 10;
pub const OC: usize = 9;
pub const OD: usize = 8;
pub const OE: usize = 6;
pub const OF: usize = 13;
pub const OG: usize = 12;
}
generate_chip!(
SevenSegmentsDecoder,
vcc: SevenSegmentsDecoder::VCC,
gnd: SevenSegmentsDecoder::GND,
bi: SevenSegmentsDecoder::BI,
ia: SevenSegmentsDecoder::IA,
ib: SevenSegmentsDecoder::IB,
ic: SevenSegmentsDecoder::IC,
id: SevenSegmentsDecoder::ID,
oa: SevenSegmentsDecoder::OA,
ob: SevenSegmentsDecoder::OB,
oc: SevenSegmentsDecoder::OC,
od: SevenSegmentsDecoder::OD,
oe: SevenSegmentsDecoder::OE,
of: SevenSegmentsDecoder::OF,
og: SevenSegmentsDecoder::OG
);
impl ChipBuilder<ChipSet> for SevenSegmentsDecoder {
fn build() -> ChipSet {
ChipSet::SevenSegmentDecoder(SevenSegmentsDecoder {
vcc: Pin::from(PinType::Input),
gnd: Pin::from(PinType::Output),
bi: Pin::from(PinType::Input),
ia: Pin::from(PinType::Input),
ib: Pin::from(PinType::Input),
ic: Pin::from(PinType::Input),
id: Pin::from(PinType::Input),
oa: Pin::from(PinType::Output),
ob: Pin::from(PinType::Output),
oc: Pin::from(PinType::Output),
od: Pin::from(PinType::Output),
oe: Pin::from(PinType::Output),
of: Pin::from(PinType::Output),
og: Pin::from(PinType::Output),
})
}
}
const SEG_DECODER_LUT: [u8; 16] = [
0b1111110, 0b0110000, 0b1101101, 0b1111001, 0b0110011, 0b1011011, 0b1011111, 0b1110000,
0b1111111, 0b1111011, 0b1110111, 0b0011111, 0b0001101, 0b0111101, 0b1001111, 0b1000111,
];
impl ChipRunner for SevenSegmentsDecoder {
fn run(&mut self, _: std::time::Duration) {
if self.vcc.state.as_logic(3.3).into() {
self.gnd.state = State::Low;
let output = if self.bi.state.as_logic(3.3).into() {
let data = Pin::read_threshold(&[&self.ia, &self.ib, &self.ic, &self.id], 3.3);
SEG_DECODER_LUT[data & 0xF]
} else {
0
};
Pin::write(
&mut [
&mut self.og,
&mut self.of,
&mut self.oe,
&mut self.od,
&mut self.oc,
&mut self.ob,
&mut self.oa,
],
output as usize,
);
}
}
}