diff --git a/Cargo.toml b/Cargo.toml index 2dcd848..d202831 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] -serialport = "4.3.0" \ No newline at end of file +serialport = "4.3.0" +tokio = { version = "1.36.0", features=["full"] } diff --git a/src/main copy.rs b/src/main copy.rs new file mode 100644 index 0000000..6dcebee --- /dev/null +++ b/src/main copy.rs @@ -0,0 +1,141 @@ +#![feature(exclusive_range_pattern)] + +use std::io::{self, Write}; +use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; +use std::thread; +use wacca::TouchLink; + +pub mod wacca; + +#[tokio::main] +async fn main() { + let mut gleft = serialport::new("/dev/tnt0", 115_200) + .timeout(Duration::from_millis(10)) + .open() + .expect("Failed to open serial port"); + + let mut gright = serialport::new("/dev/tnt2", 115_200) + .timeout(Duration::from_millis(10)) + .open() + .expect("Failed to open serial port"); + + let mut wleft = serialport::new("/dev/ttyUSB0", 921_600) + .timeout(Duration::from_millis(10)) + .open() + .expect("Failed to open serial port"); + + let mut wright = serialport::new("/dev/ttyUSB1", 921_600) + .timeout(Duration::from_millis(10)) + .open() + .expect("Failed to open serial port"); + + let mut left: TouchLink<'_> = TouchLink { + scan_active: false, + port: Arc::new(Mutex::new(gleft)), + sync_board_version: "190523", + buffer: vec![0; 1000], + buffer2: vec![0; 1000], + syncboardparams: wacca::SyncBoardParams::get(), + side: false, + touchbuffer: Arc::new(Mutex::new(vec![0; 36])), + wport: Arc::new(Mutex::new(wleft)), + time: Instant::now(), + pollrate: Duration::from_millis(1), + }; + + let mut right = TouchLink { + scan_active: false, + port: Arc::new(Mutex::new(gright)), + sync_board_version: "190523", + buffer: vec![0; 1000], + buffer2: vec![0; 1000], + syncboardparams: wacca::SyncBoardParams::get(), + side: true, + touchbuffer: Arc::new(Mutex::new(vec![0; 36])), + wport: Arc::new(Mutex::new(wright)), + time: Instant::now(), + pollrate: Duration::from_millis(1), + }; + + let mut lefttiming2: Instant = Instant::now(); + let mut righttiming: Instant = Instant::now(); + let mut righttiming2: Instant = Instant::now(); + let ltouch = &left.touchbuffer; + let ltouch2 = &left.touchbuffer; + let lwport = &left.wport; + let lport = &left.port; + let rtouch = &right.touchbuffer; + let rtouch2 = &right.touchbuffer; + let rwport = &right.wport; + let rport = &right.port; + + tokio::spawn(async move { + let mut timing: Instant = Instant::now(); + let ltoucha = ltouch.clone(); + loop { + if timing.elapsed() >= Duration::from_millis(8) { + timing = Instant::now(); + if left.scan_active { + //wacca::touch_recv(lwport.clone(), ltouch.clone(), false) + } + } + } + }); + + tokio::spawn(async move { + let mut timing: Instant = Instant::now(); + loop { + if timing.elapsed() >= Duration::from_millis(8) { + timing = Instant::now(); + if left.scan_active { + //wacca::touch_recv(lwport.clone(), ltouch.clone(), false) + } + } + } + }); + + + + tokio::spawn(async move { + loop { + if righttiming.elapsed() >= Duration::from_millis(8) { + if left.scan_active { + + } + } + } + }); + + tokio::spawn(async move { + loop { + if righttiming2.elapsed() >= Duration::from_millis(8) { + if right.scan_active { + + } + } + } + }); + +/* if left.scan_active { + if lefttiming.elapsed() >= Duration::from_millis(8) { + lefttiming = Instant::now(); + tokio::spawn(async {wacca::touch_recv(lwport, ltouch, false)}); + tokio::spawn(async {wacca::touch_send(lport, ltouch2)}); + } + } else { + left.poll(); + } + + + if right.scan_active { + if righttiming.elapsed() >= Duration::from_millis(8) { + righttiming = Instant::now(); + tokio::spawn(async {wacca::touch_recv(rwport, rtouch, true)}); + tokio::spawn(async {wacca::touch_send(rport, rtouch2)}); + } + } else { + right.poll(); + */ //} + +} diff --git a/src/main.rs b/src/main.rs index dbcf061..0776fd3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,74 +1,182 @@ #![feature(exclusive_range_pattern)] use std::io::{self, Write}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{mpsc, Arc, Mutex}; use std::time::{Duration, Instant}; use std::thread; -use wacca::TouchLink; +use serialport::SerialPort; +use wacca::{handle_data, SyncBoardParams, TouchLink}; pub mod wacca; -fn main() { - let mut gleft = serialport::new("/dev/tnt0", 115_200) +#[tokio::main] +async fn main() { + + struct touch<'a> { + wedge: Arc>>, + game: Arc>>, + sync_board_params: SyncBoardParams<'a>, + } + let mut gleft = Arc::new(Mutex::new(serialport::new("/dev/tnt0", 115_200) .timeout(Duration::from_millis(10)) .open() - .expect("Failed to open serial port"); + .expect("Failed to open serial port"))); - let mut gright = serialport::new("/dev/tnt2", 115_200) + let mut gright = Arc::new(Mutex::new(serialport::new("/dev/tnt2", 115_200) .timeout(Duration::from_millis(10)) .open() - .expect("Failed to open serial port"); + .expect("Failed to open serial port"))); - let mut wleft = serialport::new("/dev/ttyUSB2", 921_600) + let mut wleft = Arc::new(Mutex::new(serialport::new("/dev/ttyUSB0", 921_600) .timeout(Duration::from_millis(10)) .open() - .expect("Failed to open serial port"); + .expect("Failed to open serial port"))); - let mut wright = serialport::new("/dev/ttyUSB3", 921_600) + let mut wright = Arc::new(Mutex::new(serialport::new("/dev/ttyUSB1", 921_600) .timeout(Duration::from_millis(10)) .open() - .expect("Failed to open serial port"); + .expect("Failed to open serial port"))); + + let touchpairs = vec![touch {wedge: wleft, game: gleft, sync_board_params: SyncBoardParams::get(false)}, touch {wedge: wright.clone(), game: gright, sync_board_params: SyncBoardParams::get(true)}]; + // let ltouch = &left.touchbuffer; + // let ltouch2 = &left.touchbuffer; + // let lwport = &left.wport; + // let lport = &left.port; + for i in touchpairs.into_iter() { + + let gleft = i.game; + let wleft = i.wedge; + let leftparams: SyncBoardParams<'_> = i.sync_board_params; + let lefttouchbuffer = Arc::new(Mutex::new(vec![0; 36])); + let lefttouchactive = Arc::new(AtomicBool::new(false)); + let leftactive1 = lefttouchactive.clone(); + let leftactive2 = lefttouchactive.clone(); + let leftactive3 = lefttouchactive.clone(); + // let rtouch = &right.touchbuffer; + // let rtouch2 = &right.touchbuffer; + // let rwport = &right.wport; + // let rport = &right.port; + let righttouchbuffer = Arc::new(Mutex::new(vec![0; 36])); + let righttouchactive: Arc> = Arc::new(Mutex::new(false)); + + let lefttouchbuffer1: Arc>> = lefttouchbuffer.clone(); + let lport1: Arc>> = gleft.clone(); + let lport2: Arc>> = wleft.clone(); + + let (tx, mut rx) = mpsc::channel(); + + tokio::spawn(async move { + let ltouch = &lefttouchbuffer; + let lport = wleft; + let mut timing: Instant = Instant::now(); + loop { + if timing.elapsed() >= Duration::from_millis(8) { + if leftactive2.load(Ordering::Relaxed) { + let touchbuffer: Arc>> = ltouch.clone(); + let port: Arc>> = lport.clone(); + timing = Instant::now(); + //println!("bib {:?}",); + let _ = tx.send(wacca::touch_recv(port, leftparams.side)); + } + + } else {thread::sleep(Duration::from_millis(1))} + } + }); + tokio::spawn(async move { + let ltouch = &lefttouchbuffer1; + let lport = gleft; + let mut touchbuffer: Vec = vec![0; 36]; + let mut timing: Instant = Instant::now(); + loop { + if timing.elapsed() >= Duration::from_millis(8) { + if leftactive1.load(Ordering::Relaxed) { + let port: Arc>> = lport.clone(); + timing = Instant::now(); + match rx.try_recv() { + Ok(d) => { + for b in 0..d.len() { + touchbuffer[b+1] = d[b]; + } + }, + Err(err) => {}, + }; + wacca::touch_send(port, &mut touchbuffer); + } + } else {thread::sleep(Duration::from_millis(1))} + } + }); - thread::spawn(move || { - let mut left = TouchLink { - scan_active: false, - port: &mut gleft, - sync_board_version: "190523", - buffer: vec![0; 1000], - buffer2: vec![0; 1000], - syncboardparams: wacca::SyncBoardParams::get(), - side: false, - touchbuffer: vec![0; 36], - wport: &mut wleft, - time: Instant::now(), - pollrate: Duration::from_millis(1), - }; - loop { - left.poll(); - } - }); - thread::spawn(move || { - let mut right = TouchLink { - scan_active: false, - port: &mut gright, - sync_board_version: "190523", - buffer: vec![0; 1000], - buffer2: vec![0; 1000], - syncboardparams: wacca::SyncBoardParams::get(), - side: true, - touchbuffer: vec![0; 36], - wport: &mut wright, - time: Instant::now(), - pollrate: Duration::from_millis(1), - }; + tokio::spawn(async move { + let port1 = &lport1; + let port2 = &lport2; + let leftactive3 = &lefttouchactive; + let mut serialbuffer = vec![0; 1000]; + let mut timing: Instant = Instant::now(); - loop { - right.poll() - } - }); + loop { + if timing.elapsed() >= Duration::from_millis(100) { + if !leftactive3.load(Ordering::Relaxed) { + timing = Instant::now(); + let binding1 = port1.clone(); + let mut port = binding1.lock().unwrap(); + let binding2 = port2.clone(); + let mut port2 = binding2.lock().unwrap(); + let mut leftactive3 = leftactive3.clone(); + + match port.read(serialbuffer.as_mut_slice()) { + Ok(t) => handle_data(&serialbuffer[..t].to_vec(), port, port2, &leftparams, leftactive3), + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + } + } else {thread::sleep(Duration::from_millis(100))}; + } + + + }); + } loop { - + let mut timing: Instant = Instant::now(); + if timing.elapsed() >= Duration::from_millis(8) { + timing = Instant::now(); + // let mut serialbuffer = vec![0; 1000]; + // let mut wright= loop { + // match rport1.lock() { + // Ok(g) => {break g}, + // Err(e) => () + // } + // }; + // let mut gright = rport2.lock().expect("hi"); + // match gright.read(serialbuffer.as_mut_slice()) { + // Ok(t) => { println!("hi"); handle_data(&serialbuffer[..t].to_vec(), gright, wright, &rightparams, righttouchactive2.lock().unwrap()) }, + // Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + // Err(e) => eprintln!("{:?}", e), + // } + } else {thread::sleep(Duration::from_millis(8))} + } +/* if left.scan_active { + if lefttiming.elapsed() >= Duration::from_millis(8) { + lefttiming = Instant::now(); + tokio::spawn(async {wacca::touch_recv(lwport, ltouch, false)}); + tokio::spawn(async {wacca::touch_send(lport, ltouch2)}); + } + } else { + left.poll(); } + + + if right.scan_active { + if righttiming.elapsed() >= Duration::from_millis(8) { + righttiming = Instant::now(); + tokio::spawn(async {wacca::touch_recv(rwport, rtouch, true)}); + tokio::spawn(async {wacca::touch_send(rport, rtouch2)}); + } + } else { + right.poll(); + */ //} + } diff --git a/src/wacca copy.rs b/src/wacca copy.rs new file mode 100644 index 0000000..80a2710 --- /dev/null +++ b/src/wacca copy.rs @@ -0,0 +1,322 @@ +use std::{io::{self, Write}, marker::StructuralEq, process::Command, str, sync::{Arc, Mutex, MutexGuard}, time::{Duration, Instant}}; + +use serialport::SerialPort; + +fn fix_touch(byte: u8, side: bool) -> u8 { + if side { + println!(byte); + println!(byte.reverse_bits() >> 2); + byte.reverse_bits() >> 2 + } else { + byte & 0x7f + } +} + +pub struct UnitBoardVersionPacket { + pub sync_board_version: String, + pub unit_board_version: Vec, + 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.as_slice(),vec![0x80].as_slice()].concat())); + //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(mut data: Vec) -> Result { //TODO: Rewrite this parser to be more lenient with incoming data (trailing zero's etc) + if data.len() < 4 { + return Err("Invalid Size") + } + if data[data.len()-1] == 0 { + data = data[..data.len()-1].to_vec(); + } + let c: u8 = if data[1] == 0xA1 { + calc_checksum(&[data[0..data.len()-2].to_vec(), vec![0x80]].concat()) + } else { + calc_checksum(&data[0..data.len()-2].to_vec()) + }; + let checksum: u8 = data[data.len()-2]; + if c != checksum { + println!("aaa"); + 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")} + + let datalen: usize = if data.len() > 4 { + data.len()-3 + } else { + 2 + }; + return Ok(CommandPacket { + out: a.0, + wedge_id: a.1, + command_id: data[1], + data: data[2..datalen].to_vec() + }) + } +} + +pub struct SyncBoardParams<'a> { + pub param0000: &'a str, + pub param0016: &'a str, + pub param0032: &'a str, + pub sync_board_version: &'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", + sync_board_version: "190523", + } + } +} +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: Arc>>, + pub sync_board_version: &'a str, + pub buffer: Vec, + pub buffer2: Vec, + pub syncboardparams: SyncBoardParams<'a>, + pub side: bool, + pub touchbuffer: Arc>>, + pub wport: Arc>>, + pub time: Instant, + pub pollrate: Duration, + +} +impl TouchLink<'_> { +/* pub fn poll(&mut self) { + let binding = self.port.clone(); + let mut port: std::sync::MutexGuard<'_, Box> = binding.lock().expect("aaa"); + match port.read(self.buffer.as_mut_slice()) { + Ok(t) => self.handle_data(&self.buffer[..t].to_vec(), port), + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + } */ + pub fn handle_data(&mut self, buffer: &Vec, mut port: MutexGuard<'_, Box>, mut portw: MutexGuard<'_, Box>) { + match buffer[0] { + 0xa0 => { + self.scan_active = false; + 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 _ = port.write(&[ 162, 63, 29, 0, 0, 0, 0 ]); + for i in 1..7 { + let packet: Result = issue_command( ,CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new() }); + } + }, + 0x94 => { + self.scan_active = false; + for i in 1..7 { + let packet: Result = issue_command( ,CommandPacket { out: true, wedge_id: i, command_id: 0x94, data: Vec::new() }); + } + let _ = port.write(&[ 148, 0, 20, 0, 0, 0, 0 ]); + }, + 0xc9 => { + for i in 1..7 { + let packet: Result = issue_command( ,CommandPacket { out: true, wedge_id: i, command_id: 0x90, data: vec![0x14, 0x07, 0x7F, 0x3F,] }); + } + self.scan_active = true; + let _ = port.write(&[ 201, 0, 73, 0, 0, 0, 0 ]); + }, + 0xa8 => { + let mut versions: Vec = Vec::new(); + for i in 1..7 { + let packet = issue_command( ,CommandPacket { out: true, wedge_id: i, command_id: 0xA8, data: Vec::new() }); + let data = packet.unwrap().data.to_owned(); + let version = str::from_utf8(&data).expect("Error").to_string(); + versions.push(version[..6].to_string()); + } + let _ = port.write(&UnitBoardVersionPacket { + sync_board_version: self.sync_board_version.to_string(), + unit_board_version: versions, + 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 _ = port.write(&[param.as_bytes(), &vec![calc_checksum(¶m.as_bytes().to_vec())]].concat()); + }, + 0x9a => { + self.scan_active = false; + }, + _ => {}, + } + } + pub fn issue_command(&mut self, command: CommandPacket) -> Result{ + let binding = self.wport.clone(); + let mut wport = binding.lock().expect("yes"); + let _ = wport.write(&command.serialize()); + let data = loop { + match wport.read(self.buffer2.as_mut_slice()) { + Ok(t) => {break self.buffer2[..t].to_vec()}, + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + }; + CommandPacket::new(data) + } +} + +pub fn handle_data(buffer: &Vec, mut port: std::sync::MutexGuard<'_, Box>, mut portw: std::sync::MutexGuard<'_, Box>, params: &SyncBoardParams, scan_active: MutexGuard<'_, bool>) { + match buffer[0] { + 0xa0 => { + self.scan_active = false; + port.write(&[vec![buffer[0]], params.sync_board_version.as_bytes().to_vec(), vec![44]].concat()).unwrap(); + }, + 0x77 => {}, + 0x20 => { + self.scan_active = false; + }, + 0xa2 => { + self.scan_active = false; + let _ = port.write(&[ 162, 63, 29, 0, 0, 0, 0 ]); + for i in 1..7 { + let packet: Result = issue_command(portw ,CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new() }); + } + }, + 0x94 => { + self.scan_active = false; + for i in 1..7 { + let packet: Result = issue_command(portw ,CommandPacket { out: true, wedge_id: i, command_id: 0x94, data: Vec::new() }); + } + let _ = port.write(&[ 148, 0, 20, 0, 0, 0, 0 ]); + }, + 0xc9 => { + for i in 1..7 { + let packet: Result = issue_command(portw ,CommandPacket { out: true, wedge_id: i, command_id: 0x90, data: vec![0x14, 0x07, 0x7F, 0x3F,] }); + } + self.scan_active = true; + let _ = port.write(&[ 201, 0, 73, 0, 0, 0, 0 ]); + }, + 0xa8 => { + let mut versions: Vec = Vec::new(); + for i in 1..7 { + let packet = issue_command(portw ,CommandPacket { out: true, wedge_id: i, command_id: 0xA8, data: Vec::new() }); + let data = packet.unwrap().data.to_owned(); + let version = str::from_utf8(&data).expect("Error").to_string(); + versions.push(version[..6].to_string()); + } + let _ = port.write(&UnitBoardVersionPacket { + sync_board_version: params.sync_board_version.to_string(), + unit_board_version: versions, + side: self.side, + }.serialize()); + }, + 0x72 => { + self.scan_active = false; + let param: &str = match buffer[3] { + 0x30 => {params.param0000} + 0x31 => {params.param0016} + 0x33 => {params.param0032} + _ => {""} + }; + let _ = port.write(&[param.as_bytes(), &vec![calc_checksum(¶m.as_bytes().to_vec())]].concat()); + }, + 0x9a => { + self.scan_active = false; + }, + _ => {}, + } +} + +pub fn touch_recv(port: Arc>>, touchbuffer: Arc>>, side: bool) { + let mut port = port.lock().expect("yes"); + let mut touchbuffer = touchbuffer.lock().expect("yes"); + let mut serialbuffer = vec![0; 1000]; + for i in 1..7 { + let r: usize = 7-i; + let _ = port.write(&CommandPacket { out: true, wedge_id: i as u8, command_id: 0xA1, data: Vec::new() }.serialize()); + let data = loop { + match port.read(serialbuffer.as_mut_slice()) { + Ok(t) => {break serialbuffer[..t].to_vec()}, + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + }; + if let Ok(ret) = CommandPacket::new(data) { + touchbuffer[r as usize] = fix_touch(ret.data[0], side); + touchbuffer[(r+6) as usize] = fix_touch(ret.data[1], side); + touchbuffer[(r+12) as usize] = fix_touch(ret.data[2], side); + touchbuffer[(r+18) as usize] = fix_touch(ret.data[3], side); + } + } + +} + +pub fn issue_command(mut wport: std::sync::MutexGuard<'_, Box>, command: CommandPacket) -> Result{ + let _ = wport.write(&command.serialize()); + let mut serialbuffer = vec![0; 1000]; + let data = loop { + match wport.read(serialbuffer.as_mut_slice()) { + Ok(t) => {break serialbuffer[..t].to_vec()}, + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + }; + CommandPacket::new(data) +} + +pub fn touch_send(port: Arc>>, touchbuffer: Arc>>) { + let mut port = port.lock().unwrap(); + let mut touchbuffer = touchbuffer.lock().unwrap(); + touchbuffer[0] = 129; + touchbuffer[34] = touchbuffer[34] + 1; + touchbuffer[35] = 128; + touchbuffer[35] = calc_checksum(&touchbuffer); + if touchbuffer[34] == 127 {touchbuffer[34] = 0}; + let _ = port.write(&touchbuffer); +} \ No newline at end of file diff --git a/src/wacca.rs b/src/wacca.rs index 7e13e55..0878230 100644 --- a/src/wacca.rs +++ b/src/wacca.rs @@ -1,10 +1,10 @@ -use std::{io::{self, Write}, process::Command, str, time::{Duration, Instant}}; +use std::{io::{self, Write}, str, sync::{atomic::{AtomicBool, Ordering}, mpsc, Arc, Mutex, MutexGuard}, time::{Duration, Instant}}; use serialport::SerialPort; fn fix_touch(byte: u8, side: bool) -> u8 { if side { - byte.reverse_bits() >> 2 + byte.reverse_bits() >> 3 } else { byte & 0x7f } @@ -60,6 +60,7 @@ impl CommandPacket { }; let checksum: u8 = data[data.len()-2]; if c != checksum { + println!("check"); return Err("Invalid Checksum"); }; let a: (bool, u8) = match data[0] { @@ -87,14 +88,18 @@ pub struct SyncBoardParams<'a> { pub param0000: &'a str, pub param0016: &'a str, pub param0032: &'a str, + pub sync_board_version: &'a str, + pub side: bool, } impl SyncBoardParams<'static> { - pub fn get() -> SyncBoardParams<'static> { + pub fn get(side: bool) -> 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", + sync_board_version: "190523", + side, } } } @@ -108,120 +113,127 @@ pub fn calc_checksum(data: &Vec) -> u8 { pub struct TouchLink<'a> { pub scan_active: bool, - pub port: &'a mut Box, + pub port: Arc>>, pub sync_board_version: &'a str, pub buffer: Vec, pub buffer2: Vec, pub syncboardparams: SyncBoardParams<'a>, pub side: bool, - pub touchbuffer: Vec, - pub wport: &'a mut Box, + pub touchbuffer: Arc>>, + pub wport: Arc>>, pub time: Instant, pub pollrate: Duration, } -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) { - 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 ]); - for i in 1..7 { - let packet: Result = self.issue_command(CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new() }); - } - }, - 0x94 => { - self.scan_active = false; - for i in 1..7 { - let packet: Result = self.issue_command(CommandPacket { out: true, wedge_id: i, command_id: 0x94, data: Vec::new() }); - } - let _ = self.port.write(&[ 148, 0, 20, 0, 0, 0, 0 ]); - }, - 0xc9 => { - for i in 1..7 { - let packet: Result = self.issue_command(CommandPacket { out: true, wedge_id: i, command_id: 0x90, data: vec![0x14, 0x07, 0x7F, 0x3F,] }); - } - self.scan_active = true; - let _ = self.port.write(&[ 201, 0, 73, 0, 0, 0, 0 ]); - }, - 0xa8 => { - let mut versions: Vec = Vec::new(); - for i in 1..7 { - let packet = self.issue_command(CommandPacket { out: true, wedge_id: i, command_id: 0xA8, data: Vec::new() }); - let data = packet.unwrap().data.to_owned(); - let version = str::from_utf8(&data).expect("Error").to_string(); - versions.push(version[..6].to_string()); - } - let _ = self.port.write(&UnitBoardVersionPacket { - sync_board_version: self.sync_board_version.to_string(), - unit_board_version: versions, - 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) { - //if self.time.elapsed() >= self.pollrate { - self.time = Instant::now(); + +pub fn handle_data(buffer: &Vec, mut port: std::sync::MutexGuard<'_, Box>, mut portw: std::sync::MutexGuard<'_, Box>, params: &SyncBoardParams, mut scan_active: Arc) { + match buffer[0] { + 0xa0 => { + scan_active.store(false, Ordering::Relaxed); + port.write(&[vec![buffer[0]], params.sync_board_version.as_bytes().to_vec(), vec![44]].concat()).unwrap(); + }, + 0x77 => {}, + 0x20 => { + scan_active.store(false, Ordering::Relaxed); + }, + 0xa2 => { + scan_active.store(false, Ordering::Relaxed); + let _ = port.write(&[ 162, 63, 29, 0, 0, 0, 0 ]); for i in 1..7 { - let r: usize = 7-i; - let packet: Result = self.issue_command(CommandPacket { out: true, wedge_id: i as u8, command_id: 0xA1, data: Vec::new() }); - if let Ok(ret) = packet { - self.touchbuffer[r as usize] = fix_touch(ret.data[0], self.side); - self.touchbuffer[(r+6) as usize] = fix_touch(ret.data[1], self.side); - self.touchbuffer[(r+12) as usize] = fix_touch(ret.data[2], self.side); - self.touchbuffer[(r+18) as usize] = fix_touch(ret.data[3], self.side); - } + let packet: Result = issue_command(&mut portw ,CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new() }); } - 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); - //} + }, + 0x94 => { + scan_active.store(false, Ordering::Relaxed); + for i in 1..7 { + let packet: Result = issue_command(&mut portw ,CommandPacket { out: true, wedge_id: i, command_id: 0x94, data: Vec::new() }); + } + let _ = port.write(&[ 148, 0, 20, 0, 0, 0, 0 ]); + }, + 0xc9 => { + for i in 1..7 { + let packet: Result = issue_command(&mut portw ,CommandPacket { out: true, wedge_id: i, command_id: 0x90, data: vec![0x14, 0x07, 0x7F, 0x3F,] }); + } + scan_active.store(true, Ordering::Relaxed); + let _ = port.write(&[ 201, 0, 73, 0, 0, 0, 0 ]); + }, + 0xa8 => { + let mut versions: Vec = Vec::new(); + for i in 1..7 { + let packet = issue_command(&mut portw ,CommandPacket { out: true, wedge_id: i, command_id: 0xA8, data: Vec::new() }); + let data = packet.unwrap().data.to_owned(); + let version = str::from_utf8(&data).expect("Error").to_string(); + versions.push(version[..6].to_string()); + } + let _ = port.write(&UnitBoardVersionPacket { + sync_board_version: params.sync_board_version.to_string(), + unit_board_version: versions, + side: params.side, + }.serialize()); + }, + 0x72 => { + scan_active.store(false, Ordering::Relaxed); + let param: &str = match buffer[3] { + 0x30 => {params.param0000} + 0x31 => {params.param0016} + 0x33 => {params.param0032} + _ => {""} + }; + let _ = port.write(&[param.as_bytes(), &vec![calc_checksum(¶m.as_bytes().to_vec())]].concat()); + }, + 0x9a => { + scan_active.store(false, Ordering::Relaxed); + }, + _ => {}, } - pub fn issue_command(&mut self, command: CommandPacket) -> Result{ - let _ = self.wport.write(&command.serialize()); +} + +pub fn touch_recv(port: Arc>>, side: bool) -> Vec { + let mut port = port.lock().expect("yes"); + let mut serialbuffer = vec![0; 1000]; + let mut datar = vec!(0; 24); + for i in 1..7 { + let r: usize = 7-i; + let _ = port.write(&CommandPacket { out: true, wedge_id: i as u8, command_id: 0xA1, data: Vec::new() }.serialize()); let data = loop { - match self.wport.read(self.buffer2.as_mut_slice()) { - Ok(t) => {break self.buffer2[..t].to_vec()}, + match port.read(serialbuffer.as_mut_slice()) { + Ok(t) => {break serialbuffer[..t].to_vec()}, Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), Err(e) => eprintln!("{:?}", e), } }; - CommandPacket::new(data) + if let Ok(ret) = CommandPacket::new(data) { + if ret.data.len() >= 4 { + datar[r-1 as usize] = fix_touch(ret.data[0], side); + datar[(r+6)-1 as usize] = fix_touch(ret.data[1], side); + datar[(r+12)-1 as usize] = fix_touch(ret.data[2], side); + datar[(r+18)-1 as usize] = fix_touch(ret.data[3], side); + } + } } + return datar; } + +pub fn issue_command(mut wport: &mut std::sync::MutexGuard<'_, Box>, command: CommandPacket) -> Result{ + let _ = wport.write(&command.serialize()); + let mut serialbuffer = vec![0; 1000]; + let data = loop { + match wport.read(serialbuffer.as_mut_slice()) { + Ok(t) => {break serialbuffer[..t].to_vec()}, + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + }; + CommandPacket::new(data) +} + +pub fn touch_send(port: Arc>>, touchbuffer: &mut Vec) { + let mut port = port.lock().unwrap(); + + touchbuffer[0] = 129; + touchbuffer[34] = touchbuffer[34] + 1; + touchbuffer[35] = 128; + touchbuffer[35] = calc_checksum(&touchbuffer); + if touchbuffer[34] == 127 {touchbuffer[34] = 0}; + let _ = port.write(&touchbuffer); +} \ No newline at end of file