Add pressure visual modes and breakout game
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
use crate::serial_core::codec::Codec;
|
||||
use crate::serial_core::codecs::tactile_a::TactileACodec;
|
||||
use crate::serial_core::frame::TactileAFrame;
|
||||
use crate::serial_core::utils::elapsed_millis;
|
||||
use crossbeam_channel::{Receiver, Sender, TryRecvError};
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
use std::io::{Read, Write};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
const POLL_INTERVAL_MS: u64 = 10;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct SerialIoStats {
|
||||
pub rx_bytes: u64,
|
||||
pub tx_bytes: u64,
|
||||
}
|
||||
|
||||
/// Runs the serial polling loop on the calling (background) thread.
|
||||
/// Sends decoded pressure matrix data (Vec<i32>) to the output channel.
|
||||
pub fn run_serial_loop(
|
||||
@@ -16,12 +21,20 @@ pub fn run_serial_loop(
|
||||
cols: usize,
|
||||
cancel_rx: &Receiver<()>,
|
||||
sample_tx: &Sender<Vec<i32>>,
|
||||
stats_tx: Option<&Sender<SerialIoStats>>,
|
||||
) {
|
||||
let session_started_at = Instant::now();
|
||||
let mut codec = TactileACodec::new(cols, rows);
|
||||
let req_frame = TactileACodec::build_req_frame(cols, rows);
|
||||
let req_frame = match TactileACodec::build_req_frame(cols, rows) {
|
||||
Ok(frame) => frame,
|
||||
Err(err) => {
|
||||
eprintln!("[serial] request frame build error: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let mut buffer = [0u8; 1024];
|
||||
let mut poll_interval = Duration::from_millis(POLL_INTERVAL_MS);
|
||||
let poll_interval = Duration::from_millis(POLL_INTERVAL_MS);
|
||||
let mut io_stats = SerialIoStats::default();
|
||||
|
||||
loop {
|
||||
// Check cancel
|
||||
@@ -31,7 +44,10 @@ pub fn run_serial_loop(
|
||||
|
||||
// Send poll request
|
||||
if let Ok(req_bytes) = codec.encode(&req_frame) {
|
||||
let _ = port.write_all(&req_bytes);
|
||||
if port.write_all(&req_bytes).is_ok() {
|
||||
io_stats.tx_bytes += req_bytes.len() as u64;
|
||||
publish_stats(stats_tx, io_stats);
|
||||
}
|
||||
}
|
||||
|
||||
// Read response with poll interval
|
||||
@@ -43,6 +59,8 @@ pub fn run_serial_loop(
|
||||
|
||||
match port.read(&mut buffer) {
|
||||
Ok(n) if n > 0 => {
|
||||
io_stats.rx_bytes += n as u64;
|
||||
publish_stats(stats_tx, io_stats);
|
||||
if let Ok(frames) = codec.decode(&buffer[..n], session_started_at) {
|
||||
for frame in frames {
|
||||
if let TactileAFrame::Rep(rep) = frame {
|
||||
@@ -68,6 +86,12 @@ pub fn run_serial_loop(
|
||||
}
|
||||
}
|
||||
|
||||
fn publish_stats(stats_tx: Option<&Sender<SerialIoStats>>, stats: SerialIoStats) {
|
||||
if let Some(tx) = stats_tx {
|
||||
let _ = tx.try_send(stats);
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait abstracting read+write for the serial port
|
||||
pub trait ReadWrite: Send {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize>;
|
||||
|
||||
Reference in New Issue
Block a user