mirror of https://github.com/4yn/slidershim
hook with slider
parent
24d920c5bf
commit
08b1b92f52
|
@ -1,6 +1,9 @@
|
|||
extern crate slider_io;
|
||||
|
||||
use std::io;
|
||||
use std::{
|
||||
io,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use slider_io::{device::diva, shared::worker::ThreadJob, state::SliderState};
|
||||
|
||||
|
@ -10,7 +13,7 @@ fn main() {
|
|||
.init();
|
||||
|
||||
let state = SliderState::new();
|
||||
let mut job = diva::DivaSliderJob::new(&state, &"COM3".to_string(), 0x3f);
|
||||
let mut job = diva::DivaSliderJob::new(&state, &"COM1".to_string(), 0x3f);
|
||||
|
||||
let ok = job.setup();
|
||||
while ok {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use log::{error, info, warn}; // debug
|
||||
use std::collections::VecDeque; //thread::sleep, time::Duration
|
||||
use log::{debug, error, info, warn};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
time::{Duration, Instant},
|
||||
}; // thread::sleep, time::Duration
|
||||
use wwserial::WwSerial;
|
||||
|
||||
use crate::{shared::worker::ThreadJob, state::SliderState};
|
||||
|
@ -197,6 +200,7 @@ pub struct DivaSliderJob {
|
|||
deserializer: DivaDeserializer,
|
||||
serial_port: Option<WwSerial>,
|
||||
bootstrap: DivaSliderBootstrap,
|
||||
last_lights: Instant,
|
||||
}
|
||||
|
||||
impl DivaSliderJob {
|
||||
|
@ -211,6 +215,7 @@ impl DivaSliderJob {
|
|||
deserializer: DivaDeserializer::new(),
|
||||
serial_port: None,
|
||||
bootstrap: DivaSliderBootstrap::Init,
|
||||
last_lights: Instant::now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +228,7 @@ impl ThreadJob for DivaSliderJob {
|
|||
115200
|
||||
);
|
||||
|
||||
let serial_port = WwSerial::new(self.port.clone(), 115200, 10, true);
|
||||
let serial_port = WwSerial::new(self.port.clone(), 115200, 5, 0, false);
|
||||
if !serial_port.check() {
|
||||
error!("Cannot open serial port at {}", self.port.as_str());
|
||||
return false;
|
||||
|
@ -238,9 +243,9 @@ impl ThreadJob for DivaSliderJob {
|
|||
let serial_port = self.serial_port.as_mut().unwrap();
|
||||
|
||||
self.read_buf.clear();
|
||||
let read_amount = serial_port.read(&mut self.read_buf, 1024) as usize;
|
||||
let read_amount = serial_port.read(&mut self.read_buf) as usize;
|
||||
if read_amount > 0 {
|
||||
// debug!("Serial read {} bytes", read_amount);
|
||||
debug!("Serial read {} bytes", read_amount);
|
||||
self
|
||||
.deserializer
|
||||
.deserialize(&self.read_buf[0..read_amount], &mut self.in_packets);
|
||||
|
@ -285,6 +290,7 @@ impl ThreadJob for DivaSliderJob {
|
|||
let start_packet = DivaPacket::from_bytes(0x03, &[]);
|
||||
self.out_packets.push_back(start_packet);
|
||||
self.bootstrap = DivaSliderBootstrap::ReadLoop;
|
||||
self.last_lights = Instant::now();
|
||||
}
|
||||
}
|
||||
DivaSliderBootstrap::ReadLoop => {
|
||||
|
@ -302,7 +308,8 @@ impl ThreadJob for DivaSliderJob {
|
|||
let mut lights_buf = [0; 94];
|
||||
{
|
||||
let mut lights_handle = self.state.lights.lock();
|
||||
if lights_handle.dirty {
|
||||
// Send leds at least once a second to keep alive
|
||||
if lights_handle.dirty || self.last_lights.elapsed() > Duration::from_millis(1000) {
|
||||
send_lights = true;
|
||||
lights_buf[0] = self.brightness;
|
||||
lights_buf[1..94].copy_from_slice(&lights_handle.ground[0..93]);
|
||||
|
@ -311,16 +318,26 @@ impl ThreadJob for DivaSliderJob {
|
|||
}
|
||||
|
||||
if send_lights {
|
||||
self.last_lights = Instant::now();
|
||||
let lights_packet = DivaPacket::from_bytes(0x02, &lights_buf);
|
||||
self.out_packets.push_back(lights_packet);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// sleep(Duration::from_millis(3));
|
||||
while let Some(mut packet) = self.out_packets.pop_front() {
|
||||
serial_port.write(packet.serialize());
|
||||
work = true;
|
||||
let data = packet.serialize();
|
||||
let bytes_written = serial_port.write(data);
|
||||
if bytes_written == 0 {
|
||||
warn!("Serial write timeout");
|
||||
}
|
||||
debug!("Serial write {}/{}", bytes_written, data.len());
|
||||
}
|
||||
|
||||
// sleep(Duration::from_millis(3));
|
||||
|
||||
// TODO: async worker?
|
||||
// sleep(Duration::from_millis(10));
|
||||
|
||||
|
|
|
@ -82,6 +82,8 @@ impl AsyncWorker {
|
|||
where
|
||||
T: AsyncJob,
|
||||
{
|
||||
info!("Async worker starting {}", name);
|
||||
|
||||
let stop_signal = Arc::new(AtomicBool::new(false));
|
||||
|
||||
let stop_signal_clone = Arc::clone(&stop_signal);
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
struct CxxSerial
|
||||
{
|
||||
CxxSerial(rust::String port, uint32_t baud, uint32_t timeout, bool hardware);
|
||||
CxxSerial(rust::String port, uint32_t baud, uint32_t read_timeout, uint32_t write_timeout, bool hardware);
|
||||
|
||||
uint32_t write(const rust::Vec<uint8_t> &data) const;
|
||||
|
||||
uint32_t read(rust::Vec<uint8_t> &data, uint32_t cap) const;
|
||||
uint32_t read(rust::Vec<uint8_t> &data) const;
|
||||
|
||||
void flush() const;
|
||||
|
||||
|
@ -22,4 +22,4 @@ private:
|
|||
};
|
||||
|
||||
// port: String, baud: u32, timeout: u32, hardware: bool
|
||||
std::unique_ptr<CxxSerial> new_cxx_serial(rust::String port, uint32_t baud, uint32_t timeout, bool hardware);
|
||||
std::unique_ptr<CxxSerial> new_cxx_serial(rust::String port, uint32_t baud, uint32_t read_timeout, uint32_t write_timeout, bool hardware);
|
|
@ -3,7 +3,7 @@ extern crate wwserial;
|
|||
use wwserial::WwSerial;
|
||||
|
||||
fn main() {
|
||||
let s = WwSerial::new("COM3".to_string(), 115200, 1000, true);
|
||||
let s = WwSerial::new("COM3".to_string(), 115200, 20, 20, true);
|
||||
|
||||
let x: Vec<u8> = vec![0xff, 0x10, 0x00, 0xf1];
|
||||
println!("Sending {:?}", x);
|
||||
|
@ -11,7 +11,7 @@ fn main() {
|
|||
println!("Sent {}/4", bytes);
|
||||
|
||||
let mut r: Vec<u8> = Vec::with_capacity(100);
|
||||
s.read(&mut r, 100);
|
||||
s.read(&mut r);
|
||||
println!("Received {:?}", r);
|
||||
|
||||
let x: Vec<u8> = vec![0xff, 0xf0, 0x00, 0x11];
|
||||
|
@ -20,7 +20,7 @@ fn main() {
|
|||
println!("Sent {}/4", bytes);
|
||||
|
||||
let mut r: Vec<u8> = Vec::with_capacity(100);
|
||||
s.read(&mut r, 100);
|
||||
s.read(&mut r);
|
||||
println!("Received {:?}", r);
|
||||
|
||||
let x: Vec<u8> = vec![0xff, 0x03, 0x00, 0xfe];
|
||||
|
@ -28,12 +28,28 @@ fn main() {
|
|||
let bytes = s.write(&x);
|
||||
println!("Sent {}/4", bytes);
|
||||
|
||||
let mut r: Vec<u8> = Vec::with_capacity(100);
|
||||
s.read(&mut r);
|
||||
println!("Received {:?}", r);
|
||||
|
||||
let x: Vec<u8> = vec![0xff; 130];
|
||||
println!("Sending {:?}", x);
|
||||
let bytes = s.write(&x);
|
||||
println!("Sent {}/130", bytes);
|
||||
|
||||
println!("Infinite looping, ctrl-c to quit");
|
||||
loop {
|
||||
let mut r: Vec<u8> = Vec::with_capacity(500);
|
||||
let bytes = s.read(&mut r, 500);
|
||||
let bytes = s.read(&mut r);
|
||||
if bytes > 0 {
|
||||
println!("(ctrl-c to quit) Received ({}) {:?}", bytes, r);
|
||||
|
||||
{
|
||||
let x: Vec<u8> = vec![0xff; 130];
|
||||
println!("Sending {:?}", x);
|
||||
let bytes = s.write(&x);
|
||||
println!("Sent {}/130", bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@ mod ffi {
|
|||
fn new_cxx_serial(
|
||||
port: String,
|
||||
baud: u32,
|
||||
timeout: u32,
|
||||
read_timeout: u32,
|
||||
write_timeout: u32,
|
||||
hardware: bool,
|
||||
) -> UniquePtr<CxxSerial>;
|
||||
|
||||
fn write(self: &CxxSerial, data: &Vec<u8>) -> u32;
|
||||
|
||||
fn read(self: &CxxSerial, data: &mut Vec<u8>, cap: u32) -> u32;
|
||||
fn read(self: &CxxSerial, data: &mut Vec<u8>) -> u32;
|
||||
|
||||
fn flush(self: &CxxSerial);
|
||||
|
||||
|
@ -31,9 +32,15 @@ pub struct WwSerial {
|
|||
unsafe impl Send for WwSerial {}
|
||||
|
||||
impl WwSerial {
|
||||
pub fn new(port: String, baud: u32, timeout: u32, hardware: bool) -> Self {
|
||||
pub fn new(
|
||||
port: String,
|
||||
baud: u32,
|
||||
read_timeout: u32,
|
||||
write_timeout: u32,
|
||||
hardware: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
inner: new_cxx_serial(port, baud, timeout, hardware),
|
||||
inner: new_cxx_serial(port, baud, read_timeout, write_timeout, hardware),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,8 +50,8 @@ impl WwSerial {
|
|||
}
|
||||
|
||||
// #[inline(always)]
|
||||
pub fn read(&self, data: &mut Vec<u8>, cap: u32) -> u32 {
|
||||
self.inner.read(data, cap)
|
||||
pub fn read(&self, data: &mut Vec<u8>) -> u32 {
|
||||
self.inner.read(data)
|
||||
}
|
||||
|
||||
// #[inline(always)]
|
||||
|
|
|
@ -351,8 +351,13 @@ Serial::SerialImpl::write (const uint8_t *data, size_t length)
|
|||
}
|
||||
DWORD bytes_written;
|
||||
if (!WriteFile(fd_, data, static_cast<DWORD>(length), &bytes_written, NULL)) {
|
||||
DWORD errcode = GetLastError();
|
||||
if (errcode == 121) {
|
||||
// Timeout
|
||||
return 0;
|
||||
}
|
||||
stringstream ss;
|
||||
ss << "Error while writing to the serial port: " << GetLastError();
|
||||
ss << "Error while writing to the serial port: " << errcode;
|
||||
THROW (IOException, ss.str().c_str());
|
||||
}
|
||||
return (size_t) (bytes_written);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "wwserial/src/lib.rs.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
struct CxxSerial::impl
|
||||
{
|
||||
|
@ -16,7 +17,7 @@ struct CxxSerial::impl
|
|||
CxxSerial::impl::impl()
|
||||
: serial_port(nullptr){};
|
||||
|
||||
CxxSerial::CxxSerial(rust::String port, uint32_t baud, uint32_t timeout, bool hardware)
|
||||
CxxSerial::CxxSerial(rust::String port, uint32_t baud, uint32_t read_timeout, uint32_t write_timeout, bool hardware)
|
||||
: impl(new struct CxxSerial::impl)
|
||||
{
|
||||
impl->ok = true;
|
||||
|
@ -24,7 +25,7 @@ CxxSerial::CxxSerial(rust::String port, uint32_t baud, uint32_t timeout, bool ha
|
|||
try
|
||||
{
|
||||
impl->serial_port = std::shared_ptr<serial::Serial>(
|
||||
new class serial::Serial(port_stdstring, baud, serial::Timeout::simpleTimeout(timeout)));
|
||||
new class serial::Serial(port_stdstring, baud, serial::Timeout(1, read_timeout, 0, write_timeout, 0)));
|
||||
if (hardware)
|
||||
{
|
||||
impl->serial_port->setFlowcontrol(serial::flowcontrol_hardware);
|
||||
|
@ -41,18 +42,19 @@ uint32_t CxxSerial::write(const rust::Vec<uint8_t> &data) const
|
|||
if (impl->ok && impl->serial_port->isOpen())
|
||||
{
|
||||
std::vector<uint8_t> buf(data.begin(), data.end());
|
||||
return impl->serial_port->write(buf);
|
||||
size_t bytes_written = impl->serial_port->write(buf);
|
||||
return bytes_written;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
uint32_t CxxSerial::read(rust::Vec<uint8_t> &data, uint32_t cap) const
|
||||
uint32_t CxxSerial::read(rust::Vec<uint8_t> &data) const
|
||||
{
|
||||
if (impl->ok && impl->serial_port->isOpen())
|
||||
{
|
||||
std::vector<uint8_t> buf;
|
||||
buf.reserve(cap);
|
||||
size_t bytes_read = impl->serial_port->read(buf, (size_t)cap);
|
||||
buf.reserve(data.capacity());
|
||||
size_t bytes_read = impl->serial_port->read(buf, (size_t)buf.capacity());
|
||||
std::copy(
|
||||
buf.begin(), buf.end(),
|
||||
std::back_inserter(data));
|
||||
|
@ -74,7 +76,7 @@ bool CxxSerial::check() const
|
|||
return impl->ok;
|
||||
}
|
||||
|
||||
std::unique_ptr<CxxSerial> new_cxx_serial(rust::String port, uint32_t baud, uint32_t timeout, bool hardware)
|
||||
std::unique_ptr<CxxSerial> new_cxx_serial(rust::String port, uint32_t baud, uint32_t read_timeout, uint32_t write_timeout, bool hardware)
|
||||
{
|
||||
return std::make_unique<CxxSerial>(port, baud, timeout, hardware);
|
||||
return std::make_unique<CxxSerial>(port, baud, read_timeout, write_timeout, hardware);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue