Skip to main content

hidpp/feature/report_rate/
mod.rs

1//! Implements the legacy `ReportRate` feature (ID `0x8060`).
2
3use std::sync::Arc;
4
5use crate::{
6    channel::HidppChannel,
7    feature::{CreatableFeature, Feature, FeatureEndpoint},
8    protocol::v20::Hidpp20Error,
9};
10
11bitflags::bitflags! {
12    /// Report-rate values supported by a `0x8060` device, encoded as milliseconds.
13    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14    #[cfg_attr(feature = "serde", derive(serde::Serialize))]
15    pub struct ReportRateList: u8 {
16        /// 1 ms report interval.
17        const MS_1 = 1 << 0;
18        /// 2 ms report interval.
19        const MS_2 = 1 << 1;
20        /// 3 ms report interval.
21        const MS_3 = 1 << 2;
22        /// 4 ms report interval.
23        const MS_4 = 1 << 3;
24        /// 5 ms report interval.
25        const MS_5 = 1 << 4;
26        /// 6 ms report interval.
27        const MS_6 = 1 << 5;
28        /// 7 ms report interval.
29        const MS_7 = 1 << 6;
30        /// 8 ms report interval.
31        const MS_8 = 1 << 7;
32    }
33}
34
35/// Implements the `ReportRate` / `0x8060` feature.
36#[derive(Clone)]
37pub struct ReportRateFeature {
38    /// The endpoint this feature talks to.
39    endpoint: FeatureEndpoint,
40}
41
42impl CreatableFeature for ReportRateFeature {
43    const ID: u16 = 0x8060;
44    const STARTING_VERSION: u8 = 0;
45
46    fn new(chan: Arc<HidppChannel>, device_index: u8, feature_index: u8) -> Self {
47        Self {
48            endpoint: FeatureEndpoint::new(chan, device_index, feature_index),
49        }
50    }
51}
52
53impl Feature for ReportRateFeature {}
54
55impl ReportRateFeature {
56    /// Retrieves the supported report intervals in milliseconds.
57    pub async fn get_report_rate_list(&self) -> Result<ReportRateList, Hidpp20Error> {
58        let payload = self.endpoint.call(0, [0; 3]).await?.extend_payload();
59        Ok(ReportRateList::from_bits_retain(payload[0]))
60    }
61
62    /// Retrieves the active report interval in milliseconds.
63    pub async fn get_report_rate(&self) -> Result<u8, Hidpp20Error> {
64        Ok(self.endpoint.call(1, [0; 3]).await?.extend_payload()[0])
65    }
66
67    /// Sets the active report interval in milliseconds.
68    ///
69    /// Devices reject unsupported intervals with `InvalidArgument`.
70    pub async fn set_report_rate(&self, report_rate_ms: u8) -> Result<(), Hidpp20Error> {
71        self.endpoint.call(2, [report_rate_ms, 0, 0]).await?;
72        Ok(())
73    }
74}