feat(hid): streamline timing between consistency and superhack

This commit is contained in:
Naxdy 2024-04-19 17:07:26 +02:00
parent d661abc882
commit 818e0abf76
Signed by: Naxdy
GPG key ID: CC15075846BCE91B

View file

@ -13,7 +13,7 @@ use embassy_rp::{
}; };
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, signal::Signal}; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, signal::Signal};
use embassy_time::{Duration, Instant, Ticker, Timer}; use embassy_time::{Duration, Instant, Timer};
use embassy_usb::{ use embassy_usb::{
class::hid::{HidReaderWriter, ReportId, RequestHandler, State}, class::hid::{HidReaderWriter, ReportId, RequestHandler, State},
control::OutResponse, control::OutResponse,
@ -361,7 +361,7 @@ pub async fn usb_transfer_task(raw_serial: [u8; 8], driver: Driver<'static, USB>
let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap(); let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap();
let mut last_report_time = Instant::now(); let mut last_report_time = Instant::now();
let mut ticker = Ticker::every(Duration::from_micros(8333)); let mut rate_limit_end_time = Instant::now();
loop { loop {
// This is what we like to call a "hack". // This is what we like to call a "hack".
@ -374,18 +374,9 @@ pub async fn usb_transfer_task(raw_serial: [u8; 8], driver: Driver<'static, USB>
// a minimum of 333 extra us to send a report every time it's polled, but it // a minimum of 333 extra us to send a report every time it's polled, but it
// works to our advantage. // works to our advantage.
match input_consistency_mode { match input_consistency_mode {
InputConsistencyMode::SuperHack => { InputConsistencyMode::SuperHack | InputConsistencyMode::ConsistencyHack => {
// In SuperHack mode, we send reports only if the state changes, but // "Ticker at home", so we can use this for both consistency and SuperHack mode
// in order to not mess up very fast inputs (like sticks travelling, for example), Timer::at(rate_limit_end_time).await;
// we still need to "rate limit" the reports to every 8.33ms at most.
// This does rate limit it to ~8.33ms fairly well, my only
// gripe with it is that I hate it :)
Timer::at(last_report_time + Duration::from_micros(8100)).await;
}
InputConsistencyMode::ConsistencyHack => {
// Ticker better maintains a consistent interval than Timer, so
// we prefer it for consistency mode, where we send reports regularly.
ticker.next().await;
} }
InputConsistencyMode::Original => {} InputConsistencyMode::Original => {}
} }
@ -404,12 +395,10 @@ pub async fn usb_transfer_task(raw_serial: [u8; 8], driver: Driver<'static, USB>
let polltime = currtime.duration_since(last_report_time); let polltime = currtime.duration_since(last_report_time);
let micros = polltime.as_micros(); let micros = polltime.as_micros();
debug!("Report written in {}us", micros); debug!("Report written in {}us", micros);
// If we're sending reports too fast in regular consistency mode, reset the ticker. if input_consistency_mode != InputConsistencyMode::Original {
// This might happen right after plug-in, or after suspend. while rate_limit_end_time < currtime {
if input_consistency_mode == InputConsistencyMode::ConsistencyHack rate_limit_end_time += Duration::from_micros(8333);
&& micros < 8150 }
{
ticker.reset()
} }
last_report_time = currtime; last_report_time = currtime;
} }