feat(hid): implement lower-latency consistency algo
This commit is contained in:
parent
d661abc882
commit
1d51c12bc1
1 changed files with 15 additions and 12 deletions
|
@ -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,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 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 frame_ready_time = Instant::now() + Duration::from_micros(8333);
|
||||||
|
let mut usb_ready_time = Instant::now() + Duration::from_millis(8);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// This is what we like to call a "hack".
|
// 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;
|
Timer::at(last_report_time + Duration::from_micros(8100)).await;
|
||||||
}
|
}
|
||||||
InputConsistencyMode::ConsistencyHack => {
|
InputConsistencyMode::ConsistencyHack => {
|
||||||
// Ticker better maintains a consistent interval than Timer, so
|
// Ensure we report in multiples of 1 (not in decimals, like 8.33ms)
|
||||||
// we prefer it for consistency mode, where we send reports regularly.
|
Timer::at(usb_ready_time).await;
|
||||||
ticker.next().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 => {}
|
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 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.
|
|
||||||
// This might happen right after plug-in, or after suspend.
|
|
||||||
if input_consistency_mode == InputConsistencyMode::ConsistencyHack
|
|
||||||
&& micros < 8150
|
|
||||||
{
|
|
||||||
ticker.reset()
|
|
||||||
}
|
|
||||||
last_report_time = currtime;
|
last_report_time = currtime;
|
||||||
}
|
}
|
||||||
Err(e) => warn!("Failed to send report: {:?}", e),
|
Err(e) => warn!("Failed to send report: {:?}", e),
|
||||||
|
|
Loading…
Reference in a new issue