The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

d/dd: Add Daydream driver

authored by

Pete Black and committed by
Ryan Pavlik
b6613db5 6b4ec70d

+827 -3
+5 -1
CMakeLists.txt
··· 99 99 option(BUILD_WITH_NS "Enable North Star driver" ON) 100 100 101 101 # You can set this from a superproject to add a driver 102 - list(APPEND AVAILABLE_DRIVERS DUMMY HDK HYDRA NS OHMD PSMV PSVR RS V4L2 VIVE) 102 + list(APPEND AVAILABLE_DRIVERS DUMMY HDK HYDRA NS OHMD PSMV PSVR RS V4L2 VIVE DAYDREAM) 103 103 104 104 ### 105 105 # Flags ··· 197 197 198 198 if(BUILD_WITH_HYDRA) 199 199 set(BUILD_DRIVER_HYDRA TRUE) 200 + endif() 201 + 202 + if(BUILD_WITH_DAYDREAM) 203 + set(BUILD_DRIVER_DAYDREAM TRUE) 200 204 endif() 201 205 202 206
+13 -1
src/xrt/drivers/CMakeLists.txt
··· 5 5 set(ENABLED_HEADSET_DRIVERS) 6 6 set(ENABLED_DRIVERS) 7 7 8 + if(BUILD_DRIVER_DAYDREAM) 9 + set(DAYDREAM_SOURCE_FILES 10 + daydream/daydream_device.c 11 + daydream/daydream_device.h 12 + daydream/daydream_interface.h 13 + daydream/daydream_prober.c 14 + ) 15 + 16 + add_library(drv_daydream STATIC ${DAYDREAM_SOURCE_FILES}) 17 + target_link_libraries(drv_daydream PRIVATE xrt-interfaces aux_util aux_os) 18 + list(APPEND ENABLED_DRIVERS daydream) 19 + endif() 20 + 8 21 if(BUILD_DRIVER_DUMMY) 9 22 set(DUMMY_SOURCE_FILES 10 23 dummy/dummy_hmd.c ··· 82 95 target_link_libraries(drv_psmv PRIVATE xrt-interfaces PUBLIC aux_os aux_tracking) 83 96 list(APPEND ENABLED_DRIVERS psmv) 84 97 endif() 85 - 86 98 87 99 if(BUILD_DRIVER_PSVR) 88 100 set(PSVR_SOURCE_FILES
+433
src/xrt/drivers/daydream/daydream_device.c
··· 1 + // Copyright 2019-2020, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Daydream controller code. 6 + * @author Pete Black <pete.black@collabora.com> 7 + * @author Jakob Bornecrantz <jakob@collabora.com> 8 + * @ingroup drv_daydream 9 + */ 10 + 11 + #include "xrt/xrt_prober.h" 12 + #include "xrt/xrt_tracking.h" 13 + 14 + #include "os/os_time.h" 15 + 16 + #include "math/m_api.h" 17 + #include "tracking/t_imu.h" 18 + 19 + #include "util/u_var.h" 20 + #include "util/u_time.h" 21 + #include "util/u_misc.h" 22 + #include "util/u_debug.h" 23 + #include "util/u_device.h" 24 + #include "util/u_bitwise.h" 25 + 26 + #include "daydream_device.h" 27 + 28 + #include <stdio.h> 29 + #include <math.h> 30 + #include <assert.h> 31 + 32 + 33 + /*! 34 + * Indices where each input is in the input list. 35 + */ 36 + enum daydream_input_index 37 + { 38 + DAYDREAM_TOUCHPAD_CLICK, 39 + DAYDREAM_BAR_CLICK, 40 + DAYDREAM_CIRCLE_CLICK, 41 + DAYDREAM_VOLUP_CLICK, 42 + DAYDREAM_VOLDN_CLICK, 43 + DAYDREAM_TOUCHPAD_POSX, 44 + DAYDREAM_TOUCHPAD_POSY, 45 + 46 + }; 47 + 48 + /*! 49 + * Input package for Daydream. 50 + */ 51 + struct daydream_input_packet 52 + { 53 + uint8_t data[20]; 54 + }; 55 + 56 + 57 + /* 58 + * 59 + * Smaller helper functions. 60 + * 61 + */ 62 + 63 + static inline struct daydream_device * 64 + daydream_device(struct xrt_device *xdev) 65 + { 66 + return (struct daydream_device *)xdev; 67 + } 68 + 69 + static void 70 + daydream_update_input_click(struct daydream_device *daydream, 71 + int index, 72 + int64_t now, 73 + uint32_t bit) 74 + { 75 + 76 + daydream->base.inputs[index].timestamp = now; 77 + daydream->base.inputs[index].value.boolean = 78 + (daydream->last.buttons & bit) != 0; 79 + } 80 + 81 + 82 + /* 83 + * 84 + * Internal functions. 85 + * 86 + */ 87 + 88 + static void 89 + update_fusion(struct daydream_device *daydream, 90 + struct daydream_parsed_sample *sample, 91 + timepoint_ns timestamp_ns, 92 + time_duration_ns delta_ns) 93 + { 94 + DAYDREAM_DEBUG(daydream, 95 + "fusion sample mx %d my %d mz %d ax %d ay %d az %d gx " 96 + "%d gy %d gz %d\n", 97 + sample->mag.x, sample->mag.y, sample->mag.z, 98 + sample->accel.x, sample->accel.y, sample->accel.z, 99 + sample->gyro.x, sample->gyro.y, sample->gyro.z); 100 + 101 + 102 + daydream->read.accel.x = 103 + (sample->accel.x - daydream->calibration.accel.bias.x) / 104 + daydream->calibration.accel.factor.x * MATH_GRAVITY_M_S2; 105 + daydream->read.accel.y = 106 + (sample->accel.y - daydream->calibration.accel.bias.y) / 107 + daydream->calibration.accel.factor.y * MATH_GRAVITY_M_S2; 108 + daydream->read.accel.z = 109 + (sample->accel.z - daydream->calibration.accel.bias.z) / 110 + daydream->calibration.accel.factor.z * MATH_GRAVITY_M_S2; 111 + 112 + daydream->read.gyro.x = 113 + (sample->gyro.x - daydream->calibration.gyro.bias.x) / 114 + daydream->calibration.gyro.factor.x; 115 + daydream->read.gyro.y = 116 + (sample->gyro.y - daydream->calibration.gyro.bias.y) / 117 + daydream->calibration.gyro.factor.y; 118 + daydream->read.gyro.z = 119 + (sample->gyro.z - daydream->calibration.gyro.bias.z) / 120 + daydream->calibration.gyro.factor.z; 121 + DAYDREAM_DEBUG( 122 + daydream, 123 + "fusion calibrated sample ax %f ay %f az %f gx %f gy %f gz %f\n", 124 + daydream->read.accel.x, daydream->read.accel.y, 125 + daydream->read.accel.z, daydream->read.gyro.x, 126 + daydream->read.gyro.y, daydream->read.gyro.z); 127 + 128 + math_quat_integrate_velocity(&daydream->fusion.rot, 129 + &daydream->read.gyro, delta_ns, 130 + &daydream->fusion.rot); 131 + 132 + /* 133 + imu_fusion_incorporate_gyros_and_accelerometer( 134 + daydream->fusion.fusion, timestamp_ns, &daydream->read.gyro, 135 + &daydream->fusion.variance.gyro, &daydream->read.accel, 136 + &daydream->fusion.variance.accel, NULL); 137 + struct xrt_vec3 angvel_dummy; 138 + imu_fusion_get_prediction(daydream->fusion.fusion, timestamp_ns, 139 + &daydream->fusion.rot, &angvel_dummy); 140 + imu_fusion_get_prediction_rotation_vec( 141 + daydream->fusion.fusion, timestamp_ns, 142 + &daydream->fusion.rotvec); 143 + */ 144 + } 145 + 146 + static int 147 + daydream_parse_input(struct daydream_device *daydream, 148 + void *data, 149 + struct daydream_parsed_input *input) 150 + { 151 + U_ZERO(input); 152 + unsigned char *b = (unsigned char *)data; 153 + DAYDREAM_DEBUG( 154 + daydream, 155 + "raw input: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x " 156 + "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 157 + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], 158 + b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]); 159 + input->timestamp = get_bits(b, 0, 14); 160 + input->sample.mag.x = sign_extend_13(get_bits(b, 14, 13)); 161 + input->sample.mag.y = sign_extend_13(get_bits(b, 27, 13)); 162 + input->sample.mag.z = sign_extend_13(get_bits(b, 40, 13)); 163 + input->sample.accel.x = sign_extend_13(get_bits(b, 53, 13)); 164 + input->sample.accel.y = sign_extend_13(get_bits(b, 66, 13)); 165 + input->sample.accel.z = sign_extend_13(get_bits(b, 79, 13)); 166 + input->sample.gyro.x = sign_extend_13(get_bits(b, 92, 13)); 167 + input->sample.gyro.y = sign_extend_13(get_bits(b, 105, 13)); 168 + input->sample.gyro.z = sign_extend_13(get_bits(b, 118, 13)); 169 + input->touchpad.x = get_bits(b, 131, 8); 170 + input->touchpad.y = get_bits(b, 139, 8); 171 + input->buttons |= get_bit(b, 147) << DAYDREAM_VOLUP_BUTTON_BIT; 172 + input->buttons |= get_bit(b, 148) << DAYDREAM_VOLDN_BUTTON_BIT; 173 + input->buttons |= get_bit(b, 149) << DAYDREAM_CIRCLE_BUTTON_BIT; 174 + input->buttons |= get_bit(b, 150) << DAYDREAM_BAR_BUTTON_BIT; 175 + input->buttons |= get_bit(b, 151) << DAYDREAM_TOUCHPAD_BUTTON_BIT; 176 + // DAYDREAM_DEBUG(daydream,"touchpad: %d %dx\n", 177 + // input->touchpad.x,input->touchpad.y); 178 + 179 + daydream->last = *input; 180 + return 1; 181 + } 182 + 183 + /*! 184 + * Reads one packet from the device,handles locking and checking if 185 + * the thread has been told to shut down. 186 + */ 187 + static bool 188 + daydream_read_one_packet(struct daydream_device *daydream, 189 + uint8_t *buffer, 190 + size_t size) 191 + { 192 + os_thread_helper_lock(&daydream->oth); 193 + 194 + while (os_thread_helper_is_running_locked(&daydream->oth)) { 195 + int retries = 5; 196 + int ret = -1; 197 + os_thread_helper_unlock(&daydream->oth); 198 + 199 + while (retries > 0) { 200 + ret = os_ble_read(daydream->ble, buffer, size, 500); 201 + if (ret == (int)size) { 202 + break; 203 + } 204 + retries--; 205 + } 206 + if (ret == 0) { 207 + fprintf(stderr, "%s\n", __func__); 208 + // Must lock thread before check in while. 209 + os_thread_helper_lock(&daydream->oth); 210 + continue; 211 + } 212 + if (ret < 0) { 213 + DAYDREAM_ERROR(daydream, "Failed to read device '%i'!", 214 + ret); 215 + return false; 216 + } 217 + return true; 218 + } 219 + 220 + return false; 221 + } 222 + 223 + static void * 224 + daydream_run_thread(void *ptr) 225 + { 226 + struct daydream_device *daydream = (struct daydream_device *)ptr; 227 + //! @todo this should be injected at construction time 228 + struct time_state *time = time_state_create(); 229 + 230 + uint8_t buffer[20]; 231 + struct daydream_parsed_input input; // = {0}; 232 + 233 + // wait for a package to sync up, it's discarded but that's okay. 234 + if (!daydream_read_one_packet(daydream, buffer, 20)) { 235 + // Does null checking and sets to null. 236 + time_state_destroy(&time); 237 + return NULL; 238 + } 239 + 240 + timepoint_ns then_ns = time_state_get_now(time); 241 + while (daydream_read_one_packet(daydream, buffer, 20)) { 242 + 243 + timepoint_ns now_ns = time_state_get_now(time); 244 + 245 + int num = daydream_parse_input(daydream, buffer, &input); 246 + (void)num; 247 + 248 + time_duration_ns delta_ns = now_ns - then_ns; 249 + then_ns = now_ns; 250 + 251 + // Lock last and the fusion. 252 + os_mutex_lock(&daydream->lock); 253 + 254 + 255 + // Process the parsed data. 256 + update_fusion(daydream, &input.sample, now_ns, delta_ns); 257 + 258 + // Now done. 259 + os_mutex_unlock(&daydream->lock); 260 + } 261 + 262 + // Does null checking and sets to null. 263 + time_state_destroy(&time); 264 + 265 + return NULL; 266 + } 267 + 268 + static int 269 + daydream_get_calibration(struct daydream_device *daydream) 270 + { 271 + return 0; 272 + } 273 + 274 + 275 + /* 276 + * 277 + * Device functions. 278 + * 279 + */ 280 + 281 + static void 282 + daydream_get_fusion_pose(struct daydream_device *daydream, 283 + enum xrt_input_name name, 284 + timepoint_ns when, 285 + struct xrt_space_relation *out_relation) 286 + { 287 + out_relation->pose.orientation = daydream->fusion.rot; 288 + 289 + //! @todo assuming that orientation is actually currently tracked. 290 + out_relation->relation_flags = (enum xrt_space_relation_flags)( 291 + XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | 292 + XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT); 293 + } 294 + 295 + static void 296 + daydream_device_destroy(struct xrt_device *xdev) 297 + { 298 + struct daydream_device *daydream = daydream_device(xdev); 299 + 300 + // Destroy the thread object. 301 + os_thread_helper_destroy(&daydream->oth); 302 + 303 + // Now that the thread is not running we can destroy the lock. 304 + os_mutex_destroy(&daydream->lock); 305 + 306 + // Destroy the IMU fusion. 307 + imu_fusion_destroy(daydream->fusion.fusion); 308 + 309 + // Remove the variable tracking. 310 + u_var_remove_root(daydream); 311 + 312 + // Does null checking and zeros. 313 + os_ble_destroy(&daydream->ble); 314 + 315 + free(daydream); 316 + } 317 + 318 + static void 319 + daydream_device_update_inputs(struct xrt_device *xdev, 320 + struct time_state *timekeeping) 321 + { 322 + struct daydream_device *daydream = daydream_device(xdev); 323 + 324 + int64_t now = time_state_get_now(timekeeping); 325 + 326 + // Lock the data. 327 + os_mutex_lock(&daydream->lock); 328 + 329 + // clang-format off 330 + daydream_update_input_click(daydream, 1, now, DAYDREAM_TOUCHPAD_BUTTON_MASK); 331 + daydream_update_input_click(daydream, 2, now, DAYDREAM_BAR_BUTTON_MASK); 332 + daydream_update_input_click(daydream, 3, now, DAYDREAM_CIRCLE_BUTTON_MASK); 333 + daydream_update_input_click(daydream, 4, now, DAYDREAM_VOLDN_BUTTON_MASK); 334 + daydream_update_input_click(daydream, 5, now, DAYDREAM_VOLUP_BUTTON_MASK); 335 + // clang-format on 336 + 337 + daydream->base.inputs[6].timestamp = now; 338 + daydream->base.inputs[6].value.vec1.x = daydream->last.touchpad.x; 339 + daydream->base.inputs[7].timestamp = now; 340 + daydream->base.inputs[7].value.vec1.x = daydream->last.touchpad.y; 341 + 342 + // Done now. 343 + 344 + os_mutex_unlock(&daydream->lock); 345 + } 346 + 347 + static void 348 + daydream_device_get_tracked_pose(struct xrt_device *xdev, 349 + enum xrt_input_name name, 350 + struct time_state *timekeeping, 351 + int64_t *out_timestamp, 352 + struct xrt_space_relation *out_relation) 353 + { 354 + struct daydream_device *daydream = daydream_device(xdev); 355 + 356 + timepoint_ns now = time_state_get_now(timekeeping); 357 + 358 + daydream_get_fusion_pose(daydream, name, now, out_relation); 359 + } 360 + 361 + 362 + /* 363 + * 364 + * Prober functions. 365 + * 366 + */ 367 + 368 + struct daydream_device * 369 + daydream_device_create(struct os_ble_device *ble, 370 + bool print_spew, 371 + bool print_debug) 372 + { 373 + enum u_device_alloc_flags flags = 374 + (enum u_device_alloc_flags)(U_DEVICE_ALLOC_TRACKING_NONE); 375 + struct daydream_device *dd = 376 + U_DEVICE_ALLOCATE(struct daydream_device, flags, 8, 0); 377 + 378 + dd->print_spew = print_spew; 379 + dd->print_debug = print_debug; 380 + dd->base.name = XRT_DEVICE_DAYDREAM; 381 + dd->base.destroy = daydream_device_destroy; 382 + dd->base.update_inputs = daydream_device_update_inputs; 383 + dd->base.get_tracked_pose = daydream_device_get_tracked_pose; 384 + dd->base.inputs[0].name = XRT_INPUT_DAYDREAM_POSE; 385 + dd->base.inputs[1].name = XRT_INPUT_DAYDREAM_TOUCHPAD_CLICK; 386 + dd->base.inputs[2].name = XRT_INPUT_DAYDREAM_BAR_CLICK; 387 + dd->base.inputs[3].name = XRT_INPUT_DAYDREAM_CIRCLE_CLICK; 388 + dd->base.inputs[4].name = XRT_INPUT_DAYDREAM_VOLDN_CLICK; 389 + dd->base.inputs[5].name = XRT_INPUT_DAYDREAM_VOLUP_CLICK; 390 + dd->base.inputs[6].name = XRT_INPUT_DAYDREAM_TOUCHPAD_VALUE_X; 391 + dd->base.inputs[7].name = XRT_INPUT_DAYDREAM_TOUCHPAD_VALUE_Y; 392 + 393 + dd->ble = ble; 394 + dd->fusion.rot.w = 1.0f; 395 + dd->fusion.fusion = imu_fusion_create(); 396 + dd->fusion.variance.accel.x = 1.0f; 397 + dd->fusion.variance.accel.y = 1.0f; 398 + dd->fusion.variance.accel.z = 1.0f; 399 + dd->fusion.variance.gyro.x = 1.0f; 400 + dd->fusion.variance.gyro.y = 1.0f; 401 + dd->fusion.variance.gyro.z = 1.0f; 402 + 403 + dd->calibration.accel.factor.x = 120000000000.0; 404 + dd->calibration.accel.factor.y = 120000000000.0; 405 + dd->calibration.accel.factor.z = 120000000000.0; 406 + 407 + dd->calibration.accel.bias.x = 0.0; 408 + dd->calibration.accel.bias.y = 0.0; 409 + dd->calibration.accel.bias.z = 0.0; 410 + 411 + dd->calibration.gyro.factor.x = 120000000000.0; 412 + dd->calibration.gyro.factor.y = 120000000000.0; 413 + dd->calibration.gyro.factor.z = 120000000000.0; 414 + 415 + dd->calibration.gyro.bias.x = 0.0; 416 + dd->calibration.gyro.bias.y = 0.0; 417 + dd->calibration.gyro.bias.z = 0.0; 418 + 419 + daydream_get_calibration(dd); 420 + 421 + // Everything done, finally start the thread. 422 + int ret = os_thread_helper_start(&dd->oth, daydream_run_thread, dd); 423 + if (ret != 0) { 424 + DAYDREAM_ERROR(dd, "Failed to start thread!"); 425 + daydream_device_destroy(&dd->base); 426 + return NULL; 427 + } 428 + 429 + 430 + DAYDREAM_DEBUG(dd, "Created device!"); 431 + 432 + return dd; 433 + }
+183
src/xrt/drivers/daydream/daydream_device.h
··· 1 + // Copyright 2019-2020, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Interface to Daydream driver code. 6 + * @author Pete Black <pete.black@collabora.com> 7 + * @ingroup drv_daydream 8 + */ 9 + 10 + #pragma once 11 + 12 + #include "math/m_api.h" 13 + #include "xrt/xrt_device.h" 14 + #include "os/os_threading.h" 15 + #include "os/os_ble.h" 16 + 17 + #ifdef __cplusplus 18 + extern "C" { 19 + #endif 20 + 21 + 22 + /*! 23 + * A parsed sample of accel and gyro. 24 + */ 25 + struct daydream_parsed_sample 26 + { 27 + struct xrt_vec3_i32 accel; 28 + struct xrt_vec3_i32 gyro; 29 + struct xrt_vec3_i32 mag; 30 + }; 31 + 32 + /*! 33 + * A parsed input packet. 34 + */ 35 + /*struct button_data 36 + { 37 + uint8_t volup : 1; 38 + uint8_t voldn : 1; 39 + uint8_t app : 1; 40 + uint8_t home : 1; 41 + uint8_t touchpad : 1; 42 + }; 43 + */ 44 + enum daydream_button_bits 45 + { 46 + DAYDREAM_TOUCHPAD_BUTTON_BIT = 0, 47 + DAYDREAM_CIRCLE_BUTTON_BIT = 1, 48 + DAYDREAM_BAR_BUTTON_BIT = 2, 49 + DAYDREAM_VOLUP_BUTTON_BIT = 3, 50 + DAYDREAM_VOLDN_BUTTON_BIT = 4, 51 + }; 52 + 53 + enum daydream_button_masks 54 + { 55 + DAYDREAM_TOUCHPAD_BUTTON_MASK = 1 << DAYDREAM_TOUCHPAD_BUTTON_BIT, 56 + DAYDREAM_CIRCLE_BUTTON_MASK = 1 << DAYDREAM_CIRCLE_BUTTON_BIT, 57 + DAYDREAM_BAR_BUTTON_MASK = 1 << DAYDREAM_BAR_BUTTON_BIT, 58 + DAYDREAM_VOLUP_BUTTON_MASK = 1 << DAYDREAM_VOLUP_BUTTON_BIT, 59 + DAYDREAM_VOLDN_BUTTON_MASK = 1 << DAYDREAM_VOLDN_BUTTON_BIT, 60 + }; 61 + 62 + struct daydream_parsed_input 63 + { 64 + uint8_t buttons; 65 + int timestamp; 66 + uint16_t timestamp_last; 67 + struct xrt_vec2_i32 touchpad; 68 + struct daydream_parsed_sample sample; 69 + }; 70 + 71 + struct daydream_device 72 + { 73 + struct xrt_device base; 74 + struct os_ble_device *ble; 75 + struct os_thread_helper oth; 76 + char mac[128]; 77 + char path[128]; 78 + 79 + struct 80 + { 81 + //! Lock for last and fusion. 82 + struct os_mutex lock; 83 + 84 + //! Last sensor read. 85 + struct daydream_parsed_input last; 86 + 87 + struct 88 + { 89 + struct xrt_quat rot; 90 + struct xrt_vec3 rotvec; 91 + struct imu_fusion *fusion; 92 + struct 93 + { 94 + struct xrt_vec3 accel; 95 + struct xrt_vec3 gyro; 96 + struct xrt_vec3 mag; 97 + 98 + } variance; 99 + } fusion; 100 + }; 101 + 102 + struct 103 + { 104 + 105 + struct 106 + { 107 + struct xrt_vec3 factor; 108 + struct xrt_vec3 bias; 109 + } accel; 110 + 111 + struct 112 + { 113 + struct xrt_vec3 factor; 114 + struct xrt_vec3 bias; 115 + } gyro; 116 + 117 + struct 118 + { 119 + struct xrt_vec3 factor; 120 + struct xrt_vec3 bias; 121 + } mag; 122 + 123 + 124 + } calibration; 125 + 126 + struct 127 + { 128 + //! Last adjusted accelerator value. 129 + struct xrt_vec3 accel; 130 + //! Last adjusted gyro value. 131 + struct xrt_vec3 gyro; 132 + struct xrt_vec3 mag; 133 + 134 + } read; 135 + 136 + bool print_spew; 137 + bool print_debug; 138 + 139 + struct 140 + { 141 + bool control; 142 + bool calibration; 143 + bool last_frame; 144 + bool fusion; 145 + } gui; 146 + }; 147 + 148 + 149 + struct daydream_device * 150 + daydream_device_create(struct os_ble_device *ble, 151 + bool print_spew, 152 + bool print_debug); 153 + 154 + 155 + #define DAYDREAM_SPEW(c, ...) \ 156 + do { \ 157 + if (c->print_spew) { \ 158 + fprintf(stderr, "%s - ", __func__); \ 159 + fprintf(stderr, __VA_ARGS__); \ 160 + fprintf(stderr, "\n"); \ 161 + } \ 162 + } while (false) 163 + 164 + #define DAYDREAM_DEBUG(c, ...) \ 165 + do { \ 166 + if (c->print_debug) { \ 167 + fprintf(stderr, "%s - ", __func__); \ 168 + fprintf(stderr, __VA_ARGS__); \ 169 + fprintf(stderr, "\n"); \ 170 + } \ 171 + } while (false) 172 + 173 + #define DAYDREAM_ERROR(c, ...) \ 174 + do { \ 175 + fprintf(stderr, "%s - ", __func__); \ 176 + fprintf(stderr, __VA_ARGS__); \ 177 + fprintf(stderr, "\n"); \ 178 + } while (false) 179 + 180 + 181 + #ifdef __cplusplus 182 + } 183 + #endif
+41
src/xrt/drivers/daydream/daydream_interface.h
··· 1 + // Copyright 2019-2020, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Interface to @ref drv_daydream. 6 + * @author Pete Black <pete.black@collabora.com> 7 + * @ingroup drv_daydream 8 + */ 9 + 10 + #pragma once 11 + 12 + #ifdef __cplusplus 13 + extern "C" { 14 + #endif 15 + 16 + /*! 17 + * @defgroup drv_daydream Daydream Controller driver 18 + * @ingroup drv 19 + * 20 + * @brief Driver for the Google Daydream Controller. 21 + */ 22 + 23 + /*! 24 + * Probing function for the Daydream controller. 25 + * 26 + * @ingroup drv_daydream 27 + */ 28 + struct xrt_auto_prober * 29 + daydream_create_auto_prober(); 30 + 31 + 32 + /*! 33 + * @dir drivers/daydream 34 + * 35 + * @brief @ref drv_daydream files. 36 + */ 37 + 38 + 39 + #ifdef __cplusplus 40 + } 41 + #endif
+114
src/xrt/drivers/daydream/daydream_prober.c
··· 1 + // Copyright 2019-2020, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Daydream prober code. 6 + * @author Pete Black <pete.black@collabora.com> 7 + * @ingroup drv_daydream 8 + */ 9 + 10 + #include <stdio.h> 11 + #include <stdlib.h> 12 + #include <wchar.h> 13 + 14 + #include "xrt/xrt_prober.h" 15 + 16 + #include "util/u_misc.h" 17 + #include "util/u_debug.h" 18 + 19 + #include "daydream_interface.h" 20 + #include "daydream_device.h" 21 + 22 + 23 + 24 + /* 25 + * 26 + * Defines & structs. 27 + * 28 + */ 29 + 30 + // Should the experimental PSVR driver be enabled. 31 + DEBUG_GET_ONCE_BOOL_OPTION(daydream_enable, "DAYDREAM_ENABLE", true) 32 + DEBUG_GET_ONCE_BOOL_OPTION(daydream_spew, "DAYDREAM_PRINT_SPEW", false) 33 + DEBUG_GET_ONCE_BOOL_OPTION(daydream_debug, "DAYDREAM_PRINT_DEBUG", false) 34 + 35 + /*! 36 + * Daydream prober struct. 37 + * 38 + * @ingroup drv_daydream 39 + */ 40 + struct daydream_prober 41 + { 42 + struct xrt_auto_prober base; 43 + 44 + bool print_spew; 45 + bool print_debug; 46 + bool enabled; 47 + }; 48 + 49 + 50 + /* 51 + * 52 + * Static functions. 53 + * 54 + */ 55 + 56 + static inline struct daydream_prober * 57 + daydream_prober(struct xrt_auto_prober *p) 58 + { 59 + return (struct daydream_prober *)p; 60 + } 61 + 62 + static void 63 + daydream_prober_destroy(struct xrt_auto_prober *p) 64 + { 65 + struct daydream_prober *pdaydream = daydream_prober(p); 66 + 67 + free(pdaydream); 68 + } 69 + 70 + static struct xrt_device * 71 + daydream_prober_autoprobe(struct xrt_auto_prober *xap, 72 + bool no_hmds, 73 + struct xrt_prober *xp) 74 + { 75 + struct daydream_prober *pdaydream = daydream_prober(xap); 76 + if (!pdaydream->enabled) { 77 + return NULL; 78 + } 79 + 80 + const char *dev_uuid = "0000fe55-0000-1000-8000-00805f9b34fb"; 81 + const char *char_uuid = "00000001-1000-1000-8000-00805f9b34fb"; 82 + 83 + struct os_ble_device *ble = NULL; 84 + os_ble_notify_open(dev_uuid, char_uuid, &ble); 85 + if (ble == NULL) { 86 + return NULL; 87 + } 88 + 89 + struct daydream_device *dd = daydream_device_create( 90 + ble, pdaydream->print_spew, pdaydream->print_debug); 91 + 92 + return &dd->base; 93 + } 94 + 95 + 96 + /* 97 + * 98 + * Exported functions. 99 + * 100 + */ 101 + 102 + struct xrt_auto_prober * 103 + daydream_create_auto_prober() 104 + { 105 + struct daydream_prober *pdaydream = 106 + U_TYPED_CALLOC(struct daydream_prober); 107 + pdaydream->base.destroy = daydream_prober_destroy; 108 + pdaydream->base.lelo_dallas_autoprobe = daydream_prober_autoprobe; 109 + pdaydream->enabled = debug_get_bool_option_daydream_enable(); 110 + pdaydream->print_spew = debug_get_bool_option_daydream_spew(); 111 + pdaydream->print_debug = debug_get_bool_option_daydream_debug(); 112 + 113 + return &pdaydream->base; 114 + }
+12
src/xrt/include/xrt/xrt_defines.h
··· 358 358 359 359 XRT_DEVICE_PSMV = 2, 360 360 XRT_DEVICE_HYDRA = 3, 361 + XRT_DEVICE_DAYDREAM = 4, 361 362 }; 362 363 363 364 /*! ··· 442 443 XRT_INPUT_HYDRA_JOYSTICK_VALUE = XRT_INPUT_NAME(0x0037, VEC2_MINUS_ONE_TO_ONE), 443 444 XRT_INPUT_HYDRA_TRIGGER_VALUE = XRT_INPUT_NAME(0x0038, VEC1_ZERO_TO_ONE), 444 445 XRT_INPUT_HYDRA_POSE = XRT_INPUT_NAME(0x0039, POSE), 446 + 447 + XRT_INPUT_DAYDREAM_TOUCHPAD_CLICK = XRT_INPUT_NAME(0x0040, BOOLEAN), 448 + XRT_INPUT_DAYDREAM_BAR_CLICK = XRT_INPUT_NAME(0x0041, BOOLEAN), 449 + XRT_INPUT_DAYDREAM_CIRCLE_CLICK = XRT_INPUT_NAME(0x0042, BOOLEAN), 450 + XRT_INPUT_DAYDREAM_VOLUP_CLICK = XRT_INPUT_NAME(0x0043, BOOLEAN), 451 + XRT_INPUT_DAYDREAM_VOLDN_CLICK = XRT_INPUT_NAME(0x0044, BOOLEAN), 452 + //! @todo This should be merged and be tagged as a touchpad, maybe. 453 + XRT_INPUT_DAYDREAM_TOUCHPAD_VALUE_X = XRT_INPUT_NAME(0x0045, VEC1_ZERO_TO_ONE), 454 + XRT_INPUT_DAYDREAM_TOUCHPAD_VALUE_Y = XRT_INPUT_NAME(0x0046, VEC1_ZERO_TO_ONE), 455 + XRT_INPUT_DAYDREAM_POSE = XRT_INPUT_NAME(0x0047, POSE), 456 + 445 457 // clang-format on 446 458 }; 447 459
+5 -1
src/xrt/state_trackers/oxr/oxr_binding.c
··· 1 - // Copyright 2018-2019, Collabora, Ltd. 1 + // Copyright 2018-2020, Collabora, Ltd. 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file ··· 248 248 interaction_profile_find(log, inst, inst->path_cache.khr_simple_controller, out_p); 249 249 interaction_profile_find(log, inst, inst->path_cache.mnd_ball_on_stick_controller, out_p); 250 250 // clang-format on 251 + return; 252 + case XRT_DEVICE_DAYDREAM: 253 + interaction_profile_find( 254 + log, inst, inst->path_cache.khr_simple_controller, out_p); 251 255 return; 252 256 default: return; 253 257 }
+8
src/xrt/state_trackers/oxr/oxr_binding_data.h
··· 59 59 { 60 60 XRT_INPUT_PSMV_TRIGGER_VALUE, 61 61 XRT_INPUT_HYDRA_TRIGGER_VALUE, 62 + XRT_INPUT_DAYDREAM_TOUCHPAD_CLICK, 62 63 (enum xrt_input_name)0, 63 64 }, 64 65 }, ··· 74 75 { 75 76 XRT_INPUT_PSMV_MOVE_CLICK, 76 77 XRT_INPUT_HYDRA_MIDDLE_CLICK, 78 + XRT_INPUT_DAYDREAM_BAR_CLICK, 77 79 (enum xrt_input_name)0, 78 80 }, 79 81 }, ··· 89 91 { 90 92 XRT_INPUT_PSMV_BODY_CENTER_POSE, 91 93 XRT_INPUT_HYDRA_POSE, 94 + XRT_INPUT_DAYDREAM_POSE, 92 95 (enum xrt_input_name)0, 93 96 }, 94 97 }, ··· 104 107 { 105 108 XRT_INPUT_PSMV_BALL_TIP_POSE, 106 109 XRT_INPUT_HYDRA_POSE, 110 + XRT_INPUT_DAYDREAM_POSE, 107 111 (enum xrt_input_name)0, 108 112 }, 109 113 }, ··· 132 136 { 133 137 XRT_INPUT_PSMV_TRIGGER_VALUE, 134 138 XRT_INPUT_HYDRA_TRIGGER_VALUE, 139 + XRT_INPUT_DAYDREAM_TOUCHPAD_CLICK, 135 140 (enum xrt_input_name)0, 136 141 }, 137 142 }, ··· 147 152 { 148 153 XRT_INPUT_PSMV_MOVE_CLICK, 149 154 XRT_INPUT_HYDRA_MIDDLE_CLICK, 155 + XRT_INPUT_DAYDREAM_BAR_CLICK, 150 156 (enum xrt_input_name)0, 151 157 }, 152 158 }, ··· 162 168 { 163 169 XRT_INPUT_PSMV_BODY_CENTER_POSE, 164 170 XRT_INPUT_HYDRA_POSE, 171 + XRT_INPUT_DAYDREAM_POSE, 165 172 (enum xrt_input_name)0, 166 173 }, 167 174 }, ··· 177 184 { 178 185 XRT_INPUT_PSMV_BALL_TIP_POSE, 179 186 XRT_INPUT_HYDRA_POSE, 187 + XRT_INPUT_DAYDREAM_POSE, 180 188 (enum xrt_input_name)0, 181 189 }, 182 190 },
+4
src/xrt/targets/common/CMakeLists.txt
··· 10 10 target_include_directories(target_lists PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../drivers) 11 11 target_include_directories(target_lists PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 12 12 13 + if(BUILD_DRIVER_DAYDREAM) 14 + target_link_libraries(target_lists PRIVATE drv_daydream) 15 + endif() 16 + 13 17 if(BUILD_DRIVER_DUMMY) 14 18 target_link_libraries(target_lists PRIVATE drv_dummy) 15 19 endif()
+9
src/xrt/targets/common/target_lists.c
··· 42 42 #include "vive/vive_prober.h" 43 43 #endif 44 44 45 + #ifdef XRT_BUILD_DRIVER_DAYDREAM 46 + #include "daydream/daydream_interface.h" 47 + #endif 48 + 45 49 /*! 46 50 * Each entry should be a vendor ID (VID), product ID (PID), a "found" function, 47 51 * and a string literal name. ··· 90 94 xrt_auto_prober_creator target_auto_list[] = { 91 95 #ifdef XRT_BUILD_DRIVER_PSVR 92 96 psvr_create_auto_prober, 97 + #endif 98 + 99 + #ifdef XRT_BUILD_DRIVER_DAYDREAM 100 + // Before OpenHMD 101 + daydream_create_auto_prober, 93 102 #endif 94 103 95 104 #ifdef XRT_BUILD_DRIVER_OHMD