diff --git a/hid-service/src/i2c/device.rs b/hid-service/src/i2c/device.rs index 9d8940e2a..e9265c063 100644 --- a/hid-service/src/i2c/device.rs +++ b/hid-service/src/i2c/device.rs @@ -1,6 +1,7 @@ use core::borrow::BorrowMut; use embassy_sync::mutex::Mutex; +use embassy_time::{Duration, with_timeout}; use embedded_hal_async::i2c::{AddressMode, I2c}; use embedded_services::hid::{DeviceContainer, InvalidSizeError, Opcode, Response}; use embedded_services::{GlobalRawMutex, buffer::*}; @@ -8,6 +9,9 @@ use embedded_services::{error, hid, info, trace}; use crate::Error; +const DEVICE_RESPONSE_TIMEOUT_MS: u64 = 200; +const DATA_READ_TIMEOUT_MS: u64 = 50; + pub struct Device> { device: hid::Device, buffer: OwnedRef<'static, u8>, @@ -47,10 +51,19 @@ impl> Device { })))?; reg.copy_from_slice(&self.device.regs.hid_desc_reg.to_le_bytes()); - if let Err(e) = bus.write_read(self.address, ®, buf).await { + with_timeout( + Duration::from_millis(DEVICE_RESPONSE_TIMEOUT_MS), + bus.write_read(self.address, ®, buf), + ) + .await + .map_err(|_| { + error!("Read HID descriptor timeout"); + Error::Hid(hid::Error::Timeout) + })? + .map_err(|e| { error!("Failed to read HID descriptor"); - return Err(Error::Bus(e)); - } + Error::Bus(e) + })?; let res = hid::Descriptor::decode_from_slice(buf); match res { @@ -89,8 +102,9 @@ impl> Device { let len = desc.w_report_desc_length as usize; let mut bus = self.bus.lock().await; - if let Err(e) = bus - .write_read( + with_timeout( + Duration::from_millis(DEVICE_RESPONSE_TIMEOUT_MS), + bus.write_read( self.address, ®, buf.get_mut(0..len) @@ -98,12 +112,17 @@ impl> Device { expected: len, actual: buffer_len, })))?, - ) - .await - { + ), + ) + .await + .map_err(|_| { + error!("Read report descriptor timeout"); + Error::Hid(hid::Error::Timeout) + })? + .map_err(|e| { error!("Failed to read report descriptor"); - return Err(Error::Bus(e)); - } + Error::Bus(e) + })?; self.buffer.reference().slice(0..len).map_err(Error::Buffer) } @@ -123,10 +142,16 @@ impl> Device { })))?; let mut bus = self.bus.lock().await; - if let Err(e) = bus.read(self.address, buf).await { - error!("Failed to read input report"); - return Err(Error::Bus(e)); - } + with_timeout(Duration::from_millis(DATA_READ_TIMEOUT_MS), bus.read(self.address, buf)) + .await + .map_err(|_| { + error!("Read input report timeout"); + Error::Hid(hid::Error::Timeout) + })? + .map_err(|e| { + error!("Failed to read input report"); + Error::Bus(e) + })?; self.buffer .reference() @@ -164,27 +189,39 @@ impl> Device { })?; let mut bus = self.bus.lock().await; - if let Err(e) = bus - .write( + with_timeout( + Duration::from_millis(DEVICE_RESPONSE_TIMEOUT_MS), + bus.write( self.address, buf.get(..len) .ok_or(Error::Hid(hid::Error::InvalidSize(InvalidSizeError { expected: len, actual: buffer_len, })))?, - ) - .await - { + ), + ) + .await + .map_err(|_| { + error!("Write command timeout"); + Error::Hid(hid::Error::Timeout) + })? + .map_err(|e| { error!("Failed to write command"); - return Err(Error::Bus(e)); - } + Error::Bus(e) + })?; if opcode.has_response() { trace!("Reading host data"); - if let Err(e) = bus.read(self.address, buf).await { - error!("Failed to read host data"); - return Err(Error::Bus(e)); - } + with_timeout(Duration::from_millis(DATA_READ_TIMEOUT_MS), bus.read(self.address, buf)) + .await + .map_err(|_| { + error!("Read host data timeout"); + Error::Hid(hid::Error::Timeout) + })? + .map_err(|e| { + error!("Failed to read host data"); + Error::Bus(e) + })?; return Ok(Some(Response::FeatureReport(self.buffer.reference()))); }