mirror of
https://github.com/4yn/slidershim.git
synced 2025-02-08 15:18:17 +01:00
diva draft
This commit is contained in:
parent
6bc462210f
commit
5865cd9d21
@ -5,41 +5,42 @@ use std::{future::Future, io, time::Duration};
|
||||
|
||||
use tokio::{select, time::sleep};
|
||||
|
||||
// use slidershim::slider_io::worker::{AsyncJob, AsyncWorker};
|
||||
use slider_io::shared::worker::{AsyncHaltableJob, AsyncHaltableWorker};
|
||||
|
||||
// struct CounterJob;
|
||||
struct CounterJob;
|
||||
|
||||
// #[async_trait]
|
||||
// impl AsyncJob for CounterJob {
|
||||
// async fn run<F: Future<Output = ()> + Send>(self, stop_signal: F) {
|
||||
// let job_a = async {
|
||||
// println!("Start job A");
|
||||
// let mut x = 0;
|
||||
// loop {
|
||||
// x += 1;
|
||||
// println!("{}", x);
|
||||
// sleep(Duration::from_millis(100)).await;
|
||||
// }
|
||||
// };
|
||||
// let job_b = async move {
|
||||
// println!("Start job B");
|
||||
// stop_signal.await;
|
||||
// println!("Stop signal hit at job B");
|
||||
// };
|
||||
#[async_trait]
|
||||
impl AsyncHaltableJob for CounterJob {
|
||||
async fn run<F: Future<Output = ()> + Send>(self, stop_signal: F) {
|
||||
let job_a = async {
|
||||
println!("Start job A");
|
||||
let mut x = 0;
|
||||
loop {
|
||||
x += 1;
|
||||
println!("{}", x);
|
||||
sleep(Duration::from_millis(500)).await;
|
||||
}
|
||||
};
|
||||
let job_b = async move {
|
||||
println!("Start job B");
|
||||
stop_signal.await;
|
||||
println!("Stop signal hit at job B");
|
||||
};
|
||||
|
||||
// select! {
|
||||
// _ = job_a => {},
|
||||
// _ = job_b => {},
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
select! {
|
||||
_ = job_a => {},
|
||||
_ = job_b => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
env_logger::Builder::new()
|
||||
.filter_level(log::LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
// let worker = AsyncWorker::new("counter", CounterJob);
|
||||
let _worker = AsyncHaltableWorker::new("counter", CounterJob);
|
||||
let mut input = String::new();
|
||||
let string = io::stdin().read_line(&mut input).unwrap();
|
||||
io::stdin().read_line(&mut input).unwrap();
|
||||
}
|
||||
|
@ -1,19 +1,20 @@
|
||||
extern crate slider_io;
|
||||
|
||||
use std::{io, time::Duration};
|
||||
use std::io;
|
||||
|
||||
use tokio::time::sleep;
|
||||
use slider_io::{
|
||||
device::brokenithm::BrokenithmJob, shared::worker::AsyncHaltableWorker, state::SliderState,
|
||||
};
|
||||
|
||||
// use slidershim::slider_io::{
|
||||
// brokenithm::BrokenithmJob, controller_state::FullState, worker::AsyncWorker,
|
||||
// };
|
||||
|
||||
fn main() {
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
env_logger::Builder::new()
|
||||
.filter_level(log::LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
// let worker = AsyncWorker::new("brokenithm", BrokenithmJob::new(FullState::new()));
|
||||
let state = SliderState::new();
|
||||
|
||||
let _worker = AsyncHaltableWorker::new("brokenithm", BrokenithmJob::new(&state, &false, &false));
|
||||
let mut input = String::new();
|
||||
let string = io::stdin().read_line(&mut input).unwrap();
|
||||
io::stdin().read_line(&mut input).unwrap();
|
||||
}
|
||||
|
27
src-slider_io/src/bin/test_diva.rs
Normal file
27
src-slider_io/src/bin/test_diva.rs
Normal file
@ -0,0 +1,27 @@
|
||||
extern crate slider_io;
|
||||
|
||||
use std::io;
|
||||
|
||||
use slider_io::{
|
||||
device::diva,
|
||||
shared::{utils::LoopTimer, worker::ThreadWorker},
|
||||
state::SliderState,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
env_logger::Builder::new()
|
||||
.filter_level(log::LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
let state = SliderState::new();
|
||||
|
||||
let timer = LoopTimer::new();
|
||||
let _worker = ThreadWorker::new(
|
||||
"d",
|
||||
diva::DivaSliderJob::new(&state, &"COM5".to_string()),
|
||||
timer,
|
||||
);
|
||||
|
||||
let mut input = String::new();
|
||||
io::stdin().read_line(&mut input).unwrap();
|
||||
}
|
@ -7,5 +7,5 @@ fn main() {
|
||||
let res = available_ports();
|
||||
println!("{:?}", res);
|
||||
let mut input = String::new();
|
||||
let string = io::stdin().read_line(&mut input).unwrap();
|
||||
io::stdin().read_line(&mut input).unwrap();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ extern crate slider_io;
|
||||
|
||||
use std::io;
|
||||
|
||||
// use slidershim::slider_io::{Config, Context};
|
||||
use slider_io::config::Config;
|
||||
|
||||
fn main() {
|
||||
env_logger::Builder::new()
|
||||
@ -10,55 +10,64 @@ fn main() {
|
||||
.init();
|
||||
|
||||
// voltex?
|
||||
// let config = Config::from_str(
|
||||
// r#"{
|
||||
// "deviceMode": "yuancon",
|
||||
// "outputMode": "gamepad-voltex",
|
||||
// "keyboardSensitivity": 50,
|
||||
// "ledMode": "reactive-voltex",
|
||||
// "ledSensitivity": 50
|
||||
// }"#,
|
||||
// )
|
||||
// .unwrap();
|
||||
let config = Config::from_str(
|
||||
r#"{
|
||||
"deviceMode": "yuancon",
|
||||
"outputMode": "gamepad-voltex",
|
||||
"outputPolling": "60",
|
||||
"keyboardSensitivity": 50,
|
||||
"ledMode": "reactive-voltex",
|
||||
"ledSensitivity": 50
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
println!("{:?}", config);
|
||||
|
||||
// serial?
|
||||
// let config = Config::from_str(
|
||||
// r#"{
|
||||
// "deviceMode": "yuancon",
|
||||
// "outputMode": "kb-32-tasoller",
|
||||
// "keyboardSensitivity": 50,
|
||||
// "ledMode": "serial",
|
||||
// "ledSerialPort": "COM5"
|
||||
// }"#,
|
||||
// )
|
||||
// .unwrap();
|
||||
let config = Config::from_str(
|
||||
r#"{
|
||||
"deviceMode": "yuancon",
|
||||
"outputMode": "kb-32-tasoller",
|
||||
"outputPolling": "60",
|
||||
"keyboardSensitivity": 50,
|
||||
"ledMode": "serial",
|
||||
"ledSerialPort": "COM5"
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
println!("{:?}", config);
|
||||
|
||||
// basic
|
||||
// let config = Config::from_str(
|
||||
// r#"{
|
||||
// "deviceMode": "yuancon",
|
||||
// "outputMode": "kb-32-tasoller",
|
||||
// "keyboardSensitivity": 50,fdwdfp1
|
||||
// "ledMode": "reactive-8",
|
||||
// "ledSensitivity": 50
|
||||
// }"#,
|
||||
// )
|
||||
// .unwrap();
|
||||
let config = Config::from_str(
|
||||
r#"{
|
||||
"deviceMode": "yuancon",
|
||||
"outputMode": "kb-32-tasoller",
|
||||
"keyboardSensitivity": 50,
|
||||
"outputPolling": "60",
|
||||
"ledMode": "reactive-8",
|
||||
"ledSensitivity": 50
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
println!("{:?}", config);
|
||||
|
||||
// tasoller/
|
||||
// let config = Config::from_str(
|
||||
// r#"{
|
||||
// "deviceMode": "tasoller-two",
|
||||
// "outputMode": "kb-32-tasoller",
|
||||
// "keyboardSensitivity": 50,
|
||||
// "ledMode": "reactive-8",
|
||||
// "ledSensitivity": 50
|
||||
// }"#,
|
||||
// )
|
||||
// .unwrap();
|
||||
let config = Config::from_str(
|
||||
r#"{
|
||||
"deviceMode": "tasoller-two",
|
||||
"outputMode": "kb-32-tasoller",
|
||||
"outputPolling": "60",
|
||||
"keyboardSensitivity": 50,
|
||||
"ledMode": "reactive-8",
|
||||
"ledSensitivity": 50
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
println!("{:?}", config);
|
||||
|
||||
// let manager = Context::new(config);
|
||||
|
||||
let mut input = String::new();
|
||||
let string = io::stdin().read_line(&mut input).unwrap();
|
||||
io::stdin().read_line(&mut input).unwrap();
|
||||
}
|
||||
|
@ -1,31 +1,41 @@
|
||||
extern crate slider_io;
|
||||
|
||||
use std::io;
|
||||
use std::{io, thread::sleep, time::Duration};
|
||||
|
||||
// use slidershim::slider_io::worker::{Job, Worker};
|
||||
use slider_io::shared::{
|
||||
utils::LoopTimer,
|
||||
worker::{ThreadJob, ThreadWorker},
|
||||
};
|
||||
|
||||
// struct TestJob {
|
||||
// data: i64,
|
||||
// }
|
||||
struct TestJob {
|
||||
data: i64,
|
||||
}
|
||||
|
||||
// impl Job for TestJob {
|
||||
// fn setup(&mut self) {
|
||||
// self.data = 10;
|
||||
// println!("setup {}", self.data);
|
||||
// }
|
||||
// fn tick(&mut self) {
|
||||
// self.data -= 1;
|
||||
// println!("tick {}", self.data);
|
||||
// }
|
||||
// fn teardown(&mut self) {
|
||||
// self.data = 11;
|
||||
// println!("teardown {}", self.data);
|
||||
// }
|
||||
// }
|
||||
impl ThreadJob for TestJob {
|
||||
fn setup(&mut self) -> bool {
|
||||
self.data = 0;
|
||||
println!("setup {}", self.data);
|
||||
true
|
||||
}
|
||||
fn tick(&mut self) -> bool {
|
||||
self.data += 1;
|
||||
println!("tick {}", self.data);
|
||||
sleep(Duration::from_millis(500));
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestJob {
|
||||
fn drop(&mut self) {
|
||||
self.data = -1;
|
||||
println!("teardown {}", self.data);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// let worker = Worker::new(TestJob { data: 1 });
|
||||
let timer = LoopTimer::new();
|
||||
let _worker = ThreadWorker::new("j", TestJob { data: 1 }, timer);
|
||||
|
||||
let mut input = String::new();
|
||||
let string = io::stdin().read_line(&mut input).unwrap();
|
||||
io::stdin().read_line(&mut input).unwrap();
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ pub struct Context {
|
||||
state: SliderState,
|
||||
config: Config,
|
||||
device_thread_worker: Option<ThreadWorker>,
|
||||
device_async_worker: Option<AsyncWorker>,
|
||||
device_async_haltable_worker: Option<AsyncHaltableWorker>,
|
||||
output_worker: Option<AsyncWorker>,
|
||||
lights_worker: Option<AsyncWorker>,
|
||||
@ -35,12 +36,14 @@ impl Context {
|
||||
let state = SliderState::new();
|
||||
let mut timers = vec![];
|
||||
|
||||
let (device_worker, brokenithm_worker) = match &config.device_mode {
|
||||
DeviceMode::None => (None, None),
|
||||
let (device_thread_worker, device_async_worker, device_async_haltable_worker) =
|
||||
match &config.device_mode {
|
||||
DeviceMode::None => (None, None, None),
|
||||
DeviceMode::Brokenithm {
|
||||
ground_only,
|
||||
lights_enabled,
|
||||
} => (
|
||||
None,
|
||||
None,
|
||||
Some(AsyncHaltableWorker::new(
|
||||
"brokenithm",
|
||||
@ -58,6 +61,7 @@ impl Context {
|
||||
))
|
||||
},
|
||||
None,
|
||||
None,
|
||||
),
|
||||
DeviceMode::DivaSlider { port } => (
|
||||
{
|
||||
@ -70,6 +74,7 @@ impl Context {
|
||||
))
|
||||
},
|
||||
None,
|
||||
None,
|
||||
),
|
||||
};
|
||||
let output_worker = match &config.output_mode {
|
||||
@ -100,8 +105,9 @@ impl Context {
|
||||
Self {
|
||||
state,
|
||||
config,
|
||||
device_thread_worker: device_worker,
|
||||
device_async_haltable_worker: brokenithm_worker,
|
||||
device_thread_worker,
|
||||
device_async_worker,
|
||||
device_async_haltable_worker,
|
||||
output_worker,
|
||||
lights_worker,
|
||||
timers,
|
||||
|
@ -1,8 +1,17 @@
|
||||
use log::{error, info};
|
||||
use serialport::SerialPort;
|
||||
use std::{collections::VecDeque, num::Wrapping, thread::sleep, time::Duration};
|
||||
use serialport::{COMPort, SerialPort};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
io::{Read, Write},
|
||||
num::Wrapping,
|
||||
thread::sleep,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::{shared::worker::ThreadJob, state::SliderState};
|
||||
use crate::{
|
||||
shared::{serial::ReadWriteTimeout, worker::ThreadJob},
|
||||
state::SliderState,
|
||||
};
|
||||
|
||||
struct DivaPacket {
|
||||
command: u8,
|
||||
@ -98,15 +107,20 @@ impl DivaDeserializer {
|
||||
}
|
||||
|
||||
fn deserialize(&mut self, data: &[u8], out: &mut VecDeque<DivaPacket>) {
|
||||
// println!("Found data");
|
||||
for c in data {
|
||||
match c {
|
||||
0xff => {
|
||||
self.packet = DivaPacket::new();
|
||||
self.packet.checksum = Wrapping(0xff);
|
||||
self.state = DivaDeserializerState::ExpectCommand;
|
||||
self.escape = 0;
|
||||
|
||||
// println!("{} open", c);
|
||||
}
|
||||
0xfd => {
|
||||
self.escape = 1;
|
||||
// println!("esc {}", c);
|
||||
}
|
||||
c => {
|
||||
let c = c + self.escape;
|
||||
@ -117,6 +131,8 @@ impl DivaDeserializer {
|
||||
DivaDeserializerState::ExpectCommand => {
|
||||
self.packet.command = c;
|
||||
self.state = DivaDeserializerState::ExpectLen;
|
||||
|
||||
// println!("cmd {}", c);
|
||||
}
|
||||
DivaDeserializerState::ExpectLen => {
|
||||
self.len = c;
|
||||
@ -125,6 +141,7 @@ impl DivaDeserializer {
|
||||
0 => DivaDeserializerState::ExpectChecksum,
|
||||
_ => DivaDeserializerState::ExpectData,
|
||||
};
|
||||
// println!("len {}", c);
|
||||
}
|
||||
DivaDeserializerState::ExpectData => {
|
||||
self.packet.data.push(c);
|
||||
@ -133,8 +150,11 @@ impl DivaDeserializer {
|
||||
if self.len == 0 {
|
||||
self.state = DivaDeserializerState::ExpectChecksum;
|
||||
}
|
||||
|
||||
// println!("data {}", c);
|
||||
}
|
||||
DivaDeserializerState::ExpectChecksum => {
|
||||
// println!("checksum {} {:?}", c, self.packet.checksum);
|
||||
debug_assert!(self.packet.checksum == Wrapping(0));
|
||||
if self.packet.checksum == Wrapping(0) {
|
||||
out.push_back(DivaPacket::new());
|
||||
@ -163,7 +183,7 @@ pub struct DivaSliderJob {
|
||||
port: String,
|
||||
packets: VecDeque<DivaPacket>,
|
||||
deserializer: DivaDeserializer,
|
||||
serial_port: Option<Box<dyn SerialPort>>,
|
||||
serial_port: Option<COMPort>,
|
||||
bootstrap: DivaSliderBootstrap,
|
||||
}
|
||||
|
||||
@ -187,10 +207,13 @@ impl ThreadJob for DivaSliderJob {
|
||||
self.port.as_str(),
|
||||
115200
|
||||
);
|
||||
match serialport::new(&self.port, 152000).open() {
|
||||
Ok(serial_port_buf) => {
|
||||
match serialport::new(&self.port, 152000).open_native() {
|
||||
Ok(serial_port) => {
|
||||
info!("Serial port opened");
|
||||
self.serial_port = Some(serial_port_buf);
|
||||
serial_port
|
||||
.set_read_write_timeout(Duration::from_millis(3))
|
||||
.ok();
|
||||
self.serial_port = Some(serial_port);
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
@ -208,53 +231,81 @@ impl ThreadJob for DivaSliderJob {
|
||||
let bytes_avail = serial_port.bytes_to_read().unwrap_or(0);
|
||||
if bytes_avail > 0 {
|
||||
let mut read_buf = vec![0 as u8; bytes_avail as usize];
|
||||
serial_port.read_exact(&mut read_buf).ok();
|
||||
serial_port.read(&mut read_buf).ok();
|
||||
self.deserializer.deserialize(&read_buf, &mut self.packets);
|
||||
work = true;
|
||||
}
|
||||
|
||||
match self.bootstrap {
|
||||
DivaSliderBootstrap::Init => {
|
||||
println!("Diva sending init");
|
||||
info!("Diva sending init");
|
||||
let mut reset_packet = DivaPacket::from_bytes(0x10, &[]);
|
||||
serial_port.write(reset_packet.serialize()).ok();
|
||||
println!("Diva sent init");
|
||||
match serial_port.write(reset_packet.serialize()) {
|
||||
Ok(_) => {
|
||||
info!("Diva sent init");
|
||||
|
||||
self.bootstrap = DivaSliderBootstrap::AwaitReset;
|
||||
work = true;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Diva send init error {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for flush
|
||||
sleep(Duration::from_millis(100));
|
||||
}
|
||||
DivaSliderBootstrap::AwaitReset => {
|
||||
while self.packets.len() > 1 {
|
||||
self.packets.pop_front();
|
||||
}
|
||||
if let Some(ack_packet) = self.packets.pop_front() {
|
||||
info!(
|
||||
"Diva slider ack reset {:?} {:?}",
|
||||
"Diva ack reset {:?} {:?}",
|
||||
ack_packet.command, ack_packet.data
|
||||
);
|
||||
|
||||
let mut info_packet = DivaPacket::from_bytes(0xf0, &[]);
|
||||
serial_port.write(info_packet.serialize()).ok();
|
||||
|
||||
match serial_port.write(info_packet.serialize()) {
|
||||
Ok(_) => {
|
||||
info!("Diva sent info");
|
||||
|
||||
self.bootstrap = DivaSliderBootstrap::AwaitInfo;
|
||||
work = true;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Diva send info error {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DivaSliderBootstrap::AwaitInfo => {
|
||||
if let Some(ack_packet) = self.packets.pop_front() {
|
||||
info!(
|
||||
"Diva slider ack info {:?} {:?}",
|
||||
"Diva ack info {:?} {:?}",
|
||||
ack_packet.command, ack_packet.data
|
||||
);
|
||||
|
||||
let mut start_packet = DivaPacket::from_bytes(0x03, &[]);
|
||||
serial_port.write(start_packet.serialize()).ok();
|
||||
|
||||
match serial_port.write(start_packet.serialize()) {
|
||||
Ok(_) => {
|
||||
info!("Diva sent start");
|
||||
|
||||
self.bootstrap = DivaSliderBootstrap::AwaitStart;
|
||||
work = true;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Diva send start error {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DivaSliderBootstrap::AwaitStart => {
|
||||
if let Some(ack_packet) = self.packets.pop_front() {
|
||||
info!(
|
||||
"Diva slider ack start {:?} {:?}",
|
||||
"Diva ack start {:?} {:?}",
|
||||
ack_packet.command, ack_packet.data
|
||||
);
|
||||
|
||||
@ -301,16 +352,15 @@ impl ThreadJob for DivaSliderJob {
|
||||
|
||||
impl Drop for DivaSliderJob {
|
||||
fn drop(&mut self) {
|
||||
println!("Dropping diva");
|
||||
match self.bootstrap {
|
||||
DivaSliderBootstrap::AwaitStart | DivaSliderBootstrap::ReadLoop => {
|
||||
info!("Diva slider sending stop");
|
||||
|
||||
let serial_port = self.serial_port.as_mut().unwrap();
|
||||
let mut stop_packet = DivaPacket::from_bytes(0x04, &[]);
|
||||
serial_port.write(stop_packet.serialize()).ok();
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
info!("Diva serial port closed");
|
||||
// println!("Diva slider dropped");
|
||||
}
|
||||
}
|
||||
|
@ -5,18 +5,18 @@
|
||||
#![feature(div_duration)]
|
||||
#![feature(more_qualified_paths)]
|
||||
|
||||
mod config;
|
||||
mod shared;
|
||||
mod state;
|
||||
pub mod config;
|
||||
pub mod shared;
|
||||
pub mod state;
|
||||
|
||||
mod device;
|
||||
mod lighting;
|
||||
mod output;
|
||||
pub mod device;
|
||||
pub mod lighting;
|
||||
pub mod output;
|
||||
|
||||
mod system;
|
||||
pub mod system;
|
||||
|
||||
mod context;
|
||||
mod manager;
|
||||
pub mod context;
|
||||
pub mod manager;
|
||||
|
||||
pub use config::Config;
|
||||
pub use manager::Manager;
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod serial;
|
||||
pub mod utils;
|
||||
pub mod voltex;
|
||||
pub mod worker;
|
||||
|
31
src-slider_io/src/shared/serial.rs
Normal file
31
src-slider_io/src/shared/serial.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use serialport::COMPort;
|
||||
use std::{os::windows::prelude::AsRawHandle, time::Duration};
|
||||
|
||||
use winapi::{
|
||||
shared::minwindef::DWORD,
|
||||
um::{commapi::SetCommTimeouts, winbase::COMMTIMEOUTS},
|
||||
};
|
||||
|
||||
pub trait ReadWriteTimeout {
|
||||
fn set_read_write_timeout(&self, timeout: Duration) -> Result<(), ()>;
|
||||
}
|
||||
|
||||
impl ReadWriteTimeout for COMPort {
|
||||
fn set_read_write_timeout(&self, timeout: Duration) -> Result<(), ()> {
|
||||
let milliseconds = timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000;
|
||||
|
||||
let mut timeouts = COMMTIMEOUTS {
|
||||
ReadIntervalTimeout: 0,
|
||||
ReadTotalTimeoutMultiplier: 0,
|
||||
ReadTotalTimeoutConstant: milliseconds as DWORD,
|
||||
WriteTotalTimeoutMultiplier: 0,
|
||||
WriteTotalTimeoutConstant: milliseconds as DWORD,
|
||||
};
|
||||
|
||||
if unsafe { SetCommTimeouts(self.as_raw_handle(), &mut timeouts) } == 0 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
4
src-tauri/Cargo.lock
generated
4
src-tauri/Cargo.lock
generated
@ -1628,9 +1628,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.114"
|
||||
version = "0.2.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0005d08a8f7b65fb8073cb697aa0b12b631ed251ce73d862ce50eeb52ce3b50"
|
||||
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
|
||||
|
||||
[[package]]
|
||||
name = "libudev"
|
||||
|
Loading…
x
Reference in New Issue
Block a user