Skip to main content

hidpp/feature/crown/
event.rs

1//! The event emitted by the `Crown` feature (`0x4600`).
2
3use num_enum::{IntoPrimitive, TryFromPrimitive};
4
5/// Rotation phase reported in a [`CrownUpdate`].
6#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize))]
8#[non_exhaustive]
9#[repr(u8)]
10pub enum RotationState {
11    /// Not rotating (or not diverted).
12    Inactive = 0,
13    /// Rotation started.
14    Start = 1,
15    /// Rotation ongoing.
16    Active = 2,
17    /// Rotation stopped.
18    Stop = 3,
19}
20
21/// Proximity or touch activity phase reported in a [`CrownUpdate`].
22#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize))]
24#[non_exhaustive]
25#[repr(u8)]
26pub enum ActivityState {
27    /// Inactive.
28    Inactive = 0,
29    /// Started.
30    Start = 1,
31    /// Ongoing.
32    Active = 2,
33    /// Stopped.
34    Stop = 3,
35}
36
37/// Touch gesture reported in a [`CrownUpdate`].
38#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
39#[cfg_attr(feature = "serde", derive(serde::Serialize))]
40#[non_exhaustive]
41#[repr(u8)]
42pub enum CrownGesture {
43    /// No gesture.
44    None = 0,
45    /// Single tap.
46    Tap = 1,
47    /// Double tap.
48    DoubleTap = 2,
49}
50
51/// Crown button state reported in a [`CrownUpdate`].
52#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
53#[cfg_attr(feature = "serde", derive(serde::Serialize))]
54#[non_exhaustive]
55#[repr(u8)]
56pub enum ButtonState {
57    /// Inactive (or not diverted).
58    Inactive = 0,
59    /// Press started.
60    Press = 1,
61    /// Short press active.
62    ShortPressActive = 2,
63    /// Long press reached the time threshold.
64    LongPress = 3,
65    /// Long press active.
66    LongPressActive = 4,
67    /// Released.
68    Release = 5,
69}
70
71/// An event emitted by [`CrownFeature`](super::CrownFeature).
72#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize))]
74#[non_exhaustive]
75pub enum CrownEvent {
76    /// The crown's rotation, proximity, touch, gesture or button state changed.
77    ///
78    /// Only reported while the crown is diverted (see
79    /// [`set_mode`](super::CrownFeature::set_mode)).
80    Update(CrownUpdate),
81}
82
83/// Payload of [`CrownEvent::Update`].
84#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
85#[cfg_attr(feature = "serde", derive(serde::Serialize))]
86#[non_exhaustive]
87pub struct CrownUpdate {
88    /// Current rotation phase.
89    pub rotation_state: RotationState,
90    /// Slots rotated since the last event (`-127..=127`).
91    pub relative_slot_rotation: i8,
92    /// Ratchets rotated since the last event (`-127..=127`).
93    pub relative_ratchet_rotation: i8,
94    /// Proximity-sensor phase.
95    pub proximity: ActivityState,
96    /// Touch-sensor phase.
97    pub touch: ActivityState,
98    /// Touch gesture detected.
99    pub gesture: CrownGesture,
100    /// Button state.
101    pub button: ButtonState,
102    /// Crown speed in slots per second (signed).
103    pub speed: i16,
104}
105
106/// Decodes the `0x4600` event payload by its sub-id.
107pub(super) fn decode_event(sub_id: u8, payload: &[u8; 16]) -> Option<CrownEvent> {
108    match sub_id {
109        0 => Some(CrownEvent::Update(CrownUpdate {
110            rotation_state: RotationState::try_from(payload[0]).ok()?,
111            relative_slot_rotation: payload[1] as i8,
112            relative_ratchet_rotation: payload[2] as i8,
113            proximity: ActivityState::try_from(payload[3]).ok()?,
114            touch: ActivityState::try_from(payload[4]).ok()?,
115            gesture: CrownGesture::try_from(payload[5]).ok()?,
116            button: ButtonState::try_from(payload[6]).ok()?,
117            speed: i16::from_be_bytes([payload[14], payload[15]]),
118        })),
119        _ => None,
120    }
121}