diff --git a/src/main.rs b/src/main.rs index 6664378..2285ca3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,10 @@ #![feature(exclusive_range_pattern)] -use std::{io, sync::{atomic::{AtomicBool, Ordering}, mpsc::{self, Receiver, Sender}, Arc}, thread, time::Duration}; +use std::{io, sync::{atomic::{AtomicBool, Ordering}, mpsc::{self, Receiver, Sender}, Arc, Mutex}, thread, time::{Duration, Instant}}; use serial2::SerialPort; -use wacca::{calc_checksum, SyncBoardParams, TouchBinding}; +use wacca::{calc_checksum, SyncBoardParams, TouchBinding, CommandPacket}; + +use crate::wacca::fix_touch; mod wacca; @@ -11,26 +13,35 @@ fn main() { let game_right = Arc::new(SerialPort::open("/dev/tnt2", 115200).expect("Unable to open serialport")); + let wedge_left = Arc::new(Mutex::new(SerialPort::open("/dev/ttyUSB0", 921600).expect("Unable to open serialport"))); + + let wedge_right = Arc::new(Mutex::new(SerialPort::open("/dev/ttyUSB1", 921600).expect("Unable to open serialport"))); + let bindings = vec![ TouchBinding { game_serial: game_left, + wedge_serial: wedge_left, side: false, }, TouchBinding { game_serial: game_right, + wedge_serial: wedge_right, side: true, } ]; for binding in bindings.into_iter() { println!("loading thread"); + //let we need some params - let params = SyncBoardParams::get(&binding.side); + let params = Arc::new(SyncBoardParams::get(&binding.side)); + //Sync board -> Game writer thread logic let (writer_tx, writer_rx): (Sender>, Receiver>) = mpsc::channel(); let command_tx = writer_tx.clone(); let game_serial_1 = binding.game_serial.clone(); + let wedge_serial_1 = binding.wedge_serial.clone(); thread::spawn(move || { loop { match writer_rx.recv() { @@ -45,10 +56,15 @@ fn main() { let touch_active = Arc::new(AtomicBool::new(false)); //command handler for handshake between game and sync board + let touch_active_1 = touch_active.clone(); let touch_active_2 = touch_active.clone(); let game_serial_2 = binding.game_serial.clone(); + let wedge_serial_1 = &binding.wedge_serial.clone(); + let wedge_serial_2 = &binding.wedge_serial.clone(); + let params_1 = params.clone(); thread::spawn(move || { + let wedge = &binding.wedge_serial.clone(); let mut serialbuffer: Vec = vec![0; 1000]; loop { let data = loop { @@ -58,7 +74,13 @@ fn main() { Err(e) => eprintln!("{:?}", e), } }; - match wacca::handle_data(&data, ¶ms, touch_active_2.clone()) { + let mut wedge = loop { + match wedge.lock() { + Ok(g) => {break g}, + Err(e) => () + } + }; + match wacca::handle_data(&data, ¶ms, touch_active_2.clone(), wedge) { Some(d) => command_tx.send(d).expect("Something has gone wrong!"), None => (), }; @@ -66,24 +88,107 @@ fn main() { }); //Send touch packet - let touch_active_1 = touch_active.clone(); + let wedge: Arc> = wedge_serial_2.clone(); + thread::spawn(move || { loop { for i in 0..127 { if touch_active_1.load(Ordering::Relaxed) { + let now = Instant::now(); + let mut wedge = loop { + match wedge.lock() { + Ok(g) => {break g}, + Err(e) => () + } + }; let mut touchbuffer: Vec = vec![0; 36]; + for x in 1..7 { + //bottleneck under here + let r: usize = 7-x; + let touch = match wacca::issue_command(&wedge, &CommandPacket { out: true, wedge_id: x as u8, command_id: 0xA1, data: Vec::new() }) { + Ok(data) => data, + Err(_) => continue, + }; + if touch.data.len() >= 4 { + touchbuffer[r as usize] = touchbuffer[r as usize] | fix_touch(touch.data[0], params_1.side); + touchbuffer[(r+6) as usize] = touchbuffer[(r+6) as usize] | fix_touch(touch.data[1], params_1.side); + touchbuffer[(r+12) as usize] = touchbuffer[(r+12) as usize] | fix_touch(touch.data[2], params_1.side); + touchbuffer[(r+18) as usize] = touchbuffer[(r+18) as usize] | fix_touch(touch.data[3], params_1.side); + } + } touchbuffer[0] = 129; touchbuffer[34] = i; touchbuffer[35] = 128; touchbuffer[35] = calc_checksum(&touchbuffer); if touchbuffer[34] == 127 {touchbuffer[34] = 0}; let _ = writer_tx.send(touchbuffer); + io::Write::flush(&mut io::stdout()).unwrap(); + thread::sleep(Duration::from_millis(4)); + } else { + thread::sleep(Duration::from_millis(4)); } } - thread::sleep(Duration::from_millis(8)); } }); + + //wedge stuff + //let (wedge_tx, wedge_rx): (Sender>, Receiver>) = mpsc::channel(); //channel pair for the wedge commands (unit board -> sync board) + //let (touch_tx, touch_rx): (Sender, Receiver) = mpsc::channel(); //channel pair for the touch commands (unit boards -> sync board) + +/* //thread for submitting commands to the unit boards + let wedge_serial_1 = binding.wedge_serial.clone(); + thread::spawn(move || { + loop { + match wedge_cmd_rx.recv() { + Ok(data) => { + let _ = SerialPort::write(&wedge_serial_1,&data.serialize()); + }, + Err(e) => {println!("{:?}",e)} + }; + } + }); + + //thread for receiving data from the unit boards + let wedge_serial_2 = binding.wedge_serial.clone(); + thread::spawn(move || { + let mut serialbuffer: Vec = vec![0; 1000]; + loop { + let data = loop { + match SerialPort::read(&wedge_serial_2, serialbuffer.as_mut_slice()) { + Ok(t) => {break serialbuffer[..t].to_vec()}, + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + }; + let packet = match CommandPacket::new(data) { + Ok(d) => Some(d), + Err(e) => {println!("{:?}", e); None} + }; + match packet { + Some(d) => { + match d.command_id { + 0xA0 | 0xA2 | 0x94 | 0xC9 => { + println!("hfddfi"); + let _ = &wedge_cmd_recv_tx.send(d); + } + _ => {} + } + }, + None => {thread::sleep(Duration::from_millis(10))} + } + // match wacca::handle_data(&data, ¶ms, touch_active_2.clone()) { + // Some(d) => command_tx.send(d).expect("Something has gone wrong!"), + // None => (), + // }; + }; + }); */ + + thread::spawn(move || { + println!("hi"); + thread::sleep(Duration::from_millis(100)); + }); } + loop { thread::sleep(Duration::from_secs(1)); } diff --git a/src/wacca.rs b/src/wacca.rs index 749c6b6..f26ee4d 100644 --- a/src/wacca.rs +++ b/src/wacca.rs @@ -1,4 +1,4 @@ -use std::sync::{atomic::{AtomicBool, Ordering}, Arc}; +use std::{io::{self, Read, Write}, str, sync::{atomic::{AtomicBool, Ordering}, mpsc::{Receiver, Sender}, Arc, Mutex}, thread, time::{Duration, Instant}}; use serial2::SerialPort; @@ -24,6 +24,7 @@ impl SyncBoardParams<'static> { pub struct TouchBinding { pub game_serial: Arc, + pub wedge_serial: Arc>, pub side: bool, } @@ -71,15 +72,18 @@ impl CommandPacket { 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 c: u8 = if data[1] == 0xA1 { + // calc_checksum(&[data[0..data.len()-2].to_vec(), vec![0x80]].concat()) + //} else { + let c = calc_checksum(&data[0..data.len()-2].to_vec()); + let checksum: u8 = data[data.len()-2]; if c != checksum { - println!("check"); - return Err("Invalid Checksum"); + if calc_checksum(&[data[0..data.len()-2].to_vec(), vec![0x80]].concat()) != checksum { + println!("check"); + println!("{:X?}",data); + return Err("Invalid Checksum"); + } }; let a: (bool, u8) = match data[0] { 209..215 => (false, data[0]-208), @@ -110,7 +114,8 @@ pub fn calc_checksum(data: &Vec) -> u8 { checksum } -pub fn handle_data(buffer: &Vec, params: &SyncBoardParams, mut scan_active: Arc) -> Option> { +pub fn handle_data(buffer: &Vec, params: &SyncBoardParams, mut scan_active: Arc, mut wedge: std::sync::MutexGuard<'_, SerialPort>) -> Option> { + println!("aaaa {:?}",buffer[0]); match buffer[0] { 0xa0 => { scan_active.store(false, Ordering::Relaxed); @@ -125,19 +130,37 @@ pub fn handle_data(buffer: &Vec, params: &SyncBoardParams, mut scan_active: }, 0xa2 => { scan_active.store(false, Ordering::Relaxed); + for i in 1..7 { + let packet = issue_command(&wedge,&CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new()}); + } return Some(vec![ 162, 63, 29, 0, 0, 0, 0 ]); }, 0x94 => { scan_active.store(false, Ordering::Relaxed); + for i in 1..7 { + let packet = issue_command(&wedge,&CommandPacket { out: true, wedge_id: i, command_id: 0x94, data: Vec::new() }); + } return Some(vec![ 148, 0, 20, 0, 0, 0, 0 ]); }, 0xc9 => { scan_active.store(true, Ordering::Relaxed); + for i in 1..7 { + let packet = issue_command(&wedge,&CommandPacket { out: true, wedge_id: i, command_id: 0x90, data: vec![0x14, 0x07, 0x7F, 0x3F,]}); + } return Some(vec![ 201, 0, 73, 0, 0, 0, 0 ]); }, 0xa8 => { - //let mut versions: Vec = Vec::new(); - let mut versions = vec!["190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string()]; + let mut versions: Vec = Vec::new(); + for i in 1..7 { + let packet = issue_command(&wedge,&CommandPacket { out: true, wedge_id: i, command_id: 0xA0, data: Vec::new() }); + //thread::sleep(Duration::from_secs(1)); + let data = packet.expect("veri bad"); + let version = str::from_utf8(&data.data).expect("Error").to_string(); + versions.push(version[..6].to_string()); + println!("{:?}", data) + + } + //let mut versions = vec!["190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string(), "190523".to_string()]; return Some(UnitBoardVersionPacket { sync_board_version: params.sync_board_version.to_string(), unit_board_version: versions, @@ -163,3 +186,30 @@ pub fn handle_data(buffer: &Vec, params: &SyncBoardParams, mut scan_active: }, } } + +pub(crate) fn issue_command(port: &SerialPort, data: &CommandPacket) -> Result { + let now = Instant::now(); + let _ = port.write(&data.serialize()); + //thread::sleep(Duration::from_secs(1)); + let mut serialbuffer: Vec = vec![0; 32]; + println!("afw {:?}",now.elapsed()); + let data = loop { + //println!("hi"); + match port.read(serialbuffer.as_mut_slice()) { //slow poopy function + Ok(t) => {break serialbuffer[..t].to_vec()}, + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + }; + }; + println!("x {:?}",now.elapsed()); + CommandPacket::new(data) +} + +pub fn fix_touch(byte: u8, side: bool) -> u8 { + let side = side.clone(); + if side { + byte.reverse_bits() >> 3 + } else { + byte & 0x7f + } +} \ No newline at end of file