Monado OpenXR Runtime
rift_internal.h
Go to the documentation of this file.
1// Copyright 2025, Beyley Cardellio
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Interface to Oculus Rift driver code.
6 * @author Beyley Cardellio <ep1cm1n10n123@gmail.com>
7 * @ingroup drv_rift
8 */
9
10#pragma once
11
12#include "xrt/xrt_byte_order.h"
13
14#include "util/u_device.h"
15#include "util/u_logging.h"
16
17#include "math/m_imu_3dof.h"
18#include "math/m_api.h"
19#include "math/m_mathinclude.h"
20
21#include "os/os_hid.h"
22#include "os/os_threading.h"
23
24#include <stdlib.h>
25#include <stdio.h>
26#include <assert.h>
27
28#include "rift_interface.h"
29
30
31#define HMD_TRACE(hmd, ...) U_LOG_XDEV_IFL_T(&hmd->base, hmd->log_level, __VA_ARGS__)
32#define HMD_DEBUG(hmd, ...) U_LOG_XDEV_IFL_D(&hmd->base, hmd->log_level, __VA_ARGS__)
33#define HMD_INFO(hmd, ...) U_LOG_XDEV_IFL_I(&hmd->base, hmd->log_level, __VA_ARGS__)
34#define HMD_WARN(hmd, ...) U_LOG_XDEV_IFL_W(&hmd->base, hmd->log_level, __VA_ARGS__)
35#define HMD_ERROR(hmd, ...) U_LOG_XDEV_IFL_E(&hmd->base, hmd->log_level, __VA_ARGS__)
36
37#define REPORT_MAX_SIZE 69 // max size of a feature report (FEATURE_REPORT_CALIBRATE)
38#define KEEPALIVE_INTERVAL_NS 10000000000 // 10 seconds
39// give a 5% breathing room (at 10 seconds, this is 500 milliseconds of breathing room)
40#define KEEPALIVE_SEND_RATE_NS ((KEEPALIVE_INTERVAL_NS * 19) / 20)
41#define IMU_SAMPLE_RATE (1000) // 1000hz
42#define NS_PER_SAMPLE (1000 * 1000) // 1ms (1,000,000 ns) per sample
43#define SERIAL_NUMBER_LENGTH 14
44
45#define CALIBRATION_HASH_BYTE_OFFSET 0x1bf0
46#define CALIBRATION_HASH_BYTE_LENGTH 0x10
47
48#define CALIBRATION_HEADER_BYTE_OFFSET 0x0
49#define CALIBRATION_HEADER_BYTE_LENGTH 0x4
50
51#define CALIBRATION_BODY_BYTE_OFFSET 0x4
52#define CALIBRATION_BODY_BYTE_CHUNK_LENGTH 0x14
53
54#define MICROMETERS_TO_METERS(microns) ((float)microns / 1000000.0f)
55
56// value taken from LibOVR 0.4.4
57#define DEFAULT_EXTRA_EYE_ROTATION DEG_TO_RAD(30.0f)
58
59#define IN_REPORT_DK2 11 // sent on the HMD HID interface
60#define IN_REPORT_RADIO_DATA 12 // sent on the radio HID interface
61#define IN_REPORT_CV1_RADIO_KEEPALIVE 13 // sent on the HMD HID interface when no devices are connected
62
63#define IN_REPORT_RADIO_DATA_SIZE 64
64
65#ifdef __cplusplus
66extern "C" {
67#endif
68
69// asserts the size of a type is equal to the byte size provided
70#define SIZE_ASSERT(type, size) \
71 static_assert(sizeof(type) == (size), "Size of " #type " is not " #size " bytes as was expected")
72
73enum rift_feature_reports
74{
75 // DK1
76 FEATURE_REPORT_CONFIG = 2, // get + set
77 FEATURE_REPORT_CALIBRATE = 3, // get + set
78 FEATURE_REPORT_RANGE = 4, // get + set
79 FEATURE_REPORT_REGISTER = 5, // get + set
80 FEATURE_REPORT_DFU = 6, // get + set
81 FEATURE_REPORT_DK1_KEEP_ALIVE = 8, // get + set
82 FEATURE_REPORT_DISPLAY_INFO = 9, // get + set
83 FEATURE_REPORT_SERIAL = 10, // get + set
84
85 // DK2
86 FEATURE_REPORT_TRACKING = 12, // get + set
87 FEATURE_REPORT_DISPLAY = 13, // get + set
88 FEATURE_REPORT_MAG_CALIBRATION = 14, // get + set
89 FEATURE_REPORT_POS_CALIBRATION = 15, // get + set
90 FEATURE_REPORT_CUSTOM_PATTERN = 16, // get + set
91 FEATURE_REPORT_KEEPALIVE_MUX = 17, // get + set
92 FEATURE_REPORT_MANUFACTURING = 18, // get + set
93 FEATURE_REPORT_UUID = 19, // get + set
94 FEATURE_REPORT_TEMPERATURE = 20, // get + set
95 FEATURE_REPORT_GYROOFFSET = 21, // get only
96 FEATURE_REPORT_LENS_DISTORTION = 22, // get + set
97
98 // CV1
99 FEATURE_REPORT_RADIO_CONTROL = 26, // get + set
100 FEATURE_REPORT_RADIO_READ_DATA_CMD = 27, // @todo: get + ???
101 FEATURE_REPORT_ENABLE_COMPONENTS = 29, // @todo: ??? + set
102};
103
104enum rift_config_report_flags
105{
106 // output the sample data raw from the sensors without converting them to known units
107 RIFT_CONFIG_REPORT_USE_RAW = 1,
108 // internal test mode for calibrating zero rate drift on gyro
109 RIFT_CONFIG_REPORT_INTERNAL_CALIBRATION = 1 << 1,
110 // use the calibration parameters stored on the device
111 RIFT_CONFIG_REPORT_USE_CALIBRATION = 1 << 2,
112 // recalibrate the gyro zero rate offset when the device is stationary
113 RIFT_CONFIG_REPORT_AUTO_CALIBRATION = 1 << 3,
114 // stop sending IN reports when the device has stopped moving for Interval milliseconds
115 RIFT_CONFIG_REPORT_MOTION_KEEP_ALIVE = 1 << 4,
116 // stop sending IN reports when the device has stopped receiving feature reports for Interval milliseconds
117 RIFT_CONFIG_REPORT_COMMAND_KEEP_ALIVE = 1 << 5,
118 // output the IN report data in the coordinate system used by LibOVR relative to the tracker, otherwise, report
119 // in the coordinate system of the device
120 RIFT_CONFIG_REPORT_USE_SENSOR_COORDINATES = 1 << 6,
121 // override the power state of the USB hub, forcing it to act as if the external power source is connected (DK2
122 // only, does nothing on DK1)
123 RIFT_CONFIG_REPORT_OVERRIDE_POWER = 1 << 7,
124};
125
126enum rift_distortion_type
127{
128 RIFT_DISTORTION_TYPE_DIMS = 1,
129 RIFT_DISTORTION_TYPE_K = 2,
130};
131
132enum rift_lens_type
133{
134 // firmware indirectly states lens type A is 0
135 RIFT_LENS_TYPE_A = 0,
136 // firmware does not state what lens type B is, 1 is an educated guess
137 RIFT_LENS_TYPE_B = 1,
138};
139
140enum rift_lens_distortion_version
141{
142 // no distortion data is stored
143 RIFT_LENS_DISTORTION_NONE = 0,
144 // standard distortion matrix
145 RIFT_LENS_DISTORTION_LCSV_CATMULL_ROM_10_VERSION_1 = 1,
146};
147
148enum rift_component_flags
149{
150 RIFT_COMPONENT_DISPLAY = 1 << 0,
151 RIFT_COMPONENT_AUDIO = 1 << 1,
152 RIFT_COMPONENT_LEDS = 1 << 2,
153};
154
155/*
156 *
157 * Packed structs for USB communication
158 *
159 */
160
161#pragma pack(push, 1)
162
164{
165 uint16_t command_id;
166 uint8_t config_flags;
167 // the IN report rate of the headset, rate is calculated as `sample_rate / (1 + interval)`
168 uint8_t interval;
169 // sample rate of the IMU, always 1000hz on DK1/DK2, read-only
170 uint16_t sample_rate;
171};
172
173SIZE_ASSERT(struct rift_config_report, 6);
174
176{
177 uint16_t command_id;
178 uint8_t distortion_type;
179 // the horizontal resolution of the display, in pixels
180 uint16_t resolution_x;
181 // the vertical resolution of the display, in pixels
182 uint16_t resolution_y;
183 // width in micrometers
184 uint32_t display_width;
185 // height in micrometers
186 uint32_t display_height;
187 // the vertical center of the display, in micrometers
188 uint32_t center_v;
189 // the separation between the two lenses, in micrometers
190 uint32_t lens_separation;
191 uint32_t lens_distance[2];
192 float distortion[6];
193};
194
195SIZE_ASSERT(struct rift_display_info_report, 55);
196
197#define CATMULL_COEFFICIENTS 11
198#define CHROMATIC_ABBERATION_COEFFEICENT_COUNT 4
199
201{
202 // eye relief setting, in micrometers from front surface of lens
203 uint16_t eye_relief;
204 // the k coeffecients of the distortion
205 uint16_t k[CATMULL_COEFFICIENTS];
206 uint16_t max_r;
207 uint16_t meters_per_tan_angle_at_center;
208 uint16_t chromatic_abberation[CHROMATIC_ABBERATION_COEFFEICENT_COUNT];
209 uint8_t unused[14];
210};
211
212SIZE_ASSERT(struct rift_catmull_rom_distortion_report_data, 50);
213
215{
216 uint16_t command_id;
217 // the amount of distortions on this device
218 uint8_t num_distortions;
219 // the index of this distortion in the devices array
220 uint8_t distortion_idx;
221 // unused bitmask field
222 uint8_t bitmask;
223 // the type of the lenses
224 uint16_t lens_type;
225 // the version of the lens distortion data
226 uint16_t distortion_version;
227
228 union {
229 struct rift_catmull_rom_distortion_report_data lcsv_catmull_rom_10;
230 } data;
231};
232
233SIZE_ASSERT(struct rift_lens_distortion_report, 9 + sizeof(struct rift_catmull_rom_distortion_report_data));
234
236{
237 uint16_t command;
238 uint8_t in_report;
239 uint16_t interval;
240};
241
242SIZE_ASSERT(struct rift_dk2_keepalive_mux_report, 5);
243
244enum rift_display_mode
245{
246 RIFT_DISPLAY_MODE_GLOBAL,
247 RIFT_DISPLAY_MODE_ROLLING_TOP_BOTTOM,
248 RIFT_DISPLAY_MODE_ROLLING_LEFT_RIGHT,
249 RIFT_DISPLAY_MODE_ROLLING_RIGHT_LEFT,
250};
251
252enum rift_display_limit
253{
254 RIFT_DISPLAY_LIMIT_ACL_OFF = 0,
255 RIFT_DISPLAY_LIMIT_ACL_30 = 1,
256 RIFT_DISPLAY_LIMIT_ACL_25 = 2,
257 RIFT_DISPLAY_LIMIT_ACL_50 = 3,
258};
259
260enum rift_display_flags
261{
262 RIFT_DISPLAY_USE_ROLLING = 1 << 6,
263 RIFT_DISPLAY_REVERSE_ROLLING = 1 << 7,
264 RIFT_DISPLAY_HIGH_BRIGHTNESS = 1 << 8,
265 RIFT_DISPLAY_SELF_REFRESH = 1 << 9,
266 RIFT_DISPLAY_READ_PIXEL = 1 << 10,
267 RIFT_DISPLAY_DIRECT_PENTILE = 1 << 11,
268};
269
271{
272 uint16_t command_id;
273 // relative brightness setting independent of pixel persistence, only effective when high brightness is disabled
274 uint8_t brightness;
275 // a set of flags, ordered from LSB -> MSB
276 // - panel mode/shutter type (4 bits), read only, see rift_display_mode
277 // - current limit (2 bits), see rift_display_limit
278 // - use rolling (1 bit)
279 // - reverse rolling (1 bit), unavailable on released DK2 firmware for unknown reason
280 // - high brightness (1 bit), unavailable on released DK2 firmware for unpublished reason
281 // - self refresh (1 bit)
282 // - read pixel (1 bit)
283 // - direct pentile (1 bit)
284 uint32_t flags;
285 // the length of time in rows that the display is lit each frame, defaults to the full size of the display, full
286 // persistence
287 uint16_t persistence;
288 // the offset in rows from vsync that the panel is lit when using global shutter, no effect in rolling shutter,
289 // disabled on released DK2 firmware for unknown reason
290 uint16_t lighting_offset;
291 // the time in microseconds it is estimated for a pixel to settle to one value after it is set, read only
292 uint16_t pixel_settle;
293 // the number of rows including active area and blanking period used with persistence and lightingoffset, read
294 // only
295 uint16_t total_rows;
296};
297
298SIZE_ASSERT(struct rift_display_report, 15);
299
301{
302 uint8_t data[8];
303};
304
305SIZE_ASSERT(struct rift_dk2_sensor_sample, 8);
306
308{
309 struct rift_dk2_sensor_sample accel;
310 struct rift_dk2_sensor_sample gyro;
311};
312
313SIZE_ASSERT(struct rift_dk2_sample_pack, sizeof(struct rift_dk2_sensor_sample) * 2);
314
316{
317 int16_t mag_x;
318 int16_t mag_y;
319 int16_t mag_z;
320};
321
322SIZE_ASSERT(struct rift_dk2_version_data, 6);
323
325{
326 uint16_t presence_sensor;
327 uint16_t iad_adc_value;
328 uint16_t unk;
329};
330
331SIZE_ASSERT(struct rift_cv1_version_data, 6);
332static_assert(sizeof(struct rift_cv1_version_data) == sizeof(struct rift_dk2_version_data),
333 "Incorrect version data size");
334
335#define DK2_MAX_SAMPLES 2
337{
338 uint16_t command_id;
339 uint8_t num_samples;
340 uint16_t sample_count;
341 uint16_t temperature;
342 uint32_t sample_timestamp;
343 struct rift_dk2_sample_pack samples[DK2_MAX_SAMPLES];
344 union {
345 struct rift_dk2_version_data dk2;
346 struct rift_cv1_version_data cv1;
347 };
348 uint16_t frame_count;
349 uint32_t frame_timestamp;
350 uint8_t frame_id;
351 uint8_t tracking_pattern;
352 uint16_t tracking_count;
353 uint32_t tracking_timestamp;
354};
355
356SIZE_ASSERT(struct dk2_in_report, 63);
357
359{
360 uint16_t command_id;
361 // which components to enable, see rift_component_flags
362 uint8_t flags;
363};
364
365SIZE_ASSERT(struct rift_enable_components_report, 3);
366
368{
369 uint16_t command_id;
370 struct rift_dk2_sample_pack offset;
371 struct rift_dk2_sample_pack matrix_samples[3];
372 uint16_t temperature;
373};
374
375SIZE_ASSERT(struct rift_imu_calibration_report, sizeof(struct rift_dk2_sample_pack) * 4 + 4);
376
377enum rift_radio_read_cmd
378{
379 RIFT_RADIO_READ_CMD_FLASH_CONTROL = 0x0a,
380 RIFT_RADIO_READ_CMD_SERIAL = 0x88,
381};
382
384{
385 uint16_t command_id;
386 uint8_t a;
387 uint8_t b;
388 uint8_t c;
389};
390
391SIZE_ASSERT(struct rift_radio_cmd_report, 5);
392
394{
395 uint16_t command_id;
396 uint16_t offset;
397 uint16_t length;
398 uint8_t unk[28];
399};
400
401SIZE_ASSERT(struct rift_radio_data_read_cmd, 34);
402
404{
405 uint8_t unk[5];
406 __le16 data_length;
407};
408SIZE_ASSERT(struct rift_radio_flash_read_response_header, 7);
409
411{
412 uint16_t command_id;
413 uint8_t radio_address[5];
414};
415
416SIZE_ASSERT(struct rift_radio_address_radio_report, 7);
417
418enum rift_radio_report_remote_button_masks
419{
420 RIFT_REMOTE_BUTTON_MASK_DPAD_UP = 0x001,
421 RIFT_REMOTE_BUTTON_MASK_DPAD_DOWN = 0x002,
422 RIFT_REMOTE_BUTTON_MASK_DPAD_LEFT = 0x004,
423 RIFT_REMOTE_BUTTON_MASK_DPAD_RIGHT = 0x008,
424 RIFT_REMOTE_BUTTON_MASK_SELECT = 0x010,
425 RIFT_REMOTE_BUTTON_MASK_VOLUME_UP = 0x020,
426 RIFT_REMOTE_BUTTON_MASK_VOLUME_DOWN = 0x040,
427 RIFT_REMOTE_BUTTON_MASK_OCULUS = 0x080,
428 RIFT_REMOTE_BUTTON_MASK_BACK = 0x100,
429};
430
432{
433 // the button state of the controller, see rift_radio_report_remote_button_masks
434 uint16_t buttons;
435};
436
437SIZE_ASSERT(struct rift_radio_report_remote_message, 2);
438
439enum rift_radio_report_touch_buttons
440{
441 RIFT_TOUCH_CONTROLLER_BUTTON_A = 0x01,
442 RIFT_TOUCH_CONTROLLER_BUTTON_X = 0x01,
443 RIFT_TOUCH_CONTROLLER_BUTTON_B = 0x02,
444 RIFT_TOUCH_CONTROLLER_BUTTON_Y = 0x02,
445 RIFT_TOUCH_CONTROLLER_BUTTON_MENU = 0x04,
446 RIFT_TOUCH_CONTROLLER_BUTTON_OCULUS = 0x04,
447 RIFT_TOUCH_CONTROLLER_BUTTON_STICK = 0x08,
448};
449
451{
452 uint32_t timestamp;
453 int16_t accel[3];
454 int16_t gyro[3];
455 uint8_t buttons;
456 uint8_t touch_grip_stick_state[5];
457 // see rift_radio_report_adc_channel
458 uint8_t adc_channel;
459 uint16_t adc_value;
460};
461
462SIZE_ASSERT(struct rift_radio_report_touch_message, 25);
463
464enum rift_radio_device_type
465{
466 RIFT_RADIO_DEVICE_REMOTE = 1,
467 RIFT_RADIO_DEVICE_LEFT_TOUCH = 2,
468 RIFT_RADIO_DEVICE_RIGHT_TOUCH = 3,
469 RIFT_RADIO_DEVICE_TRACKED_OBJECT = 6,
470};
471
473{
474 uint16_t flags;
475 // the type of device sending the message, see rift_radio_device_type
476 uint8_t device_type;
477 union {
480 };
481};
482
483SIZE_ASSERT(struct rift_radio_report_message, 3 + sizeof(struct rift_radio_report_touch_message));
484
486{
487 uint16_t command_id;
488 struct rift_radio_report_message messages[2];
489};
490
491#pragma pack(pop)
492
493/*
494 *
495 * Parsed structs for internal use
496 *
497 */
498
500{
501 // the k coeffecients of the distortion
502 float k[CATMULL_COEFFICIENTS];
503 float max_r;
504 float meters_per_tan_angle_at_center;
505 float chromatic_abberation[CHROMATIC_ABBERATION_COEFFEICENT_COUNT];
506};
507
509{
510 // the version of the lens distortion data
511 uint16_t distortion_version;
512 // eye relief setting, in meters from surface of lens
513 float eye_relief;
514
515 union {
516 struct rift_catmull_rom_distortion_data lcsv_catmull_rom_10;
517 } data;
518};
519
521{
522 struct xrt_vec2 scale;
523 struct xrt_vec2 offset;
524};
525
527{
528 float up_tan;
529 float down_tan;
530 float left_tan;
531 float right_tan;
532};
533
535{
536 // gap left between the two eyes
537 float screen_gap_meters;
538 // the diameter of the lenses, may need to be extended to an array
539 float lens_diameter_meters;
540 // ipd of the headset
541 float icd;
542
543 // the fov of the headset
544 struct rift_viewport_fov_tan fov;
545 // mapping from tan-angle space to target NDC space
546 struct rift_scale_and_offset eye_to_source_ndc;
547 struct rift_scale_and_offset eye_to_source_uv;
548};
549
551{
552 struct xrt_vec3 gyro_offset;
553 struct xrt_vec3 accel_offset;
554 struct xrt_matrix_3x3 gyro_matrix;
555 struct xrt_matrix_3x3 accel_matrix;
556 float temperature;
557};
558
559enum rift_touch_controller_input
560{
561 // left
562 RIFT_TOUCH_CONTROLLER_INPUT_X_CLICK = 0,
563 RIFT_TOUCH_CONTROLLER_INPUT_X_TOUCH = 1,
564 RIFT_TOUCH_CONTROLLER_INPUT_Y_CLICK = 2,
565 RIFT_TOUCH_CONTROLLER_INPUT_Y_TOUCH = 3,
566 RIFT_TOUCH_CONTROLLER_INPUT_SYSTEM_CLICK = 4,
567 // right
568 RIFT_TOUCH_CONTROLLER_INPUT_A_CLICK = 0,
569 RIFT_TOUCH_CONTROLLER_INPUT_A_TOUCH = 1,
570 RIFT_TOUCH_CONTROLLER_INPUT_B_CLICK = 2,
571 RIFT_TOUCH_CONTROLLER_INPUT_B_TOUCH = 3,
572 RIFT_TOUCH_CONTROLLER_INPUT_MENU_CLICK = 4,
573 // both
574 RIFT_TOUCH_CONTROLLER_INPUT_SQUEEZE_VALUE = 5,
575 RIFT_TOUCH_CONTROLLER_INPUT_TRIGGER_TOUCH = 6,
576 RIFT_TOUCH_CONTROLLER_INPUT_TRIGGER_VALUE = 7,
577 RIFT_TOUCH_CONTROLLER_INPUT_THUMBSTICK_CLICK = 8,
578 RIFT_TOUCH_CONTROLLER_INPUT_THUMBSTICK_TOUCH = 9,
579 RIFT_TOUCH_CONTROLLER_INPUT_THUMBSTICK = 10,
580 RIFT_TOUCH_CONTROLLER_INPUT_THUMBREST_TOUCH = 11,
581 RIFT_TOUCH_CONTROLLER_INPUT_GRIP_POSE = 12,
582 RIFT_TOUCH_CONTROLLER_INPUT_AIM_POSE = 13,
583 RIFT_TOUCH_CONTROLLER_INPUT_TRIGGER_PROXIMITY = 14,
584 RIFT_TOUCH_CONTROLLER_INPUT_THUMB_PROXIMITY = 15,
585 RIFT_TOUCH_CONTROLLER_INPUT_COUNT = 16,
586};
587
589{
590 struct xrt_vec3 position;
591 struct xrt_vec3 normal;
592 struct xrt_vec3 angles;
593};
594
596{
597 uint16_t joy_x_range[2];
598 uint16_t joy_x_dead[2];
599 uint16_t joy_y_range[2];
600 uint16_t joy_y_dead[2];
601
602 // min - mid - max
603 uint16_t trigger_range[3];
604
605 // min - mid - max
606 uint16_t middle_range[3];
607 bool middle_flipped;
608
609 uint16_t cap_sense_min[8];
610 uint16_t cap_sense_touch[8];
611
612 float gyro_calibration[3][3];
613 struct xrt_vec3 gyro_offset;
614 float accel_calibration[3][3];
615 struct xrt_vec3 accel_offset;
616
617 struct xrt_vec3 imu_position;
618
619 size_t num_leds;
620 struct rift_touch_controller_led *leds;
621};
622
624{
625 uint8_t buttons;
626 float trigger;
627 float grip;
628 float stick[2];
629 uint8_t haptic_counter;
630 float cap_stick;
631 float cap_b_y;
632 float cap_a_x;
633 float cap_trigger;
634 float cap_thumbrest;
635};
636
637/*!
638 * A Rift Touch controller device.
639 *
640 * @implements xrt_device
641 */
643{
644 struct xrt_device base;
645
646 struct rift_hmd *hmd;
647
648 enum rift_radio_device_type device_type;
649
650 struct
651 {
652 bool mutex_created;
653 struct os_mutex mutex;
654
656
657 bool calibration_read;
658 struct rift_touch_controller_calibration calibration;
659 } input;
660
661
662 //! Locked by radio_state.thread
663 struct
664 {
665 bool serial_valid;
666
667 uint8_t calibration_hash[CALIBRATION_HASH_BYTE_LENGTH];
668
669 uint8_t calibration_data_buffer[CALIBRATION_BODY_BYTE_CHUNK_LENGTH];
670
671 uint8_t *calibration_body_json;
672 uint16_t calibration_body_json_length;
673
675};
676
677enum rift_remote_inputs
678{
679 RIFT_REMOTE_INPUT_DPAD_UP,
680 RIFT_REMOTE_INPUT_DPAD_DOWN,
681 RIFT_REMOTE_INPUT_DPAD_LEFT,
682 RIFT_REMOTE_INPUT_DPAD_RIGHT,
683 RIFT_REMOTE_INPUT_SELECT,
684 RIFT_REMOTE_INPUT_VOLUME_UP,
685 RIFT_REMOTE_INPUT_VOLUME_DOWN,
686 RIFT_REMOTE_INPUT_BACK,
687 RIFT_REMOTE_INPUT_OCULUS,
688 RIFT_REMOTE_INPUT_COUNT,
689};
690
691/*!
692 * A Rift Remote device.
693 *
694 * @implements xrt_device
695 */
697{
698 struct xrt_device base;
699
700 //! The button state of the remote, stored as an atomic to avoid needing a mutex.
701 xrt_atomic_s32_t buttons;
702
703 //! Locked by radio_state.thread
705};
706
707enum rift_radio_command
708{
709 RIFT_RADIO_COMMAND_NONE = 0,
710 RIFT_RADIO_COMMAND_READ_SERIAL,
711 RIFT_RADIO_COMMAND_READ_FLASH,
712};
713
715{
716 //! A pointer to store the serial string. Must contain at least SERIAL_NUMBER_LENGTH bytes.
717 char *serial;
718 //! A pointer to store when reading the serial was successful.
720};
721
722typedef int (*flash_read_callback_t)(void *user_data, uint16_t address, uint16_t length);
723
725{
726 void *user_data;
727
728 uint16_t address;
729 uint16_t length;
730
731 uint8_t *buffer;
732
733 flash_read_callback_t read_callback;
734};
735
737 struct rift_radio_command_data_read_serial read_serial;
738 struct rift_radio_command_data_read_flash read_flash;
739};
740
741/*!
742 * A rift HMD device.
743 *
744 * @implements xrt_device
745 */
747{
748 struct xrt_device base;
749
750 enum u_logging_level log_level;
751
752 // has built-in mutex so thread safe
753 struct m_relation_history *relation_hist;
754
755 struct os_hid_device *hmd_dev;
756 struct os_hid_device *radio_dev;
757
758 struct os_thread_helper sensor_thread;
759 bool processed_sample_packet;
760 uint32_t last_remote_sample_time_us;
761 timepoint_ns last_remote_sample_time_ns;
762 timepoint_ns last_sample_local_timestamp_ns;
763
764 struct m_imu_3dof fusion;
765 struct m_clock_windowed_skew_tracker *clock_tracker;
766
767 timepoint_ns last_keepalive_time;
768 enum rift_variant variant;
769 struct rift_config_report config;
771
772 const struct rift_lens_distortion *lens_distortions;
773 uint16_t num_lens_distortions;
774 uint16_t distortion_in_use;
775
776 struct rift_extra_display_info extra_display_info;
777 float icd_override_m;
778
779 bool presence;
780
781 bool imu_needs_calibration;
782 struct rift_imu_calibration imu_calibration;
783
784 uint8_t radio_address[5];
785
786 //! Mutex to protect access to the device array, device count == -1 means uninitialized
788
789 int device_count;
790 int added_devices;
791 struct xrt_device *devices[4]; // left touch, right touch, tracked object, remote
792
793 //! Generic state for the radio state machine
794 struct
795 {
797
798 struct rift_touch_controller *touch_controllers[3];
799 struct rift_remote *remote;
800
801 enum rift_radio_command current_command;
802 union rift_radio_command_data command_data;
804};
805
806/// Casting helper function
807static inline struct rift_hmd *
808rift_hmd(struct xrt_device *xdev)
809{
810 return (struct rift_hmd *)xdev;
811}
812
813static inline struct rift_touch_controller *
815{
816 return (struct rift_touch_controller *)xdev;
817}
818
819static inline struct rift_remote *
820rift_remote(struct xrt_device *xdev)
821{
822 return (struct rift_remote *)xdev;
823}
824
825static inline size_t
826rift_radio_device_type_to_touch_index(enum rift_radio_device_type device_type)
827{
828 switch (device_type) {
829 case RIFT_RADIO_DEVICE_LEFT_TOUCH: return 0;
830 case RIFT_RADIO_DEVICE_RIGHT_TOUCH: return 1;
831 case RIFT_RADIO_DEVICE_TRACKED_OBJECT: return 2;
832 default: assert(false);
833 }
834
835 return -1;
836}
837
838static inline enum rift_radio_device_type
839rift_radio_touch_index_to_device_type(size_t index)
840{
841 switch (index) {
842 case 0: return RIFT_RADIO_DEVICE_LEFT_TOUCH;
843 case 1: return RIFT_RADIO_DEVICE_RIGHT_TOUCH;
844 case 2: return RIFT_RADIO_DEVICE_TRACKED_OBJECT;
845 default: assert(false);
846 }
847
848 return (enum rift_radio_device_type)0;
849}
850
851bool
852rift_touch_calibration_parse(const char *calibration_data,
853 size_t calibration_size,
854 struct rift_touch_controller_calibration *out_calibration);
855
856#ifdef __cplusplus
857} // extern "C"
858#endif
u_logging_level
Logging level enum.
Definition: u_logging.h:45
int64_t timepoint_ns
Integer timestamp type.
Definition: u_time.h:77
C interface to math library.
A IMU fusion specially made for 3dof devices.
Wrapper header for <math.h> to ensure pi-related math constants are defined.
static Eigen::Map< const Eigen::Vector3f > position(const struct xrt_pose &pose)
Return a Eigen type wrapping a pose's position (const).
Definition: m_eigen_interop.hpp:217
Wrapper around OS native hid functions.
Wrapper around OS threading native functions.
Interface to Oculus Rift driver code.
static struct rift_hmd * rift_hmd(struct xrt_device *xdev)
Casting helper function.
Definition: rift_internal.h:808
Definition: oh_device.c:483
Definition: rift_internal.h:337
Definition: m_space.cpp:87
Definition: m_clock_tracking.c:35
Definition: m_imu_3dof.h:35
Definition: m_relation_history.cpp:49
Representing a single hid interface on a device.
Definition: os_hid.h:29
A wrapper around a native mutex.
Definition: os_threading.h:69
All in one helper that handles locking, waiting for change and starting a thread.
Definition: os_threading.h:499
Definition: rift_internal.h:500
Definition: rift_internal.h:201
Definition: rift_internal.h:164
Definition: rift_internal.h:325
Definition: rift_internal.h:176
Definition: rift_internal.h:271
Definition: rift_internal.h:236
Definition: rift_internal.h:308
Definition: rift_internal.h:301
Definition: rift_internal.h:316
Definition: rift_internal.h:359
Definition: rift_internal.h:535
A rift HMD device.
Definition: rift_internal.h:747
struct os_mutex device_mutex
Mutex to protect access to the device array, device count == -1 means uninitialized.
Definition: rift_internal.h:787
struct rift_hmd::@180 radio_state
Generic state for the radio state machine.
Definition: rift_internal.h:368
Definition: rift_internal.h:551
Definition: rift_internal.h:215
Definition: rift_internal.h:509
Definition: rift_internal.h:411
Definition: rift_internal.h:384
Definition: rift_internal.h:725
Definition: rift_internal.h:715
char * serial
A pointer to store the serial string. Must contain at least SERIAL_NUMBER_LENGTH bytes.
Definition: rift_internal.h:717
bool * serial_valid
A pointer to store when reading the serial was successful.
Definition: rift_internal.h:719
Definition: rift_internal.h:394
Definition: rift_internal.h:404
Definition: rift_internal.h:473
Definition: rift_internal.h:432
Definition: rift_internal.h:451
Definition: rift_internal.h:486
A Rift Remote device.
Definition: rift_internal.h:697
xrt_atomic_s32_t buttons
The button state of the remote, stored as an atomic to avoid needing a mutex.
Definition: rift_internal.h:701
bool serial_valid
Locked by radio_state.thread.
Definition: rift_internal.h:704
Definition: rift_internal.h:521
Definition: rift_internal.h:596
Definition: rift_internal.h:624
Definition: rift_internal.h:589
A Rift Touch controller device.
Definition: rift_internal.h:643
struct rift_touch_controller::@179 radio_data
Locked by radio_state.thread.
Definition: rift_internal.h:527
Definition: u_worker.c:38
A single HMD or input device.
Definition: xrt_device.h:310
struct xrt_hmd_parts * hmd
Null if this device does not interface with the users head.
Definition: xrt_device.h:322
A tightly packed 3x3 matrix of floats.
Definition: xrt_defines.h:546
A 2 element vector with single floats.
Definition: xrt_defines.h:268
A 3 element vector with single floats.
Definition: xrt_defines.h:289
Misc helpers for device drivers.
Basic logging functionality.
Definition: rift_internal.h:736
Endian-specific byte order defines.