From d7c689f7d2afb70898491be59cefa69feda49067 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 2 May 2020 11:36:11 +0200 Subject: [PATCH] Add Runtime, Token implementations, Registers --- src/bin/lsambler.rs | 4 +- src/bin/lsvm.rs | 5 + src/ledstrip_controller.rs | 84 +++++++++++ src/lib.rs | 4 +- src/registers.rs | 232 +++++++++++++++++++++++++++++++ src/runtime.rs | 46 ++++++ src/{asm_tokens.rs => tokens.rs} | 136 ++++++++++++++++++ 7 files changed, 508 insertions(+), 3 deletions(-) create mode 100644 src/bin/lsvm.rs create mode 100644 src/ledstrip_controller.rs create mode 100644 src/runtime.rs rename src/{asm_tokens.rs => tokens.rs} (58%) diff --git a/src/bin/lsambler.rs b/src/bin/lsambler.rs index 8d8c74c..cb81417 100644 --- a/src/bin/lsambler.rs +++ b/src/bin/lsambler.rs @@ -1,9 +1,9 @@ -use ledstrip_vm::asm_tokens::{ +use ledstrip_vm::registers::get_register_by_name; +use ledstrip_vm::tokens::{ AddToken, ClearToken, CmdToken, CopyToken, DivToken, ExitToken, GotoToken, JeToken, JgToken, JlToken, LabelToken, LoadToken, LshToken, ModToken, MulToken, PauseToken, RshToken, SetToken, SubToken, Token, WriteToken, }; -use ledstrip_vm::registers::get_register_by_name; use std::fs::{read_to_string, File}; use std::io; use std::io::{BufWriter, Write}; diff --git a/src/bin/lsvm.rs b/src/bin/lsvm.rs new file mode 100644 index 0000000..b6faf34 --- /dev/null +++ b/src/bin/lsvm.rs @@ -0,0 +1,5 @@ +use std::io; + +fn main() -> io::Result<()> { + Ok(()) +} diff --git a/src/ledstrip_controller.rs b/src/ledstrip_controller.rs new file mode 100644 index 0000000..c979e03 --- /dev/null +++ b/src/ledstrip_controller.rs @@ -0,0 +1,84 @@ +use std::io; +use std::io::Write; +use std::net::TcpStream; + +const STATE_COMMAND_PREFIX: u8 = 0x71; +const PROGRAM_COMMAND_PREFIX: u8 = 0x61; + +pub enum StateStripCommand { + On = 0x23, + Off = 0x24, +} + +pub enum ProgramStripCommand { + SevenCrossFade = 0x25, + RedGradual = 0x26, + GreenGradual = 0x27, + BlueGradual = 0x28, + WhiteGradual = 0x2c, + RedGreenCross = 0x2d, + RedBlueCross = 0x2e, + GreenBlueCross = 0x2f, + SevenStrobe = 0x30, + RedStrobe = 0x31, + GreenStrobe = 0x32, + BlueStrobe = 0x33, + WhiteStrobe = 0x37, + SevenJumping = 0x38, +} + +pub struct LedStripController { + stream: TcpStream, + pub r: u8, + pub g: u8, + pub b: u8, +} + +impl LedStripController { + pub fn new(ip: &str, port: usize) -> io::Result { + let stream = TcpStream::connect(format!("{}:{}", ip, port))?; + + Ok(Self { + stream, + r: 0, + g: 0, + b: 0, + }) + } + + /// Send an rgb color to the led strip + pub fn send_rgb_color(&mut self, r: u8, g: u8, b: u8) -> io::Result<()> { + self.r = r; + self.g = g; + self.b = b; + let message = create_message(&[0x31, r, g, b, 0xf0]); + self.stream.write(&message)?; + + Ok(()) + } + + /// Sets the state of the strip to either on or off + pub fn set_state(&mut self, cmd: StateStripCommand) -> io::Result<()> { + self.stream + .write(&create_message(&[STATE_COMMAND_PREFIX, cmd as u8]))?; + + Ok(()) + } + /// Sends a strip command with a specified speed + /// that is one of 0x01 0x06, 0x10, 0x1c + pub fn send_command(&mut self, cmd: ProgramStripCommand, speed: u8) -> io::Result<()> { + self.stream + .write(&create_message(&[PROGRAM_COMMAND_PREFIX, cmd as u8, speed]))?; + + Ok(()) + } +} + +/// Create a message for the led strip +fn create_message(data: &[u8]) -> Vec { + let mut data = data.clone().to_vec(); + data.append(&mut vec![0x0f]); + data.push(data.iter().sum::() & 255); + + data +} diff --git a/src/lib.rs b/src/lib.rs index fd88f32..8a98f50 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,4 @@ -pub mod asm_tokens; +pub mod ledstrip_controller; pub mod registers; +pub mod runtime; +pub mod tokens; diff --git a/src/registers.rs b/src/registers.rs index 43fd01e..3cae33d 100644 --- a/src/registers.rs +++ b/src/registers.rs @@ -1,3 +1,7 @@ +use crate::ledstrip_controller::{LedStripController, StateStripCommand}; +use std::cell::RefCell; +use std::rc::Rc; + pub const RCS: u8 = 0x01; pub const RCR: u8 = 0x02; pub const RCG: u8 = 0x03; @@ -31,3 +35,231 @@ pub fn get_register_by_name(name: &str) -> Option { None } } + +pub trait Register { + fn set(&mut self, value: T); + fn get(&self) -> T; +} + +pub struct Rcs { + value: bool, + strip_controller: Rc>, +} + +pub struct Rcr { + value: u8, + strip_controller: Rc>, +} + +pub struct Rcg { + value: u8, + strip_controller: Rc>, +} + +pub struct Rcb { + value: u8, + strip_controller: Rc>, +} + +pub struct Rgd { + value: u32, +} + +pub struct Rgp { + value: u32, +} + +pub struct Rgi { + value: u32, +} + +pub struct Rgo { + value: u32, +} + +pub struct Rgl { + value: u32, +} + +impl Rcs { + pub fn new(strip_controller: Rc>) -> Self { + Self { + value: false, + strip_controller, + } + } +} + +impl Rcr { + pub fn new(strip_controller: Rc>) -> Self { + Self { + value: 0, + strip_controller, + } + } +} + +impl Rcg { + pub fn new(strip_controller: Rc>) -> Self { + Self { + value: 0, + strip_controller, + } + } +} + +impl Rcb { + pub fn new(strip_controller: Rc>) -> Self { + Self { + value: 0, + strip_controller, + } + } +} + +impl Rgd { + pub fn new() -> Self { + Self { value: 0 } + } +} + +impl Rgp { + pub fn new() -> Self { + Self { value: 0 } + } +} + +impl Rgi { + pub fn new() -> Self { + Self { value: 0 } + } +} + +impl Rgo { + pub fn new() -> Self { + Self { value: 0 } + } +} + +impl Rgl { + pub fn new() -> Self { + Self { value: 0 } + } +} + +impl Register for Rcs { + fn set(&mut self, value: bool) { + self.value = value; + let state = if value { + StateStripCommand::On + } else { + StateStripCommand::Off + }; + self.strip_controller + .borrow_mut() + .set_state(state) + .expect("failed to set state"); + } + + fn get(&self) -> bool { + self.value + } +} + +impl Register for Rcr { + fn set(&mut self, value: u8) { + self.value = value; + let mut controller = self.strip_controller.borrow_mut(); + let g = controller.g; + let b = controller.b; + controller + .send_rgb_color(self.value, g, b) + .expect("failed send rgb color"); + } + + fn get(&self) -> u8 { + self.value + } +} + +impl Register for Rcg { + fn set(&mut self, value: u8) { + self.value = value; + let mut controller = self.strip_controller.borrow_mut(); + let r = controller.r; + let b = controller.b; + controller + .send_rgb_color(r, self.value, b) + .expect("failed to send rgb color"); + } + + fn get(&self) -> u8 { + self.value + } +} + +impl Register for Rcb { + fn set(&mut self, value: u8) { + self.value = value; + let mut controller = self.strip_controller.borrow_mut(); + let r = controller.r; + let g = controller.g; + controller + .send_rgb_color(r, g, self.value) + .expect("failed to send rgb color") + } + + fn get(&self) -> u8 { + self.value + } +} + +impl Register for Rgd { + fn set(&mut self, value: u32) { + self.value = value + } + + fn get(&self) -> u32 { + self.value + } +} + +impl Register for Rgp { + fn set(&mut self, value: u32) { + self.value = value; + } + + fn get(&self) -> u32 { + self.value + } +} + +impl Register for Rgi { + fn set(&mut self, value: u32) { + self.value = value; + } + + fn get(&self) -> u32 { + self.value + } +} + +impl Register for Rgo { + fn set(&mut self, value: u32) { + self.value = value; + } + + fn get(&self) -> u32 { + self.value + } +} + +impl Register for Rgl { + fn set(&mut self, value: u32) { + self.value = value; + } + + fn get(&self) -> u32 { + self.value + } +} diff --git a/src/runtime.rs b/src/runtime.rs new file mode 100644 index 0000000..d8bd376 --- /dev/null +++ b/src/runtime.rs @@ -0,0 +1,46 @@ +use crate::ledstrip_controller::LedStripController; +use crate::registers::{Rcb, Rcg, Rcr, Rcs, Rgd, Rgi, Rgl, Rgo, Rgp}; +use crate::tokens::Token; +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; + +pub struct Runtime { + pub rcs: Rcs, + pub rcr: Rcr, + pub rcg: Rcg, + pub rcb: Rcb, + pub rgd: Rgd, + pub rgp: Rgp, + pub rgi: Rgi, + pub rgo: Rgo, + pub rgl: Rgl, + pub memory: HashMap, + text: Vec>, + labels: HashMap, + strip_controller: Rc>, +} + +impl Runtime { + pub fn new(ip: &str, port: usize) -> Self { + let controller = LedStripController::new(ip, port) + .expect("failed to establish a connection to the led strip"); + let mut controller = Rc::new(RefCell::new(controller)); + + Self { + rcs: Rcs::new(controller.clone()), + rcr: Rcr::new(controller.clone()), + rcg: Rcg::new(controller.clone()), + rcb: Rcb::new(controller.clone()), + rgd: Rgd::new(), + rgp: Rgp::new(), + rgi: Rgi::new(), + rgo: Rgo::new(), + rgl: Rgl::new(), + memory: HashMap::new(), + text: Vec::new(), + labels: HashMap::new(), + strip_controller: controller, + } + } +} diff --git a/src/asm_tokens.rs b/src/tokens.rs similarity index 58% rename from src/asm_tokens.rs rename to src/tokens.rs index 0aae85d..532b5c1 100644 --- a/src/asm_tokens.rs +++ b/src/tokens.rs @@ -24,6 +24,10 @@ pub trait Token { fn to_bytecode(&self) -> Vec; } +pub trait FromBytecode { + fn from_bytecode(code: &[u8]) -> Self; +} + pub struct NopToken; impl Token for NopToken { @@ -32,6 +36,12 @@ impl Token for NopToken { } } +impl FromBytecode for NopToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct ExitToken { pub register: u8, } @@ -42,6 +52,12 @@ impl Token for ExitToken { } } +impl FromBytecode for ExitToken { + fn from_bytecode(code: &[u8]) -> Self { + Self { register: code[1] } + } +} + pub struct SetToken { pub value: u8, pub register: u8, @@ -53,6 +69,15 @@ impl Token for SetToken { } } +impl FromBytecode for SetToken { + fn from_bytecode(code: &[u8]) -> Self { + Self { + value: code[1], + register: code[2], + } + } +} + pub struct CopyToken { pub register_1: u8, pub register_2: u8, @@ -64,6 +89,15 @@ impl Token for CopyToken { } } +impl FromBytecode for CopyToken { + fn from_bytecode(code: &[u8]) -> Self { + Self { + register_1: code[1], + register_2: code[2], + } + } +} + pub struct LoadToken; impl Token for LoadToken { @@ -72,6 +106,12 @@ impl Token for LoadToken { } } +impl FromBytecode for LoadToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct ClearToken { pub register: u8, } @@ -82,6 +122,12 @@ impl Token for ClearToken { } } +impl FromBytecode for ClearToken { + fn from_bytecode(code: &[u8]) -> Self { + Self { register: code[1] } + } +} + pub struct WriteToken; impl Token for WriteToken { @@ -90,6 +136,12 @@ impl Token for WriteToken { } } +impl FromBytecode for WriteToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct LabelToken; impl Token for LabelToken { @@ -98,6 +150,12 @@ impl Token for LabelToken { } } +impl FromBytecode for LabelToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct GotoToken; impl Token for GotoToken { @@ -106,6 +164,12 @@ impl Token for GotoToken { } } +impl FromBytecode for GotoToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct AddToken; impl Token for AddToken { @@ -114,6 +178,12 @@ impl Token for AddToken { } } +impl FromBytecode for AddToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct SubToken; impl Token for SubToken { @@ -122,6 +192,12 @@ impl Token for SubToken { } } +impl FromBytecode for SubToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct MulToken; impl Token for MulToken { @@ -130,6 +206,12 @@ impl Token for MulToken { } } +impl FromBytecode for MulToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct DivToken; impl Token for DivToken { @@ -138,6 +220,12 @@ impl Token for DivToken { } } +impl FromBytecode for DivToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct ModToken; impl Token for ModToken { @@ -146,6 +234,12 @@ impl Token for ModToken { } } +impl FromBytecode for ModToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct LshToken; impl Token for LshToken { @@ -154,6 +248,12 @@ impl Token for LshToken { } } +impl FromBytecode for LshToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct RshToken; impl Token for RshToken { @@ -162,6 +262,12 @@ impl Token for RshToken { } } +impl FromBytecode for RshToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct JgToken; impl Token for JgToken { @@ -170,6 +276,12 @@ impl Token for JgToken { } } +impl FromBytecode for JgToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct JlToken; impl Token for JlToken { @@ -178,6 +290,12 @@ impl Token for JlToken { } } +impl FromBytecode for JlToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct JeToken; impl Token for JeToken { @@ -186,6 +304,12 @@ impl Token for JeToken { } } +impl FromBytecode for JeToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct PauseToken; impl Token for PauseToken { @@ -194,6 +318,12 @@ impl Token for PauseToken { } } +impl FromBytecode for PauseToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +} + pub struct CmdToken; impl Token for CmdToken { @@ -201,3 +331,9 @@ impl Token for CmdToken { vec![T_CMD] } } + +impl FromBytecode for CmdToken { + fn from_bytecode(_: &[u8]) -> Self { + Self + } +}