commit 7dcefbebb6c492b4e2db3d8d43d834cc4e5b068a Author: Grigorios Giotas Date: Sun Oct 23 10:21:11 2022 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2ed2e80 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "k8056" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d75ee9f --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,83 @@ +pub mod uart { + use std::convert::TryFrom; + + #[derive(Debug)] + pub struct IndexError(pub u8); + + #[derive(Debug, PartialEq, Eq, Clone, Copy)] + pub struct Idx { + relay_number: u8, + } + + impl Idx { + pub fn new(value: u8) -> Self { + Self::try_from(value).unwrap() + } + + pub fn as_byte(&self) -> u8 { + b'0' + self.relay_number + } + } + + impl TryFrom for Idx { + type Error = IndexError; + fn try_from(x: u8) -> Result { + if x < 1 || x > 9 { + Err(IndexError(x)) + } else { + Ok(Idx { relay_number: x }) + } + } + } + + #[derive(Debug, Clone, PartialEq, Eq)] + pub enum Command { + // Emergency stop all cards, regardless of address + Emergency, // E + // Display address + Display, // D + // Set a relay + Set(Idx), // S + // Clear a relay + Clear(Idx), // C + // Toggle a relay + Toggle(Idx), // T + // Change the current address of a card + Address(Idx), // A + // Force all cards to address 1 (default) + Force, // F + // Send a byte + Byte(u8), // B + } + + impl Command { + pub fn to_bytes(&self, address: u8) -> [u8; 5] { + let (cmd, idx) = self.as_tuple(); + let mut buf = [13, address, cmd, idx, 0]; + buf[4] = buf[0..=3].iter().fold(0, |a, x| a.overflowing_sub(*x).0); + buf + } + + fn as_tuple(&self) -> (u8, u8) { + match *self { + Command::Emergency => (b'E', 0), + Command::Display => (b'D', 0), + Command::Set(x) => (b'S', x.as_byte()), + Command::Clear(x) => (b'C', x.as_byte()), + Command::Toggle(x) => (b'T', x.as_byte()), + Command::Address(x) => (b'A', x.as_byte()), + Command::Force => (b'F', 0), + Command::Byte(x) => (b'B', x), + } + } + } +} + + +#[cfg(test)] +mod tests { + // use super::*; + + // #[test] + +}