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