wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
This commit is contained in:
parent
66524a39c2
commit
c018f0157d
2 changed files with 172 additions and 17 deletions
117
src/main.rs
117
src/main.rs
|
@ -1,8 +1,10 @@
|
||||||
#![feature(exclusive_range_pattern)]
|
#![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 serial2::SerialPort;
|
||||||
use wacca::{calc_checksum, SyncBoardParams, TouchBinding};
|
use wacca::{calc_checksum, SyncBoardParams, TouchBinding, CommandPacket};
|
||||||
|
|
||||||
|
use crate::wacca::fix_touch;
|
||||||
|
|
||||||
mod wacca;
|
mod wacca;
|
||||||
|
|
||||||
|
@ -11,26 +13,35 @@ fn main() {
|
||||||
|
|
||||||
let game_right = Arc::new(SerialPort::open("/dev/tnt2", 115200).expect("Unable to open serialport"));
|
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![
|
let bindings = vec![
|
||||||
TouchBinding {
|
TouchBinding {
|
||||||
game_serial: game_left,
|
game_serial: game_left,
|
||||||
|
wedge_serial: wedge_left,
|
||||||
side: false,
|
side: false,
|
||||||
},
|
},
|
||||||
TouchBinding {
|
TouchBinding {
|
||||||
game_serial: game_right,
|
game_serial: game_right,
|
||||||
|
wedge_serial: wedge_right,
|
||||||
side: true,
|
side: true,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
for binding in bindings.into_iter() {
|
for binding in bindings.into_iter() {
|
||||||
println!("loading thread");
|
println!("loading thread");
|
||||||
|
|
||||||
//let we need some params
|
//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
|
//Sync board -> Game writer thread logic
|
||||||
let (writer_tx, writer_rx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = mpsc::channel();
|
let (writer_tx, writer_rx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = mpsc::channel();
|
||||||
let command_tx = writer_tx.clone();
|
let command_tx = writer_tx.clone();
|
||||||
|
|
||||||
let game_serial_1 = binding.game_serial.clone();
|
let game_serial_1 = binding.game_serial.clone();
|
||||||
|
let wedge_serial_1 = binding.wedge_serial.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
match writer_rx.recv() {
|
match writer_rx.recv() {
|
||||||
|
@ -45,10 +56,15 @@ fn main() {
|
||||||
let touch_active = Arc::new(AtomicBool::new(false));
|
let touch_active = Arc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
//command handler for handshake between game and sync board
|
//command handler for handshake between game and sync board
|
||||||
|
let touch_active_1 = touch_active.clone();
|
||||||
let touch_active_2 = touch_active.clone();
|
let touch_active_2 = touch_active.clone();
|
||||||
let game_serial_2 = binding.game_serial.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 || {
|
thread::spawn(move || {
|
||||||
|
let wedge = &binding.wedge_serial.clone();
|
||||||
let mut serialbuffer: Vec<u8> = vec![0; 1000];
|
let mut serialbuffer: Vec<u8> = vec![0; 1000];
|
||||||
loop {
|
loop {
|
||||||
let data = loop {
|
let data = loop {
|
||||||
|
@ -58,7 +74,13 @@ fn main() {
|
||||||
Err(e) => eprintln!("{:?}", e),
|
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!"),
|
Some(d) => command_tx.send(d).expect("Something has gone wrong!"),
|
||||||
None => (),
|
None => (),
|
||||||
};
|
};
|
||||||
|
@ -66,24 +88,107 @@ fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
//Send touch packet
|
//Send touch packet
|
||||||
let touch_active_1 = touch_active.clone();
|
let wedge: Arc<Mutex<SerialPort>> = wedge_serial_2.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
for i in 0..127 {
|
for i in 0..127 {
|
||||||
if touch_active_1.load(Ordering::Relaxed) {
|
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];
|
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[0] = 129;
|
||||||
touchbuffer[34] = i;
|
touchbuffer[34] = i;
|
||||||
touchbuffer[35] = 128;
|
touchbuffer[35] = 128;
|
||||||
touchbuffer[35] = calc_checksum(&touchbuffer);
|
touchbuffer[35] = calc_checksum(&touchbuffer);
|
||||||
if touchbuffer[34] == 127 {touchbuffer[34] = 0};
|
if touchbuffer[34] == 127 {touchbuffer[34] = 0};
|
||||||
let _ = writer_tx.send(touchbuffer);
|
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, ¶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 {
|
loop {
|
||||||
thread::sleep(Duration::from_secs(1));
|
thread::sleep(Duration::from_secs(1));
|
||||||
}
|
}
|
||||||
|
|
72
src/wacca.rs
72
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;
|
use serial2::SerialPort;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ impl SyncBoardParams<'static> {
|
||||||
|
|
||||||
pub struct TouchBinding {
|
pub struct TouchBinding {
|
||||||
pub game_serial: Arc<SerialPort>,
|
pub game_serial: Arc<SerialPort>,
|
||||||
|
pub wedge_serial: Arc<Mutex<SerialPort>>,
|
||||||
pub side: bool,
|
pub side: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,15 +72,18 @@ impl CommandPacket {
|
||||||
if data[data.len()-1] == 0 {
|
if data[data.len()-1] == 0 {
|
||||||
data = data[..data.len()-1].to_vec();
|
data = data[..data.len()-1].to_vec();
|
||||||
}
|
}
|
||||||
let c: u8 = if data[1] == 0xA1 {
|
//let c: u8 = if data[1] == 0xA1 {
|
||||||
calc_checksum(&[data[0..data.len()-2].to_vec(), vec![0x80]].concat())
|
// calc_checksum(&[data[0..data.len()-2].to_vec(), vec![0x80]].concat())
|
||||||
} else {
|
//} else {
|
||||||
calc_checksum(&data[0..data.len()-2].to_vec())
|
let c = calc_checksum(&data[0..data.len()-2].to_vec());
|
||||||
};
|
|
||||||
let checksum: u8 = data[data.len()-2];
|
let checksum: u8 = data[data.len()-2];
|
||||||
if c != checksum {
|
if c != checksum {
|
||||||
println!("check");
|
if calc_checksum(&[data[0..data.len()-2].to_vec(), vec![0x80]].concat()) != checksum {
|
||||||
return Err("Invalid Checksum");
|
println!("check");
|
||||||
|
println!("{:X?}",data);
|
||||||
|
return Err("Invalid Checksum");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let a: (bool, u8) = match data[0] {
|
let a: (bool, u8) = match data[0] {
|
||||||
209..215 => (false, data[0]-208),
|
209..215 => (false, data[0]-208),
|
||||||
|
@ -110,7 +114,8 @@ pub fn calc_checksum(data: &Vec<u8>) -> u8 {
|
||||||
checksum
|
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] {
|
match buffer[0] {
|
||||||
0xa0 => {
|
0xa0 => {
|
||||||
scan_active.store(false, Ordering::Relaxed);
|
scan_active.store(false, Ordering::Relaxed);
|
||||||
|
@ -125,19 +130,37 @@ pub fn handle_data(buffer: &Vec<u8>, params: &SyncBoardParams, mut scan_active:
|
||||||
},
|
},
|
||||||
0xa2 => {
|
0xa2 => {
|
||||||
scan_active.store(false, Ordering::Relaxed);
|
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 ]);
|
return Some(vec![ 162, 63, 29, 0, 0, 0, 0 ]);
|
||||||
},
|
},
|
||||||
0x94 => {
|
0x94 => {
|
||||||
scan_active.store(false, Ordering::Relaxed);
|
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 ]);
|
return Some(vec![ 148, 0, 20, 0, 0, 0, 0 ]);
|
||||||
},
|
},
|
||||||
0xc9 => {
|
0xc9 => {
|
||||||
scan_active.store(true, Ordering::Relaxed);
|
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 ]);
|
return Some(vec![ 201, 0, 73, 0, 0, 0, 0 ]);
|
||||||
},
|
},
|
||||||
0xa8 => {
|
0xa8 => {
|
||||||
//let mut versions: Vec<String> = Vec::new();
|
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()];
|
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 {
|
return Some(UnitBoardVersionPacket {
|
||||||
sync_board_version: params.sync_board_version.to_string(),
|
sync_board_version: params.sync_board_version.to_string(),
|
||||||
unit_board_version: versions,
|
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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue