Better timing values for responsiveness and less CPU time

This commit is contained in:
Luke
2020-04-25 16:35:37 +12:00
parent 7be66f31e8
commit b821ebe267
4 changed files with 33 additions and 126 deletions

View File

@@ -24,28 +24,29 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut key_colours = KeyColourArray::new(); let mut key_colours = KeyColourArray::new();
per_key_led.push(key_colours.clone()); per_key_led.push(key_colours.clone());
for _ in 0..49 { for _ in 0..29 {
*key_colours.key(Key::ROG).0 += 5; *key_colours.key(Key::ROG).0 += 8;
*key_colours.key(Key::L).0 += 5; *key_colours.key(Key::L).0 += 8;
*key_colours.key(Key::I).0 += 5; *key_colours.key(Key::I).0 += 8;
*key_colours.key(Key::N).0 += 5; *key_colours.key(Key::N).0 += 8;
*key_colours.key(Key::U).0 += 5; *key_colours.key(Key::U).0 += 8;
*key_colours.key(Key::X).0 += 5; *key_colours.key(Key::X).0 += 8;
per_key_led.push(key_colours.clone()); per_key_led.push(key_colours.clone());
} }
for _ in 0..49 { for _ in 0..29 {
*key_colours.key(Key::ROG).0 -= 5; *key_colours.key(Key::ROG).0 -= 8;
*key_colours.key(Key::L).0 -= 5; *key_colours.key(Key::L).0 -= 8;
*key_colours.key(Key::I).0 -= 5; *key_colours.key(Key::I).0 -= 8;
*key_colours.key(Key::N).0 -= 5; *key_colours.key(Key::N).0 -= 8;
*key_colours.key(Key::U).0 -= 5; *key_colours.key(Key::U).0 -= 8;
*key_colours.key(Key::X).0 -= 5; *key_colours.key(Key::X).0 -= 8;
per_key_led.push(key_colours.clone()); per_key_led.push(key_colours.clone());
} }
// It takes the EC 20ms to process a single colour block // It takes each interrupt at least 1ms. 10ms to write complete block. Plus any extra
let time = time::Duration::from_millis(20); // penalty time such as read waits
let time = time::Duration::from_millis(16); // aim for 60 per second
let row = KeyColourArray::get_init_msg(); let row = KeyColourArray::get_init_msg();
let msg = let msg =

View File

@@ -1,78 +0,0 @@
use daemon::aura::{BuiltInModeByte, Key, KeyColourArray};
use daemon::daemon::{DBUS_IFACE, DBUS_NAME, DBUS_PATH};
use dbus::Error as DbusError;
use dbus::{ffidisp::Connection, Message};
use std::{thread, time};
pub fn dbus_led_builtin_write(bytes: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
let bus = Connection::new_system()?;
//let proxy = bus.with_proxy(DBUS_IFACE, "/", Duration::from_millis(5000));
let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")?
.append1(bytes.to_vec());
let r = bus.send_with_reply_and_block(msg, 5000)?;
if let Some(reply) = r.get1::<&str>() {
println!("Success: {:x?}", reply);
return Ok(());
}
Err(Box::new(DbusError::new_custom("name", "message")))
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let bus = Connection::new_system()?;
let mut per_key_led = Vec::new();
let mut key_colours = KeyColourArray::new();
// key_colours.set(Key::ROG, 0, 0, 0);
// key_colours.set(Key::L, 0, 0, 0);
// key_colours.set(Key::I, 0, 0, 0);
// key_colours.set(Key::N, 0, 0, 0);
// key_colours.set(Key::U, 0, 0, 0);
// key_colours.set(Key::X, 0, 0, 0);
per_key_led.push(key_colours.clone());
// for _ in 0..49 {
// *key_colours.key(Key::ROG).0 -= 5;
// *key_colours.key(Key::L).0 -= 5;
// *key_colours.key(Key::I).0 -= 5;
// *key_colours.key(Key::N).0 -= 5;
// *key_colours.key(Key::U).0 -= 5;
// *key_colours.key(Key::X).0 -= 5;
// per_key_led.push(key_colours.clone());
// }
for _ in 0..49 {
*key_colours.key(Key::ROG).0 += 5;
*key_colours.key(Key::L).0 += 5;
*key_colours.key(Key::I).0 += 5;
*key_colours.key(Key::N).0 += 5;
*key_colours.key(Key::U).0 += 5;
*key_colours.key(Key::X).0 += 5;
per_key_led.push(key_colours.clone());
}
let time = time::Duration::from_millis(2);
let row = KeyColourArray::get_init_msg();
let msg =
Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")?.append1(row);
bus.send(msg).unwrap();
loop {
let now = std::time::Instant::now();
for group in &per_key_led {
for row in group.get() {
thread::sleep(time);
let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")?
.append1(row.to_vec());
bus.send(msg).unwrap();
// if let Some(reply) = r.get1::<&str>() {
// println!("Success: {:x?}", reply);
// return Ok(());
// }
}
}
let after = std::time::Instant::now();
let diff = after.duration_since(now);
dbg!(diff.as_millis());
//return Ok(());
}
}

View File

@@ -9,7 +9,7 @@ use crate::{
}; };
use aho_corasick::AhoCorasick; use aho_corasick::AhoCorasick;
use gumdrop::Options; use gumdrop::Options;
use log::{error, info, warn}; use log::{debug, error, info, warn};
use rusb::DeviceHandle; use rusb::DeviceHandle;
use std::error::Error; use std::error::Error;
use std::fs::OpenOptions; use std::fs::OpenOptions;
@@ -64,6 +64,10 @@ impl RogCore {
for desc in iface.descriptors() { for desc in iface.descriptors() {
for endpoint in desc.endpoint_descriptors() { for endpoint in desc.endpoint_descriptors() {
if endpoint.address() == laptop.key_endpoint() { if endpoint.address() == laptop.key_endpoint() {
debug!("INTERVAL: {:?}", endpoint.interval());
debug!("MAX: {:?}", endpoint.max_packet_size());
debug!("SYNC: {:?}", endpoint.sync_type());
debug!("TRANSFER_TYPE: {:?}", endpoint.transfer_type());
interface = desc.interface_number(); interface = desc.interface_number();
break; break;
} }
@@ -128,24 +132,11 @@ impl RogCore {
} }
pub fn aura_write(&mut self, message: &[u8]) -> Result<(), AuraError> { pub fn aura_write(&mut self, message: &[u8]) -> Result<(), AuraError> {
let now = std::time::Instant::now();
match self match self
.handle .handle
.write_interrupt(self.led_endpoint, message, Duration::from_millis(1)) .write_interrupt(self.led_endpoint, message, Duration::from_millis(1))
{ {
Ok(_) => { Ok(_) => {}
let after = std::time::Instant::now();
let diff = after.duration_since(now);
dbg!(diff.as_micros());
// let mut buf = [0u8; 32];
// if let Ok(_) = self.handle.read_interrupt(
// self.led_endpoint,
// &mut buf,
// Duration::from_millis(1),
// ) {
// println!("{:X?}", buf);
// }
}
Err(err) => match err { Err(err) => match err {
rusb::Error::Timeout => {} rusb::Error::Timeout => {}
_ => error!("Failed to read keyboard interrupt: {:?}", err), _ => error!("Failed to read keyboard interrupt: {:?}", err),

View File

@@ -7,7 +7,7 @@ use dbus::{
blocking::Connection, blocking::Connection,
tree::{Factory, MethodErr}, tree::{Factory, MethodErr},
}; };
use log::{error, info, warn}; use log::{error, info};
use std::cell::RefCell; use std::cell::RefCell;
use std::error::Error; use std::error::Error;
use std::rc::Rc; use std::rc::Rc;
@@ -123,20 +123,21 @@ pub fn start_daemon() -> Result<(), Box<dyn Error>> {
// We add the tree to the connection so that incoming method calls will be handled. // We add the tree to the connection so that incoming method calls will be handled.
tree.start_receive(&connection); tree.start_receive(&connection);
//thread::spawn(move || loop {});
let supported = Vec::from(laptop.supported_modes()); let supported = Vec::from(laptop.supported_modes());
loop { loop {
// A no-comp loop takes 2 milliseconds // A no-comp loop takes 2 milliseconds
// With effect, up to 16ms // With effect, up to 16ms
// With single write, 3ms // With single write, 3ms
// Actual EC for keyboard seems to take longer to process, something like
// 2ms per line in, so 20ms per colour block?
// //
// rusb is slow. Wireshark caps show speed in nanoseconds // Timing is such that:
//thread::sleep(Duration::from_millis(2)); // - interrupt write is minimum 1ms (sometimes lower)
// - read interrupt must timeout, minimum of 1ms
// - for a single usb packet, 2ms total.
// - to maintain constant times of 1ms, per-key colours should use
// the effect endpoint so that the complete colour block is written
// as fast as 1ms per row of the matrix inside it. (10ms total time)
connection connection
.process(Duration::from_millis(20)) .process(Duration::from_millis(100))
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
error!("{:?}", err); error!("{:?}", err);
false false
@@ -145,27 +146,19 @@ pub fn start_daemon() -> Result<(), Box<dyn Error>> {
// 700u per write // 700u per write
if let Ok(mut lock) = input.try_borrow_mut() { if let Ok(mut lock) = input.try_borrow_mut() {
if let Some(bytes) = &*lock { if let Some(bytes) = &*lock {
// It takes up to 10 milliseconds to write a complete colour block here // It takes up to 20 milliseconds to write a complete colour block here
// let now = std::time::Instant::now();
rogcore.aura_set_and_save(&supported, &bytes)?; rogcore.aura_set_and_save(&supported, &bytes)?;
*lock = None; *lock = None;
// let after = std::time::Instant::now();
// let diff = after.duration_since(now);
// dbg!(diff.as_millis());
} }
} }
if let Ok(mut lock) = effect.try_borrow_mut() { if let Ok(mut lock) = effect.try_borrow_mut() {
if let Some(bytes) = &*lock { if let Some(bytes) = &*lock {
// It takes up to 10 milliseconds to write a complete colour block and here // It takes up to 10 milliseconds to write a complete colour block and here
// let now = std::time::Instant::now();
for row in bytes { for row in bytes {
rogcore.aura_write(&row)?; rogcore.aura_write(&row)?;
} }
*lock = None; *lock = None;
// let after = std::time::Instant::now();
// let diff = after.duration_since(now);
// dbg!(diff.as_millis());
} }
} }