From 80086dca662a30fbda3c25bf4e9d5609c26bd4c1 Mon Sep 17 00:00:00 2001 From: BlackDragon-B Date: Sun, 25 Feb 2024 20:11:31 +0100 Subject: [PATCH] first commit --- .gitignore | 14 +++++ Cargo.toml | 7 +++ src/3main.rs | 18 ++++++ src/main.rs | 46 +++++++++++++++ src/test.rs | 4 ++ src/wacca.rs | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 250 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/3main.rs create mode 100644 src/main.rs create mode 100644 src/test.rs create mode 100644 src/wacca.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1d364a --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdbwa \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..011711d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "Wabri" +version = "0.1.0" +edition = "2021" + +[dependencies] +serialport = "4.3.0" diff --git a/src/3main.rs b/src/3main.rs new file mode 100644 index 0000000..6e8edfc --- /dev/null +++ b/src/3main.rs @@ -0,0 +1,18 @@ +#![feature(exclusive_range_pattern)] + +use crate::wacca::CommandPacket; + +mod wacca; + +fn main() { + let packet = CommandPacket { + out: true, + wedge_id: 6, + command_id: 0x90, + data: vec![0x14, 0x07, 0x7F, 0x3F, 0x44], + }; + let b = packet.serialize(); + println!("{:X?}",b); + let test: CommandPacket = wacca::CommandPacket::new(wacca::CommandPacket::new(vec![0xD1, 0xA8, 0x31, 0x39, 0x30, 0x35, 0x31, 0x34, 0x30, 0x37, 0x33, 0x34, 0x30, 0x41, 0xF0]).unwrap().serialize()).unwrap(); + println!("{:?}",test); +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b1a0f15 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,46 @@ +#![feature(exclusive_range_pattern)] + +use std::io::{self, Write}; +use std::time::Duration; + +use wacca::TouchLink; + +pub mod wacca; + +fn main() { + let mut gleft = serialport::new("COM5", 115_200) + .timeout(Duration::from_millis(10)) + .open() + .expect("Failed to open serial port"); + + let mut gright = serialport::new("COM6", 115_200) + .timeout(Duration::from_millis(10)) + .open() + .expect("Failed to open serial port"); + let mut serial_buf: Vec = vec![0; 1000]; + + let mut left = TouchLink { + scan_active: false, + port: &mut gleft, + sync_board_version: "190523", + buffer: vec![0; 1000], + syncboardparams: wacca::SyncBoardParams::get(), + side: true, + touchbuffer: vec![0; 36], + }; + + let mut right = TouchLink { + scan_active: false, + port: &mut gright, + sync_board_version: "190523", + buffer: vec![0; 1000], + syncboardparams: wacca::SyncBoardParams::get(), + side: false, + touchbuffer: vec![0; 36], + }; + + loop { + left.poll(); + right.poll(); + } +} diff --git a/src/test.rs b/src/test.rs new file mode 100644 index 0000000..95f9fb2 --- /dev/null +++ b/src/test.rs @@ -0,0 +1,4 @@ +mod wacca; +fn main() { + println!("ffff") +} \ No newline at end of file diff --git a/src/wacca.rs b/src/wacca.rs new file mode 100644 index 0000000..7826f77 --- /dev/null +++ b/src/wacca.rs @@ -0,0 +1,161 @@ +use std::io::{self, Write}; + +use serialport::SerialPort; + +pub struct UnitBoardVersionPacket<'a> { + pub sync_board_version: &'a str, + pub unit_board_version: Vec<&'a str>, + pub side: bool, +} + +impl UnitBoardVersionPacket<'_> { + pub fn serialize(&self) -> Vec { + let mut s: Vec = vec![0xA8]; + s.append(&mut self.sync_board_version.as_bytes().to_vec()); + if self.side {s.push(0x4C)} else {s.push(0x52)}; + for v in &self.unit_board_version { + s.append(&mut v.as_bytes().to_vec()); + } + //s.push(calc_checksum(&s)); + if self.side {s.push(104)} else {s.push(118)}; + s + } +} +#[derive(Debug)] +pub struct CommandPacket { + pub out: bool, + pub wedge_id: u8, + pub command_id: u8, + pub data: Vec +} + +impl CommandPacket { + pub fn serialize(&self) -> Vec { + let dir: u8 = if self.out { 0xE0 } else { 0xD0 }; + let mut packet: Vec = vec![self.wedge_id+dir, self.command_id]; + packet.extend(&self.data); + let tail: Vec = vec![calc_checksum(&packet),240]; + return [packet, tail].concat(); + } + + pub fn new(data: Vec) -> Result { + let checksum: u8 = data[data.len()-2]; + println!("{:X?}",&data[0..data.len()-2]); + println!("{:?}", calc_checksum(&data[0..data.len()-3].to_vec())); + if calc_checksum(&data[0..data.len()-2].to_vec()) != checksum as u8 { + return Err("Invalid Checksum") + }; + let a: (bool, u8) = match data[0] { + 209..215 => (false, data[0]-208), + 225..231 => (true, data[0]-224), + _ => (false,0) + }; + if a.1 == 0 {return Err("Wedge ID out of bounds")} + + return Ok(CommandPacket { + out: a.0, + wedge_id: a.1, + command_id: data[1], + data: data[2..data.len()-2].to_vec() + }) + } +} + +pub struct SyncBoardParams<'a> { + pub param0000: &'a str, + pub param0016: &'a str, + pub param0032: &'a str, +} + +impl SyncBoardParams<'static> { + pub fn get() -> SyncBoardParams<'static> { + SyncBoardParams { + param0000: " 0 0 1 2 3 4 5 15 15 15 15 15 15 11 11 11", + param0016: " 11 11 11 128 103 103 115 138 127 103 105 111 126 113 95 100", + param0032: " 101 115 98 86 76 67 68 48 117 0 82 154 0 6 35 4", + } + } +} +pub fn calc_checksum(data: &Vec) -> u8 { + let mut checksum: u8 = 0; + for byte in data.iter() { + checksum ^= byte; + } + checksum +} + +pub struct TouchLink<'a> { + pub scan_active: bool, + pub port: &'a mut Box, + pub sync_board_version: &'a str, + pub buffer: Vec, + pub syncboardparams: SyncBoardParams<'a>, + pub side: bool, + pub touchbuffer: Vec +} +impl TouchLink<'_> { + pub fn poll(&mut self) { + match self.port.read(self.buffer.as_mut_slice()) { + Ok(t) => self.handle_data(&self.buffer[..t].to_vec()), + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + if self.scan_active { + self.touch() + } + } + pub fn handle_data(&mut self, buffer: &Vec) { + println!("{:X?}", buffer[0]); + match buffer[0] { + 0xa0 => { + self.scan_active = false; + self.port.write(&[vec![buffer[0]], self.sync_board_version.as_bytes().to_vec(), vec![44]].concat()).unwrap(); + }, + 0x77 => {}, + 0x20 => { + self.scan_active = false; + }, + 0xa2 => { + self.scan_active = false; + let _ = self.port.write(&[ 162, 63, 29, 0, 0, 0, 0 ]); + }, + 0x94 => { + self.scan_active = false; + let _ = self.port.write(&[ 148, 0, 20, 0, 0, 0, 0 ]); + }, + 0xc9 => { + self.scan_active = true; + let _ = self.port.write(&[ 201, 0, 73, 0, 0, 0, 0 ]); + }, + 0xa8 => { + let _ = self.port.write(&UnitBoardVersionPacket { + sync_board_version: self.sync_board_version, + unit_board_version: vec!["190514", "190514", "190514", "190514", "190514", "190514"], + side: self.side, + }.serialize()); + }, + 0x72 => { + self.scan_active = false; + let param: &str = match buffer[3] { + 0x30 => {self.syncboardparams.param0000} + 0x31 => {self.syncboardparams.param0016} + 0x33 => {self.syncboardparams.param0032} + _ => {""} + }; + let _ = self.port.write(&[param.as_bytes(), &vec![calc_checksum(¶m.as_bytes().to_vec())]].concat()); + }, + 0x9a => { + self.scan_active = false; + }, + _ => {}, + } + } + pub fn touch(&mut self) { + self.touchbuffer[0] = 129; + self.touchbuffer[34] = self.touchbuffer[34] + 1; + self.touchbuffer[35] = 128; + self.touchbuffer[35] = calc_checksum(&self.touchbuffer); + if self.touchbuffer[34] == 127 {self.touchbuffer[34] = 0}; + let _ = self.port.write(&self.touchbuffer); + } +}