hook with slider

pull/13/head
4yn 2022-02-22 21:55:39 +08:00
parent 24d920c5bf
commit 08b1b92f52
8 changed files with 83 additions and 31 deletions

View File

@ -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 {

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}
}
}

View File

@ -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)]

View File

@ -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);

View File

@ -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);
}