Skip to main content

beyond_lib/
protocol.rs

1//! The raw data handled by the headset.
2
3pub mod memory;
4pub mod status;
5
6use strum_macros::FromRepr;
7
8/// HID reports sent & received from the headset will always be this many bytes
9/// long.
10pub const HID_REPORT_SIZE: usize = 64;
11
12/// Minimum amount of time in minutes in which the headset registers updates for
13/// a time statistic.
14pub const TIMESTAT_STEP: u32 = 10;
15
16/// A list of all commands that can be sent or received from the mainboard.
17///
18/// These commands are only for the regular mode of the mainboard.
19///
20/// # Implementation
21/// The data sent to, or received by the HMD must always be [`HID_REPORT_SIZE`]
22/// bytes large, with the first byte representing the command ID.
23/// The subsequent [`HID_REPORT_SIZE - 1`] bytes can be used for any extra data
24/// required for this command.
25///
26/// If a sent command does not need to return anything, [`Self::Ack`] will be
27/// returned by default.
28///
29/// If a command fails, [`Self::Error`] will be returned to indicate *something*
30/// going wrong.
31#[derive(Debug, PartialEq, Eq, FromRepr)]
32#[repr(u8)]
33#[non_exhaustive]
34pub enum CommandIds {
35    // ===== General returns =====
36    /// Returned when a command is sent that doesn't need a response.
37    ///
38    /// Some examples of when it'll return are:
39    /// - Setting the fan speed.
40    /// - Setting the brightness.
41    /// - Writing memory.
42    Ack = 0x24,
43    /// Returned when a command fails for whatever reason.
44    Error = 0x45,
45
46    // ===== Device statistics =====
47    /// When sent, headset will respond with a null-terminated string of the
48    /// secondary serial number.
49    SecondarySerial = 0x26,
50    /// When sent, headset will respond with a null-terminated string of the
51    /// firmware version.
52    FirmwareVersion = 0x2A,
53    /// Send, in addition to a second byte representing which time statistic you
54    /// want to obtain from the headset.
55    ///
56    /// The available statistics are:
57    /// - 0: Idle time
58    /// - 1: Usage time
59    /// - 2: Longest session
60    ///
61    /// The returned value is a little-endian u32 in deca-minutes (10 minutes),
62    /// meaning you will need to multiply by [`TIMESTAT_STEP`] to get the value
63    /// in minutes.
64    ///
65    /// # Data representation
66    /// The returned value is alright to store in a u32 due to the maximum value
67    /// ([`u32::MAX`]) taking approx 82,000 years to overflow.
68    TimeStat = 0x5A,
69
70    // ===== Hardware commands =====
71    /// Send, in addition to a byte representing the fan speed from 0 to 100, to
72    /// temporarily set the fan speed.
73    SetFan = 0x46,
74    /// Send, in addition to a big-endian u16 representing the brightness, to
75    /// temporarily set the current brightness.
76    ///
77    /// Also see: [`crate::helpers::Brightness`].
78    SetBrightness = 0x49,
79    /// Send, in addition to 3 bytes representing red, green, and blue (in this
80    /// order) to set the LED color.
81    ///
82    /// Also see: [`crate::helpers::RgbColor`].
83    SetLed = 0x4C,
84    /// Send, in addition to a byte representing which display mode
85    /// (refresh rate & resolution) to use.
86    ///
87    /// Values for this extra byte can be:
88    /// - 0: 2560x2560 @ 75 Hz
89    /// - 1: 1920x1920 @ 90 Hz
90    ///
91    /// Also see: [`crate::helpers::DisplayMode`].
92    SetMode = 0x64,
93
94    // ===== Background Statistic =====
95    Log = 0x3B,
96    DeviceStat = 0x23,
97
98    // ===== Configuration memory =====
99    /// Send, in addition to a byte representing the bank
100    /// (zero indexed, [`crate::protocol::memory::BANK_COUNT`] banks total),
101    /// to get a byte of size
102    /// (always [`crate::protocol::memory::BANK_CAPACITY`]),
103    /// followed by `size` bytes of data.
104    ///
105    /// To get the full memory
106    /// ([`crate::protocol::memory::MEMORY_SIZE`] bytes large),
107    /// concat all the banks.
108    ///
109    /// # Decoding
110    /// To decode the banks, see
111    /// [`crate::protocol::memory::ConfigurationMemory`] for details on how to
112    /// do this.
113    ///
114    /// Also see: [`crate::protocol::memory`].
115    ReadMemory = 0x55,
116    /// Send, in addition to a byte representing the bank
117    /// (zero indexed, [`crate::protocol::memory::BANK_COUNT`] banks total),
118    /// and [`crate::protocol::memory::BANK_CAPACITY`] bytes of data
119    /// (for [`crate::protocol::memory::MEMORY_SIZE`] bytes of total data).
120    ///
121    /// Once complete, [`Self::CommitMemory`] must be sent.
122    ///
123    /// Also see: [`crate::protocol::memory`].
124    WriteMemory = 0x57,
125    /// Send to commit memory written by [`Self::WriteMemory`].
126    ///
127    /// If the display mode in the memory has been changed
128    /// (see [`crate::protocol::memory::MemoryItem::DisplayMode`]), an extra ack
129    /// ([`Self::Ack`]) will be returned.
130    CommitMemory = 0x56,
131
132    // ===== Misc =====
133    FirmwareFlash = 0x42,
134
135    BigeyeCommand = 0x65,
136}
137
138impl CommandIds {
139    #[inline]
140    pub const fn id(self) -> u8 {
141        self as u8
142    }
143}