wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

This commit is contained in:
Kyan Wanschers 2024-03-16 23:13:31 +01:00
parent 66524a39c2
commit c018f0157d
2 changed files with 172 additions and 17 deletions

View file

@ -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<Vec<u8>>, Receiver<Vec<u8>>) = 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<u8> = vec![0; 1000];
loop {
let data = loop {
@ -58,7 +74,13 @@ fn main() {
Err(e) => eprintln!("{:?}", e),
}
};
match wacca::handle_data(&data, &params, touch_active_2.clone()) {
let mut wedge = loop {
match wedge.lock() {
Ok(g) => {break g},
Err(e) => ()
}
};
match wacca::handle_data(&data, &params, 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<Mutex<SerialPort>> = 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<u8> = 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<Vec<u8>>, Receiver<Vec<u8>>) = mpsc::channel(); //channel pair for the wedge commands (unit board -> sync board)
//let (touch_tx, touch_rx): (Sender<wacca::CommandPacket>, Receiver<wacca::CommandPacket>) = 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<u8> = 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, &params, 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));
}

View file

@ -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<SerialPort>,
pub wedge_serial: Arc<Mutex<SerialPort>>,
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>) -> u8 {
checksum
}
pub fn handle_data(buffer: &Vec<u8>, params: &SyncBoardParams, mut scan_active: Arc<AtomicBool>) -> Option<Vec<u8>> {
pub fn handle_data(buffer: &Vec<u8>, params: &SyncBoardParams, mut scan_active: Arc<AtomicBool>, mut wedge: std::sync::MutexGuard<'_, SerialPort>) -> Option<Vec<u8>> {
println!("aaaa {:?}",buffer[0]);
match buffer[0] {
0xa0 => {
scan_active.store(false, Ordering::Relaxed);
@ -125,19 +130,37 @@ pub fn handle_data(buffer: &Vec<u8>, 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<String> = 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<String> = 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<u8>, params: &SyncBoardParams, mut scan_active:
},
}
}
pub(crate) fn issue_command(port: &SerialPort, data: &CommandPacket) -> Result<CommandPacket, &'static str> {
let now = Instant::now();
let _ = port.write(&data.serialize());
//thread::sleep(Duration::from_secs(1));
let mut serialbuffer: Vec<u8> = 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
}
}