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}