From 1d51c12bc1021370ee8a68770d457cb3f115d106 Mon Sep 17 00:00:00 2001 From: Naxdy Date: Fri, 19 Apr 2024 14:20:14 +0200 Subject: [PATCH] feat(hid): implement lower-latency consistency algo --- src/gcc_hid.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/gcc_hid.rs b/src/gcc_hid.rs index e5b3bff..72bcf03 100644 --- a/src/gcc_hid.rs +++ b/src/gcc_hid.rs @@ -13,7 +13,7 @@ use embassy_rp::{ }; 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::{ class::hid::{HidReaderWriter, ReportId, RequestHandler, State}, control::OutResponse, @@ -361,7 +361,8 @@ 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 last_report_time = Instant::now(); - let mut ticker = Ticker::every(Duration::from_micros(8333)); + let mut frame_ready_time = Instant::now() + Duration::from_micros(8333); + let mut usb_ready_time = Instant::now() + Duration::from_millis(8); loop { // This is what we like to call a "hack". @@ -383,9 +384,18 @@ pub async fn usb_transfer_task(raw_serial: [u8; 8], driver: Driver<'static, USB> 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; + // Ensure we report in multiples of 1 (not in decimals, like 8.33ms) + Timer::at(usb_ready_time).await; + while Instant::now() < frame_ready_time { + Timer::after_micros(1000).await; + } + // has to be done this way in case we're behind through e.g. suspends + while frame_ready_time < Instant::now() { + frame_ready_time += Duration::from_micros(8333); + } + while usb_ready_time < Instant::now() { + usb_ready_time += Duration::from_millis(8); + } } InputConsistencyMode::Original => {} } @@ -404,13 +414,6 @@ pub async fn usb_transfer_task(raw_serial: [u8; 8], driver: Driver<'static, USB> let polltime = currtime.duration_since(last_report_time); let micros = polltime.as_micros(); debug!("Report written in {}us", micros); - // If we're sending reports too fast in regular consistency mode, reset the ticker. - // This might happen right after plug-in, or after suspend. - if input_consistency_mode == InputConsistencyMode::ConsistencyHack - && micros < 8150 - { - ticker.reset() - } last_report_time = currtime; } Err(e) => warn!("Failed to send report: {:?}", e),