The open source OpenXR runtime
0
fork

Configure Feed

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

d/xreal_air: Rename nreal air to xreal air in driver, support xreal air 2 and xreal air 2 pro

+667 -606
+2 -2
CMakeLists.txt
··· 310 310 option_with_deps(XRT_BUILD_DRIVER_HYDRA "Enable Hydra driver" DEPENDS XRT_HAVE_INTERNAL_HID) 311 311 option_with_deps(XRT_BUILD_DRIVER_ILLIXR "Enable ILLIXR driver" DEPENDS ILLIXR_PATH) 312 312 option(XRT_BUILD_DRIVER_NS "Enable North Star driver" ON) 313 - option_with_deps(XRT_BUILD_DRIVER_NA "Enable Nreal Air HMD driver" DEPENDS XRT_HAVE_HIDAPI) 314 313 option_with_deps(XRT_BUILD_DRIVER_OHMD "Enable OpenHMD driver" DEPENDS OPENHMD_FOUND) 315 314 option_with_deps(XRT_BUILD_DRIVER_OPENGLOVES "Enable OpenGloves driver" DEPENDS XRT_HAVE_LIBUDEV XRT_HAVE_BLUETOOTH) 316 315 option_with_deps(XRT_BUILD_DRIVER_PSMV "Enable Playstation Move driver" DEPENDS XRT_HAVE_INTERNAL_HID "NOT MSVC") ··· 328 327 option_with_deps(XRT_BUILD_DRIVER_VF "Build video frame driver (for video file support, uses gstreamer)" DEPENDS XRT_HAVE_GST) 329 328 option_with_deps(XRT_BUILD_DRIVER_VIVE "Enable driver for HTC Vive, Vive Pro, Valve Index, and their controllers" DEPENDS ZLIB_FOUND XRT_HAVE_LINUX XRT_MODULE_AUX_VIVE) 330 329 option_with_deps(XRT_BUILD_DRIVER_WMR "Enable Windows Mixed Reality driver" DEPENDS "NOT WIN32") 330 + option_with_deps(XRT_BUILD_DRIVER_XREAL_AIR "Enable Xreal Air HMD driver" DEPENDS XRT_HAVE_HIDAPI) 331 331 option_with_deps(XRT_BUILD_DRIVER_SIMULAVR "Enable simula driver" DEPENDS XRT_HAVE_REALSENSE) 332 332 option(XRT_BUILD_DRIVER_SIMULATED "Enable simulated driver" ON) 333 333 ··· 663 663 message(STATUS "# DRIVER_HDK: ${XRT_BUILD_DRIVER_HDK}") 664 664 message(STATUS "# DRIVER_HYDRA: ${XRT_BUILD_DRIVER_HYDRA}") 665 665 message(STATUS "# DRIVER_ILLIXR: ${XRT_BUILD_DRIVER_ILLIXR}") 666 - message(STATUS "# DRIVER_NA: ${XRT_BUILD_DRIVER_NA}") 667 666 message(STATUS "# DRIVER_NS: ${XRT_BUILD_DRIVER_NS}") 668 667 message(STATUS "# DRIVER_OHMD: ${XRT_BUILD_DRIVER_OHMD}") 669 668 message(STATUS "# DRIVER_OPENGLOVES: ${XRT_BUILD_DRIVER_OPENGLOVES}") ··· 684 683 message(STATUS "# DRIVER_VF: ${XRT_BUILD_DRIVER_VF}") 685 684 message(STATUS "# DRIVER_VIVE: ${XRT_BUILD_DRIVER_VIVE}") 686 685 message(STATUS "# DRIVER_WMR: ${XRT_BUILD_DRIVER_WMR}") 686 + message(STATUS "# DRIVER_XREAL_AIR: ${XRT_BUILD_DRIVER_XREAL_AIR}") 687 687 message(STATUS "# DRIVER_STEAMVR_LIGHTHOUSE: ${XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE}") 688 688 message(STATUS "#####----- Config -----#####") 689 689 # cmake-format: on
+6 -6
src/xrt/drivers/CMakeLists.txt
··· 110 110 list(APPEND ENABLED_HEADSET_DRIVERS ns) 111 111 endif() 112 112 113 - if(XRT_BUILD_DRIVER_NA) 113 + if(XRT_BUILD_DRIVER_XREAL_AIR) 114 114 add_library( 115 - drv_na STATIC nreal_air/na_hmd.h nreal_air/na_hmd.c nreal_air/na_interface.h 116 - nreal_air/na_packet.c 115 + drv_xreal_air STATIC xreal_air/xreal_air_hmd.h xreal_air/xreal_air_hmd.c 116 + xreal_air/xreal_air_interface.h xreal_air/xreal_air_packet.c 117 117 ) 118 118 target_link_libraries( 119 - drv_na PRIVATE xrt-interfaces HIDAPI::hidapi aux_util xrt-external-cjson 119 + drv_xreal_air PRIVATE xrt-interfaces HIDAPI::hidapi aux_util xrt-external-cjson 120 120 ) 121 - target_include_directories(drv_na PRIVATE ${HIDAPI_INCLUDE_DIRS}) 122 - list(APPEND ENABLED_HEADSET_DRIVERS na) 121 + target_include_directories(drv_xreal_air PRIVATE ${HIDAPI_INCLUDE_DIRS}) 122 + list(APPEND ENABLED_HEADSET_DRIVERS xreal_air) 123 123 endif() 124 124 125 125 if(XRT_BUILD_DRIVER_ULV2)
+158 -151
src/xrt/drivers/nreal_air/na_hmd.c src/xrt/drivers/xreal_air/xreal_air_hmd.c
··· 1 - // Copyright 2023, Tobias Frisch 1 + // Copyright 2023-2024, Tobias Frisch 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file 5 - * @brief Nreal Air packet parsing implementation. 5 + * @brief Xreal Air packet parsing implementation. 6 6 * @author Tobias Frisch <thejackimonster@gmail.com> 7 - * @ingroup drv_na 7 + * @ingroup drv_xreal_air 8 8 */ 9 9 10 10 #include "xrt/xrt_compiler.h" ··· 21 21 #include "util/u_trace_marker.h" 22 22 #include "util/u_var.h" 23 23 24 - #include "na_hmd.h" 24 + #include "xreal_air_hmd.h" 25 25 26 26 #include "math/m_mathinclude.h" 27 27 #include "math/m_relation_history.h" ··· 31 31 #include <stdint.h> 32 32 #include <stdbool.h> 33 33 34 - #define NA_DEBUG(hmd, ...) U_LOG_XDEV_IFL_D(&hmd->base, hmd->log_level, __VA_ARGS__) 35 - #define NA_ERROR(hmd, ...) U_LOG_XDEV_IFL_E(&hmd->base, hmd->log_level, __VA_ARGS__) 34 + #define XREAL_AIR_DEBUG(hmd, ...) U_LOG_XDEV_IFL_D(&hmd->base, hmd->log_level, __VA_ARGS__) 35 + #define XREAL_AIR_ERROR(hmd, ...) U_LOG_XDEV_IFL_E(&hmd->base, hmd->log_level, __VA_ARGS__) 36 36 37 37 #define SENSOR_BUFFER_SIZE 64 38 38 #define CONTROL_BUFFER_SIZE 64 ··· 41 41 #define CONTROL_HEAD 0xFD 42 42 43 43 /*! 44 - * Private struct for the nreal_air device. 44 + * Private struct for the xreal_air device. 45 45 * 46 - * @ingroup drv_na 46 + * @ingroup drv_xreal_air 47 47 * @implements xrt_device 48 48 */ 49 - struct na_hmd 49 + struct xreal_air_hmd 50 50 { 51 51 struct xrt_device base; 52 52 ··· 63 63 //! Only touched from the sensor thread. 64 64 timepoint_ns last_sensor_time; 65 65 66 - struct na_parsed_sensor last; 66 + struct xreal_air_parsed_sensor last; 67 67 68 68 struct 69 69 { ··· 97 97 char *calibration_buffer; 98 98 bool calibration_valid; 99 99 100 - struct na_parsed_calibration calibration; 100 + struct xreal_air_parsed_calibration calibration; 101 101 102 102 struct 103 103 { ··· 115 115 * 116 116 */ 117 117 118 - static inline struct na_hmd * 119 - na_hmd(struct xrt_device *dev) 118 + static inline struct xreal_air_hmd * 119 + xreal_air_hmd(struct xrt_device *dev) 120 120 { 121 - return (struct na_hmd *)dev; 121 + return (struct xreal_air_hmd *)dev; 122 122 } 123 123 124 124 const uint32_t crc32_table[256] = { ··· 167 167 static uint8_t 168 168 scale_brightness(uint8_t brightness) 169 169 { 170 - float relative = ((float)brightness - NA_BRIGHTNESS_MIN) / (NA_BRIGHTNESS_MAX - NA_BRIGHTNESS_MIN); 170 + float relative = 171 + ((float)brightness - XREAL_AIR_BRIGHTNESS_MIN) / (XREAL_AIR_BRIGHTNESS_MAX - XREAL_AIR_BRIGHTNESS_MIN); 171 172 relative = CLAMP(relative, 0.0f, 1.0f); 172 173 return (uint8_t)(relative * 100.0f); 173 174 } ··· 177 178 { 178 179 float relative = ((float)scaled_brightness) / 100.0f; 179 180 relative = CLAMP(relative, 0.0f, 1.0f); 180 - return (uint8_t)(relative * (NA_BRIGHTNESS_MAX - NA_BRIGHTNESS_MIN)) + NA_BRIGHTNESS_MIN; 181 + return (uint8_t)(relative * (XREAL_AIR_BRIGHTNESS_MAX - XREAL_AIR_BRIGHTNESS_MIN)) + XREAL_AIR_BRIGHTNESS_MIN; 181 182 } 182 183 183 184 /* ··· 187 188 */ 188 189 189 190 static bool 190 - send_payload_to_sensor(struct na_hmd *hmd, uint8_t msgid, const uint8_t *data, uint8_t len) 191 + send_payload_to_sensor(struct xreal_air_hmd *hmd, uint8_t msgid, const uint8_t *data, uint8_t len) 191 192 { 192 193 uint8_t payload[SENSOR_BUFFER_SIZE]; 193 194 ··· 229 230 } 230 231 231 232 static void 232 - read_sample_and_apply_calibration(struct na_hmd *hmd, 233 - struct na_parsed_sample *sample, 233 + read_sample_and_apply_calibration(struct xreal_air_hmd *hmd, 234 + struct xreal_air_parsed_sample *sample, 234 235 struct xrt_vec3 *out_accel, 235 236 struct xrt_vec3 *out_gyro, 236 237 struct xrt_vec3 *out_mag) ··· 302 303 } 303 304 304 305 static void 305 - update_fusion_locked(struct na_hmd *hmd, struct na_parsed_sample *sample, uint64_t timestamp_ns) 306 + update_fusion_locked(struct xreal_air_hmd *hmd, struct xreal_air_parsed_sample *sample, uint64_t timestamp_ns) 306 307 { 307 308 read_sample_and_apply_calibration(hmd, sample, &hmd->read.accel, &hmd->read.gyro, &hmd->read.mag); 308 309 m_imu_3dof_update(&hmd->fusion, timestamp_ns, &hmd->read.accel, &hmd->read.gyro); 309 310 } 310 311 311 312 static void 312 - update_fusion(struct na_hmd *hmd, struct na_parsed_sample *sample, uint64_t timestamp_ns) 313 + update_fusion(struct xreal_air_hmd *hmd, struct xreal_air_parsed_sample *sample, uint64_t timestamp_ns) 313 314 { 314 315 struct xrt_space_relation rel; 315 316 U_ZERO(&rel); // Clear out the relation. ··· 339 340 } 340 341 341 342 static timepoint_ns 342 - ensure_forward_progress_timestamps(struct na_hmd *hmd, timepoint_ns timestamp_ns) 343 + ensure_forward_progress_timestamps(struct xreal_air_hmd *hmd, timepoint_ns timestamp_ns) 343 344 { 344 345 timepoint_ns t = timestamp_ns; 345 346 ··· 356 357 } 357 358 358 359 static void 359 - request_sensor_control_get_cal_data_length(struct na_hmd *hmd) 360 + request_sensor_control_get_cal_data_length(struct xreal_air_hmd *hmd) 360 361 { 361 362 // Request calibration data length. 362 363 363 - if (!send_payload_to_sensor(hmd, NA_MSG_GET_CAL_DATA_LENGTH, NULL, 0)) { 364 - NA_ERROR(hmd, "Failed to send payload for receiving calibration data length!"); 364 + if (!send_payload_to_sensor(hmd, XREAL_AIR_MSG_GET_CAL_DATA_LENGTH, NULL, 0)) { 365 + XREAL_AIR_ERROR(hmd, "Failed to send payload for receiving calibration data length!"); 365 366 } 366 367 } 367 368 368 369 static void 369 - request_sensor_control_cal_data_get_next_segment(struct na_hmd *hmd) 370 + request_sensor_control_cal_data_get_next_segment(struct xreal_air_hmd *hmd) 370 371 { 371 372 // Request next segment of calibration data. 372 373 373 - if (!send_payload_to_sensor(hmd, NA_MSG_CAL_DATA_GET_NEXT_SEGMENT, NULL, 0)) { 374 - NA_ERROR(hmd, "Failed to send payload for receiving next calibration data segment! %d / %d", 375 - hmd->calibration_buffer_pos, hmd->calibration_buffer_len); 374 + if (!send_payload_to_sensor(hmd, XREAL_AIR_MSG_CAL_DATA_GET_NEXT_SEGMENT, NULL, 0)) { 375 + XREAL_AIR_ERROR(hmd, "Failed to send payload for receiving next calibration data segment! %d / %d", 376 + hmd->calibration_buffer_pos, hmd->calibration_buffer_len); 376 377 } 377 378 } 378 379 379 380 static void 380 - request_sensor_control_get_static_id(struct na_hmd *hmd) 381 + request_sensor_control_get_static_id(struct xreal_air_hmd *hmd) 381 382 { 382 383 // Request the static id. 383 384 384 - if (!send_payload_to_sensor(hmd, NA_MSG_GET_STATIC_ID, NULL, 0)) { 385 - NA_ERROR(hmd, "Failed to send payload for receiving static id!"); 385 + if (!send_payload_to_sensor(hmd, XREAL_AIR_MSG_GET_STATIC_ID, NULL, 0)) { 386 + XREAL_AIR_ERROR(hmd, "Failed to send payload for receiving static id!"); 386 387 } 387 388 } 388 389 389 390 static void 390 - request_sensor_control_start_imu_data(struct na_hmd *hmd, uint8_t imu_stream_state) 391 + request_sensor_control_start_imu_data(struct xreal_air_hmd *hmd, uint8_t imu_stream_state) 391 392 { 392 393 // Request to change the imu stream state. 393 394 394 - if (!send_payload_to_sensor(hmd, NA_MSG_START_IMU_DATA, &imu_stream_state, 1)) { 395 - NA_ERROR(hmd, "Failed to send payload for changing the imu stream state! %d", imu_stream_state); 395 + if (!send_payload_to_sensor(hmd, XREAL_AIR_MSG_START_IMU_DATA, &imu_stream_state, 1)) { 396 + XREAL_AIR_ERROR(hmd, "Failed to send payload for changing the imu stream state! %d", imu_stream_state); 396 397 } 397 398 } 398 399 399 400 static void 400 - handle_sensor_control_get_cal_data_length(struct na_hmd *hmd, const struct na_parsed_sensor_control_data *data) 401 + handle_sensor_control_get_cal_data_length(struct xreal_air_hmd *hmd, 402 + const struct xreal_air_parsed_sensor_control_data *data) 401 403 { 402 404 // Read calibration data length. 403 405 const uint32_t calibration_data_length = ··· 421 423 } 422 424 423 425 static void 424 - handle_sensor_control_cal_data_get_next_segment(struct na_hmd *hmd, const struct na_parsed_sensor_control_data *data) 426 + handle_sensor_control_cal_data_get_next_segment(struct xreal_air_hmd *hmd, 427 + const struct xreal_air_parsed_sensor_control_data *data) 425 428 { 426 429 if (hmd->calibration_buffer_len == 0) { 427 430 request_sensor_control_get_cal_data_length(hmd); ··· 429 432 } 430 433 431 434 if (hmd->calibration_buffer_len <= hmd->calibration_buffer_pos) { 432 - NA_ERROR(hmd, "Failed to receive next calibration data segment! %d / %d", hmd->calibration_buffer_pos, 433 - hmd->calibration_buffer_len); 435 + XREAL_AIR_ERROR(hmd, "Failed to receive next calibration data segment! %d / %d", 436 + hmd->calibration_buffer_pos, hmd->calibration_buffer_len); 434 437 return; 435 438 } 436 439 ··· 448 451 449 452 if (hmd->calibration_buffer_pos == hmd->calibration_buffer_len) { 450 453 // Parse calibration data from raw json. 451 - if (!na_parse_calibration_buffer(&hmd->calibration, hmd->calibration_buffer, 452 - hmd->calibration_buffer_len)) { 453 - NA_ERROR(hmd, "Failed parse calibration data!"); 454 + if (!xreal_air_parse_calibration_buffer(&hmd->calibration, hmd->calibration_buffer, 455 + hmd->calibration_buffer_len)) { 456 + XREAL_AIR_ERROR(hmd, "Failed parse calibration data!"); 454 457 } else { 455 458 hmd->calibration_valid = true; 456 459 ··· 469 472 } 470 473 471 474 static void 472 - handle_sensor_control_start_imu_data(struct na_hmd *hmd, const struct na_parsed_sensor_control_data *data) 475 + handle_sensor_control_start_imu_data(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_sensor_control_data *data) 473 476 { 474 477 // Read the imu stream state. 475 478 const uint8_t imu_stream_state = data->data[0]; ··· 484 487 } 485 488 486 489 static void 487 - handle_sensor_control_get_static_id(struct na_hmd *hmd, const struct na_parsed_sensor_control_data *data) 490 + handle_sensor_control_get_static_id(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_sensor_control_data *data) 488 491 { 489 492 // Read the static id. 490 493 const uint32_t static_id = ··· 498 501 } 499 502 500 503 static void 501 - handle_sensor_control_data_msg(struct na_hmd *hmd, unsigned char *buffer, int size) 504 + handle_sensor_control_data_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, int size) 502 505 { 503 - struct na_parsed_sensor_control_data data; 506 + struct xreal_air_parsed_sensor_control_data data; 504 507 505 - if (!na_parse_sensor_control_data_packet(&data, buffer, size)) { 506 - NA_ERROR(hmd, "Could not decode sensor control data packet"); 508 + if (!xreal_air_parse_sensor_control_data_packet(&data, buffer, size)) { 509 + XREAL_AIR_ERROR(hmd, "Could not decode sensor control data packet"); 507 510 } 508 511 509 512 hmd->imu_stream_state = 0xAA; 510 513 511 514 switch (data.msgid) { 512 - case NA_MSG_GET_CAL_DATA_LENGTH: handle_sensor_control_get_cal_data_length(hmd, &data); break; 513 - case NA_MSG_CAL_DATA_GET_NEXT_SEGMENT: handle_sensor_control_cal_data_get_next_segment(hmd, &data); break; 514 - case NA_MSG_ALLOCATE_CAL_DATA_BUFFER: break; 515 - case NA_MSG_WRITE_CAL_DATA_SEGMENT: break; 516 - case NA_MSG_FREE_CAL_BUFFER: break; 517 - case NA_MSG_START_IMU_DATA: handle_sensor_control_start_imu_data(hmd, &data); break; 518 - case NA_MSG_GET_STATIC_ID: handle_sensor_control_get_static_id(hmd, &data); break; 519 - default: NA_ERROR(hmd, "Got unknown sensor control data msgid, 0x%02x", data.msgid); break; 515 + case XREAL_AIR_MSG_GET_CAL_DATA_LENGTH: handle_sensor_control_get_cal_data_length(hmd, &data); break; 516 + case XREAL_AIR_MSG_CAL_DATA_GET_NEXT_SEGMENT: 517 + handle_sensor_control_cal_data_get_next_segment(hmd, &data); 518 + break; 519 + case XREAL_AIR_MSG_ALLOCATE_CAL_DATA_BUFFER: break; 520 + case XREAL_AIR_MSG_WRITE_CAL_DATA_SEGMENT: break; 521 + case XREAL_AIR_MSG_FREE_CAL_BUFFER: break; 522 + case XREAL_AIR_MSG_START_IMU_DATA: handle_sensor_control_start_imu_data(hmd, &data); break; 523 + case XREAL_AIR_MSG_GET_STATIC_ID: handle_sensor_control_get_static_id(hmd, &data); break; 524 + default: XREAL_AIR_ERROR(hmd, "Got unknown sensor control data msgid, 0x%02x", data.msgid); break; 520 525 } 521 526 } 522 527 523 528 static void 524 - handle_sensor_msg(struct na_hmd *hmd, unsigned char *buffer, int size) 529 + handle_sensor_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, int size) 525 530 { 526 531 if (buffer[0] == 0xAA) { 527 532 handle_sensor_control_data_msg(hmd, buffer, size); ··· 531 536 timepoint_ns now_ns = (timepoint_ns)os_monotonic_get_ns(); 532 537 uint64_t last_timestamp = hmd->last.timestamp; 533 538 534 - if (!na_parse_sensor_packet(&hmd->last, buffer, size)) { 535 - NA_ERROR(hmd, "Could not decode sensor packet"); 539 + if (!xreal_air_parse_sensor_packet(&hmd->last, buffer, size)) { 540 + XREAL_AIR_ERROR(hmd, "Could not decode sensor packet"); 536 541 } else { 537 542 hmd->imu_stream_state = 0x1; 538 543 } ··· 541 546 request_sensor_control_start_imu_data(hmd, 0xAA); 542 547 } 543 548 544 - struct na_parsed_sensor *s = &hmd->last; 549 + struct xreal_air_parsed_sensor *s = &hmd->last; 545 550 546 551 // According to the ICM-42688-P datasheet: (offset: 25 °C, sensitivity: 132.48 LSB/°C) 547 552 hmd->read.temperature = ((float)s->temperature) / 132.48f + 25.0f; ··· 553 558 // If this is larger then one second something bad is going on. 554 559 if (hmd->fusion.state != M_IMU_3DOF_STATE_START && 555 560 inter_sample_duration_ns >= (time_duration_ns)U_TIME_1S_IN_NS) { 556 - NA_ERROR(hmd, "Drop packet (sensor too slow): %lu", inter_sample_duration_ns); 561 + XREAL_AIR_ERROR(hmd, "Drop packet (sensor too slow): %lu", inter_sample_duration_ns); 557 562 return; 558 563 } 559 564 ··· 568 573 } 569 574 570 575 static void 571 - sensor_clear_queue(struct na_hmd *hmd) 576 + sensor_clear_queue(struct xreal_air_hmd *hmd) 572 577 { 573 578 uint8_t buffer[SENSOR_BUFFER_SIZE]; 574 579 ··· 578 583 } 579 584 580 585 static int 581 - sensor_read_one_packet(struct na_hmd *hmd) 586 + sensor_read_one_packet(struct xreal_air_hmd *hmd) 582 587 { 583 588 uint8_t buffer[SENSOR_BUFFER_SIZE]; 584 589 ··· 592 597 } 593 598 594 599 static int 595 - read_one_control_packet(struct na_hmd *hmd); 600 + read_one_control_packet(struct xreal_air_hmd *hmd); 596 601 597 602 static void * 598 603 read_thread(void *ptr) 599 604 { 600 - U_TRACE_SET_THREAD_NAME("Nreal Air"); 605 + U_TRACE_SET_THREAD_NAME("Xreal Air"); 601 606 602 - struct na_hmd *hmd = (struct na_hmd *)ptr; 607 + struct xreal_air_hmd *hmd = (struct xreal_air_hmd *)ptr; 603 608 int ret = 0; 604 609 605 610 os_thread_helper_lock(&hmd->oth); ··· 637 642 * 638 643 */ 639 644 static bool 640 - send_payload_to_control(struct na_hmd *hmd, uint16_t msgid, const uint8_t *data, uint8_t len) 645 + send_payload_to_control(struct xreal_air_hmd *hmd, uint16_t msgid, const uint8_t *data, uint8_t len) 641 646 { 642 647 uint8_t payload[CONTROL_BUFFER_SIZE]; 643 648 ··· 670 675 } 671 676 672 677 static void 673 - handle_control_brightness(struct na_hmd *hmd, const struct na_parsed_control *control) 678 + handle_control_brightness(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 674 679 { 675 680 // Check status 676 681 if (control->data[0] != 0) { ··· 685 690 } 686 691 687 692 static void 688 - handle_control_display_mode(struct na_hmd *hmd, const struct na_parsed_control *control) 693 + handle_control_display_mode(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 689 694 { 690 695 // Check status 691 696 if (control->data[0] != 0) { ··· 700 705 } 701 706 702 707 static void 703 - handle_control_heartbeat_start(struct na_hmd *hmd, const struct na_parsed_control *control) 708 + handle_control_heartbeat_start(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 704 709 { 705 710 // TODO 706 711 } 707 712 708 713 static void 709 - handle_control_button(struct na_hmd *hmd, const struct na_parsed_control *control) 714 + handle_control_button(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 710 715 { 711 716 // Physical button 712 717 const uint8_t phys_button = control->data[0]; ··· 718 723 const uint8_t value = control->data[8]; 719 724 720 725 switch (virt_button) { 721 - case NA_BUTTON_VIRT_DISPLAY_TOGGLE: { 726 + case XREAL_AIR_BUTTON_VIRT_DISPLAY_TOGGLE: { 722 727 hmd->display_on = value; 723 728 break; 724 729 } 725 - case NA_BUTTON_VIRT_MENU_TOGGLE: break; 726 - case NA_BUTTON_VIRT_BRIGHTNESS_UP: 727 - case NA_BUTTON_VIRT_BRIGHTNESS_DOWN: { 730 + case XREAL_AIR_BUTTON_VIRT_MENU_TOGGLE: break; 731 + case XREAL_AIR_BUTTON_VIRT_BRIGHTNESS_UP: 732 + case XREAL_AIR_BUTTON_VIRT_BRIGHTNESS_DOWN: { 728 733 const uint8_t brightness = scale_brightness(value); 729 734 730 735 hmd->state.brightness = brightness; 731 736 hmd->wants.brightness = brightness; 732 737 break; 733 738 } 734 - case NA_BUTTON_VIRT_MODE_UP: { 739 + case XREAL_AIR_BUTTON_VIRT_MODE_UP: { 735 740 const uint8_t display_mode = hmd->state.display_mode; 736 741 737 - if (display_mode == NA_DISPLAY_MODE_2D) { 738 - hmd->wants.display_mode = NA_DISPLAY_MODE_3D; 742 + if (display_mode == XREAL_AIR_DISPLAY_MODE_2D) { 743 + hmd->wants.display_mode = XREAL_AIR_DISPLAY_MODE_3D; 739 744 } 740 745 741 746 break; 742 747 } 743 - case NA_BUTTON_VIRT_MODE_DOWN: { 748 + case XREAL_AIR_BUTTON_VIRT_MODE_DOWN: { 744 749 const uint8_t display_mode = hmd->state.display_mode; 745 750 746 - if (display_mode == NA_DISPLAY_MODE_3D) { 747 - hmd->wants.display_mode = NA_DISPLAY_MODE_2D; 751 + if (display_mode == XREAL_AIR_DISPLAY_MODE_3D) { 752 + hmd->wants.display_mode = XREAL_AIR_DISPLAY_MODE_2D; 748 753 } 749 754 750 755 break; 751 756 } 752 757 default: { 753 - NA_ERROR(hmd, "Got unknown button pressed, 0x%02x (0x%02x)", virt_button, phys_button); 758 + XREAL_AIR_ERROR(hmd, "Got unknown button pressed, 0x%02x (0x%02x)", virt_button, phys_button); 754 759 break; 755 760 } 756 761 } 757 762 } 758 763 759 764 static void 760 - handle_control_async_text(struct na_hmd *hmd, const struct na_parsed_control *control) 765 + handle_control_async_text(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 761 766 { 762 767 // Event only appears if the display is active! 763 768 hmd->display_on = true; 764 769 765 - NA_DEBUG(hmd, "Control message: %s", (const char *)control->data); 770 + XREAL_AIR_DEBUG(hmd, "Control message: %s", (const char *)control->data); 766 771 } 767 772 768 773 static void 769 - handle_control_heartbeat_end(struct na_hmd *hmd, const struct na_parsed_control *control) 774 + handle_control_heartbeat_end(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 770 775 { 771 776 // TODO 772 777 } 773 778 774 779 static void 775 - handle_control_action_locked(struct na_hmd *hmd, const struct na_parsed_control *control) 780 + handle_control_action_locked(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 776 781 { 777 782 switch (control->action) { 778 - case NA_MSG_R_BRIGHTNESS: handle_control_brightness(hmd, control); break; 779 - case NA_MSG_W_BRIGHTNESS: break; 780 - case NA_MSG_R_DISP_MODE: handle_control_display_mode(hmd, control); break; 781 - case NA_MSG_W_DISP_MODE: break; 782 - case NA_MSG_P_START_HEARTBEAT: handle_control_heartbeat_start(hmd, control); break; 783 - case NA_MSG_P_BUTTON_PRESSED: handle_control_button(hmd, control); break; 784 - case NA_MSG_P_ASYNC_TEXT_LOG: handle_control_async_text(hmd, control); break; 785 - case NA_MSG_P_END_HEARTBEAT: handle_control_heartbeat_end(hmd, control); break; 786 - default: NA_ERROR(hmd, "Got unknown control action, 0x%02x", control->action); break; 783 + case XREAL_AIR_MSG_R_BRIGHTNESS: handle_control_brightness(hmd, control); break; 784 + case XREAL_AIR_MSG_W_BRIGHTNESS: break; 785 + case XREAL_AIR_MSG_R_DISP_MODE: handle_control_display_mode(hmd, control); break; 786 + case XREAL_AIR_MSG_W_DISP_MODE: break; 787 + case XREAL_AIR_MSG_P_START_HEARTBEAT: handle_control_heartbeat_start(hmd, control); break; 788 + case XREAL_AIR_MSG_P_BUTTON_PRESSED: handle_control_button(hmd, control); break; 789 + case XREAL_AIR_MSG_P_ASYNC_TEXT_LOG: handle_control_async_text(hmd, control); break; 790 + case XREAL_AIR_MSG_P_END_HEARTBEAT: handle_control_heartbeat_end(hmd, control); break; 791 + default: XREAL_AIR_ERROR(hmd, "Got unknown control action, 0x%02x", control->action); break; 787 792 } 788 793 } 789 794 790 795 static void 791 - handle_control_msg(struct na_hmd *hmd, unsigned char *buffer, int size) 796 + handle_control_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, int size) 792 797 { 793 - struct na_parsed_control control; 798 + struct xreal_air_parsed_control control; 794 799 795 - if (!na_parse_control_packet(&control, buffer, size)) { 796 - NA_ERROR(hmd, "Could not decode control packet"); 800 + if (!xreal_air_parse_control_packet(&control, buffer, size)) { 801 + XREAL_AIR_ERROR(hmd, "Could not decode control packet"); 797 802 } 798 803 799 804 os_mutex_lock(&hmd->device_mutex); ··· 802 807 } 803 808 804 809 static void 805 - control_clear_queue(struct na_hmd *hmd) 810 + control_clear_queue(struct xreal_air_hmd *hmd) 806 811 { 807 812 uint8_t buffer[CONTROL_BUFFER_SIZE]; 808 813 ··· 812 817 } 813 818 814 819 static int 815 - read_one_control_packet(struct na_hmd *hmd) 820 + read_one_control_packet(struct xreal_air_hmd *hmd) 816 821 { 817 822 static uint8_t buffer[CONTROL_BUFFER_SIZE]; 818 823 int size = 0; ··· 830 835 } 831 836 832 837 static bool 833 - wait_for_brightness(struct na_hmd *hmd) 838 + wait_for_brightness(struct xreal_air_hmd *hmd) 834 839 { 835 840 for (int i = 0; i < 5000; i++) { 836 841 read_one_control_packet(hmd); ··· 846 851 } 847 852 848 853 static bool 849 - wait_for_display_mode(struct na_hmd *hmd) 854 + wait_for_display_mode(struct xreal_air_hmd *hmd) 850 855 { 851 856 for (int i = 0; i < 5000; i++) { 852 857 read_one_control_packet(hmd); 853 858 854 - if ((hmd->state.display_mode == NA_DISPLAY_MODE_2D) || 855 - (hmd->state.display_mode == NA_DISPLAY_MODE_3D)) { 859 + if ((hmd->state.display_mode == XREAL_AIR_DISPLAY_MODE_2D) || 860 + (hmd->state.display_mode == XREAL_AIR_DISPLAY_MODE_3D)) { 856 861 return true; 857 862 } 858 863 ··· 863 868 } 864 869 865 870 static bool 866 - control_brightness(struct na_hmd *hmd) 871 + control_brightness(struct xreal_air_hmd *hmd) 867 872 { 868 - if (!send_payload_to_control(hmd, NA_MSG_R_BRIGHTNESS, NULL, 0)) { 869 - NA_ERROR(hmd, "Failed to send payload for initial brightness value!"); 873 + if (!send_payload_to_control(hmd, XREAL_AIR_MSG_R_BRIGHTNESS, NULL, 0)) { 874 + XREAL_AIR_ERROR(hmd, "Failed to send payload for initial brightness value!"); 870 875 return false; 871 876 } 872 877 873 878 if (!wait_for_brightness(hmd)) { 874 - NA_ERROR(hmd, "Failed to wait for valid brightness value!"); 879 + XREAL_AIR_ERROR(hmd, "Failed to wait for valid brightness value!"); 875 880 return false; 876 881 } 877 882 ··· 879 884 } 880 885 881 886 static bool 882 - control_display_mode(struct na_hmd *hmd) 887 + control_display_mode(struct xreal_air_hmd *hmd) 883 888 { 884 - if (!send_payload_to_control(hmd, NA_MSG_R_DISP_MODE, NULL, 0)) { 885 - NA_ERROR(hmd, "Failed to send payload for initial display mode!"); 889 + if (!send_payload_to_control(hmd, XREAL_AIR_MSG_R_DISP_MODE, NULL, 0)) { 890 + XREAL_AIR_ERROR(hmd, "Failed to send payload for initial display mode!"); 886 891 return false; 887 892 } 888 893 889 894 if (!wait_for_display_mode(hmd)) { 890 - NA_ERROR(hmd, "Failed to wait for valid display mode!"); 895 + XREAL_AIR_ERROR(hmd, "Failed to wait for valid display mode!"); 891 896 return false; 892 897 } 893 898 ··· 895 900 } 896 901 897 902 static bool 898 - switch_display_mode(struct na_hmd *hmd, uint8_t display_mode) 903 + switch_display_mode(struct xreal_air_hmd *hmd, uint8_t display_mode) 899 904 { 900 - if ((display_mode != NA_DISPLAY_MODE_2D) && (display_mode > NA_DISPLAY_MODE_3D)) { 905 + if ((display_mode != XREAL_AIR_DISPLAY_MODE_2D) && (display_mode > XREAL_AIR_DISPLAY_MODE_3D)) { 901 906 return false; 902 907 } 903 908 ··· 912 917 info.display.w_meters *= 2.0f; 913 918 info.lens_horizontal_separation_meters *= 2.0f; 914 919 915 - if (display_mode == NA_DISPLAY_MODE_3D) { 920 + if (display_mode == XREAL_AIR_DISPLAY_MODE_3D) { 916 921 info.display.w_pixels *= 2; 917 922 } 918 923 ··· 920 925 info.fov[1] = (float)(46.0 * (M_PI / 180.0)); 921 926 922 927 if (!u_device_setup_split_side_by_side(&hmd->base, &info)) { 923 - NA_ERROR(hmd, "Failed to setup basic device info"); 928 + XREAL_AIR_ERROR(hmd, "Failed to setup basic device info"); 924 929 return false; 925 930 } 926 931 927 - if (display_mode == NA_DISPLAY_MODE_2D) { 932 + if (display_mode == XREAL_AIR_DISPLAY_MODE_2D) { 928 933 hmd->base.hmd->views[0].display.w_pixels = info.display.w_pixels; 929 934 hmd->base.hmd->views[0].viewport.w_pixels = info.display.w_pixels; 930 935 ··· 945 950 */ 946 951 947 952 static void 948 - teardown(struct na_hmd *hmd) 953 + teardown(struct xreal_air_hmd *hmd) 949 954 { 950 955 // Stop the variable tracking. 951 956 u_var_remove_root(hmd); ··· 973 978 } 974 979 975 980 static void 976 - adjust_brightness(struct na_hmd *hmd) 981 + adjust_brightness(struct xreal_air_hmd *hmd) 977 982 { 978 983 if (hmd->wants.brightness > 100) { 979 984 return; ··· 990 995 return; 991 996 } 992 997 993 - if (!send_payload_to_control(hmd, NA_MSG_W_BRIGHTNESS, &raw_brightness, 1)) { 994 - NA_ERROR(hmd, "Failed to send payload setting custom brightness value!"); 998 + if (!send_payload_to_control(hmd, XREAL_AIR_MSG_W_BRIGHTNESS, &raw_brightness, 1)) { 999 + XREAL_AIR_ERROR(hmd, "Failed to send payload setting custom brightness value!"); 995 1000 return; 996 1001 } 997 1002 ··· 999 1004 } 1000 1005 1001 1006 static void 1002 - adjust_display_mode(struct na_hmd *hmd) 1007 + adjust_display_mode(struct xreal_air_hmd *hmd) 1003 1008 { 1004 - if ((hmd->wants.display_mode != NA_DISPLAY_MODE_2D) && (hmd->wants.display_mode != NA_DISPLAY_MODE_3D)) { 1009 + if ((hmd->wants.display_mode != XREAL_AIR_DISPLAY_MODE_2D) && 1010 + (hmd->wants.display_mode != XREAL_AIR_DISPLAY_MODE_3D)) { 1005 1011 return; 1006 1012 } 1007 1013 ··· 1011 1017 1012 1018 const uint8_t display_mode = hmd->wants.display_mode; 1013 1019 1014 - if (!send_payload_to_control(hmd, NA_MSG_W_DISP_MODE, &display_mode, 1)) { 1015 - NA_ERROR(hmd, "Failed to send payload setting custom display mode!"); 1020 + if (!send_payload_to_control(hmd, XREAL_AIR_MSG_W_DISP_MODE, &display_mode, 1)) { 1021 + XREAL_AIR_ERROR(hmd, "Failed to send payload setting custom display mode!"); 1016 1022 return; 1017 1023 } 1018 1024 ··· 1026 1032 */ 1027 1033 1028 1034 static void 1029 - na_hmd_update_inputs(struct xrt_device *xdev) 1035 + xreal_air_hmd_update_inputs(struct xrt_device *xdev) 1030 1036 { 1031 - struct na_hmd *hmd = na_hmd(xdev); 1037 + struct xreal_air_hmd *hmd = xreal_air_hmd(xdev); 1032 1038 1033 1039 os_mutex_lock(&hmd->device_mutex); 1034 1040 ··· 1042 1048 } 1043 1049 1044 1050 static void 1045 - na_hmd_get_tracked_pose(struct xrt_device *xdev, 1046 - enum xrt_input_name name, 1047 - uint64_t at_timestamp_ns, 1048 - struct xrt_space_relation *out_relation) 1051 + xreal_air_hmd_get_tracked_pose(struct xrt_device *xdev, 1052 + enum xrt_input_name name, 1053 + uint64_t at_timestamp_ns, 1054 + struct xrt_space_relation *out_relation) 1049 1055 { 1050 - struct na_hmd *hmd = na_hmd(xdev); 1056 + struct xreal_air_hmd *hmd = xreal_air_hmd(xdev); 1051 1057 1052 1058 if (name != XRT_INPUT_GENERIC_HEAD_POSE) { 1053 - NA_ERROR(hmd, "unknown input name"); 1059 + XREAL_AIR_ERROR(hmd, "unknown input name"); 1054 1060 return; 1055 1061 } 1056 1062 ··· 1071 1077 } 1072 1078 1073 1079 static void 1074 - na_hmd_destroy(struct xrt_device *xdev) 1080 + xreal_air_hmd_destroy(struct xrt_device *xdev) 1075 1081 { 1076 - struct na_hmd *hmd = na_hmd(xdev); 1082 + struct xreal_air_hmd *hmd = xreal_air_hmd(xdev); 1077 1083 teardown(hmd); 1078 1084 1079 1085 u_device_free(&hmd->base); 1080 1086 } 1081 1087 1082 1088 static bool 1083 - na_hmd_compute_distortion(struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *result) 1089 + xreal_air_hmd_compute_distortion( 1090 + struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *result) 1084 1091 { 1085 1092 return u_compute_distortion_none(u, v, result); 1086 1093 } ··· 1092 1099 */ 1093 1100 1094 1101 struct xrt_device * 1095 - na_hmd_create_device(struct os_hid_device *sensor_device, 1096 - struct os_hid_device *control_device, 1097 - enum u_logging_level log_level) 1102 + xreal_air_hmd_create_device(struct os_hid_device *sensor_device, 1103 + struct os_hid_device *control_device, 1104 + enum u_logging_level log_level) 1098 1105 { 1099 1106 enum u_device_alloc_flags flags = 1100 1107 (enum u_device_alloc_flags)(U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE); 1101 - struct na_hmd *hmd = U_DEVICE_ALLOCATE(struct na_hmd, flags, 1, 0); 1108 + struct xreal_air_hmd *hmd = U_DEVICE_ALLOCATE(struct xreal_air_hmd, flags, 1, 0); 1102 1109 int ret; 1103 1110 1104 1111 hmd->log_level = log_level; 1105 - hmd->base.update_inputs = na_hmd_update_inputs; 1106 - hmd->base.get_tracked_pose = na_hmd_get_tracked_pose; 1112 + hmd->base.update_inputs = xreal_air_hmd_update_inputs; 1113 + hmd->base.get_tracked_pose = xreal_air_hmd_get_tracked_pose; 1107 1114 hmd->base.get_view_poses = u_device_get_view_poses; 1108 - hmd->base.compute_distortion = na_hmd_compute_distortion; 1109 - hmd->base.destroy = na_hmd_destroy; 1115 + hmd->base.compute_distortion = xreal_air_hmd_compute_distortion; 1116 + hmd->base.destroy = xreal_air_hmd_destroy; 1110 1117 hmd->base.name = XRT_DEVICE_GENERIC_HMD; 1111 1118 hmd->base.device_type = XRT_DEVICE_TYPE_HMD; 1112 1119 hmd->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE; ··· 1140 1147 hmd->last.timestamp = 0xFFFFFFFF; 1141 1148 1142 1149 // Print name 1143 - snprintf(hmd->base.str, XRT_DEVICE_NAME_LEN, "Nreal Air Glasses"); 1144 - snprintf(hmd->base.serial, XRT_DEVICE_NAME_LEN, "Nreal Air Glasses"); 1150 + snprintf(hmd->base.str, XRT_DEVICE_NAME_LEN, "Xreal Air Glasses"); 1151 + snprintf(hmd->base.serial, XRT_DEVICE_NAME_LEN, "Xreal Air Glasses"); 1145 1152 1146 1153 // Do mutex and thread init before any call to teardown happens. 1147 1154 os_mutex_init(&hmd->device_mutex); ··· 1186 1193 * Setup variable. 1187 1194 */ 1188 1195 1189 - u_var_add_root(hmd, "Nreal Air Glasses", true); 1196 + u_var_add_root(hmd, "Xreal Air Glasses", true); 1190 1197 u_var_add_u8(hmd, &hmd->wants.brightness, "Brightness"); 1191 1198 u_var_add_u8(hmd, &hmd->wants.display_mode, "Display mode"); 1192 1199 u_var_add_gui_header(hmd, &hmd->gui.last_frame, "Last data"); ··· 1208 1215 */ 1209 1216 1210 1217 if (hmd->log_level <= U_LOGGING_DEBUG) { 1211 - u_device_dump_config(&hmd->base, __func__, "Nreal Air"); 1218 + u_device_dump_config(&hmd->base, __func__, "Xreal Air"); 1212 1219 } 1213 1220 1214 - NA_DEBUG(hmd, "YES!"); 1221 + XREAL_AIR_DEBUG(hmd, "YES!"); 1215 1222 1216 1223 return &hmd->base; 1217 1224 1218 1225 cleanup: 1219 - NA_DEBUG(hmd, "NO! :("); 1226 + XREAL_AIR_DEBUG(hmd, "NO! :("); 1220 1227 1221 1228 if (hmd->calibration_buffer) { 1222 1229 free(hmd->calibration_buffer);
-166
src/xrt/drivers/nreal_air/na_hmd.h
··· 1 - // Copyright 2023, Tobias Frisch 2 - // SPDX-License-Identifier: BSL-1.0 3 - /*! 4 - * @file 5 - * @brief Nreal Air packet parsing implementation. 6 - * @author Tobias Frisch <thejackimonster@gmail.com> 7 - * @ingroup drv_na 8 - */ 9 - 10 - #pragma once 11 - 12 - #include "xrt/xrt_device.h" 13 - #include "xrt/xrt_prober.h" 14 - 15 - #include "os/os_hid.h" 16 - 17 - #include "util/u_logging.h" 18 - 19 - #ifdef __cplusplus 20 - extern "C" { 21 - #endif 22 - 23 - #define NA_HANDLE_IFACE 3 24 - #define NA_CONTROL_IFACE 4 25 - 26 - #define NA_MSG_R_BRIGHTNESS 0x03 27 - #define NA_MSG_W_BRIGHTNESS 0x04 28 - #define NA_MSG_R_DISP_MODE 0x07 29 - #define NA_MSG_W_DISP_MODE 0x08 30 - 31 - #define NA_MSG_P_START_HEARTBEAT 0x6c02 32 - #define NA_MSG_P_BUTTON_PRESSED 0x6C05 33 - #define NA_MSG_P_END_HEARTBEAT 0x6c12 34 - #define NA_MSG_P_ASYNC_TEXT_LOG 0x6c09 35 - 36 - #define NA_BUTTON_PHYS_DISPLAY_TOGGLE 0x1 37 - #define NA_BUTTON_PHYS_BRIGHTNESS_UP 0x2 38 - #define NA_BUTTON_PHYS_BRIGHTNESS_DOWN 0x3 39 - 40 - #define NA_BUTTON_VIRT_DISPLAY_TOGGLE 0x1 41 - #define NA_BUTTON_VIRT_MENU_TOGGLE 0x3 42 - #define NA_BUTTON_VIRT_BRIGHTNESS_UP 0x6 43 - #define NA_BUTTON_VIRT_BRIGHTNESS_DOWN 0x7 44 - #define NA_BUTTON_VIRT_MODE_UP 0x8 45 - #define NA_BUTTON_VIRT_MODE_DOWN 0x9 46 - 47 - #define NA_BRIGHTNESS_MIN 0 48 - #define NA_BRIGHTNESS_MAX 7 49 - 50 - #define NA_DISPLAY_MODE_2D 0x1 51 - #define NA_DISPLAY_MODE_3D 0x3 52 - 53 - #define NA_TICKS_PER_SECOND (1000.0) // 1 KHz ticks 54 - #define NA_NS_PER_TICK (1000000) // Each tick is a millisecond 55 - 56 - #define NA_MSG_GET_CAL_DATA_LENGTH 0x14 57 - #define NA_MSG_CAL_DATA_GET_NEXT_SEGMENT 0x15 58 - #define NA_MSG_ALLOCATE_CAL_DATA_BUFFER 0x16 59 - #define NA_MSG_WRITE_CAL_DATA_SEGMENT 0x17 60 - #define NA_MSG_FREE_CAL_BUFFER 0x18 61 - #define NA_MSG_START_IMU_DATA 0x19 62 - #define NA_MSG_GET_STATIC_ID 0x1A 63 - #define NA_MSG_UNKNOWN 0x1D 64 - 65 - struct na_parsed_calibration 66 - { 67 - struct xrt_vec3 accel_bias; 68 - struct xrt_quat accel_q_gyro; 69 - struct xrt_vec3 gyro_bias; 70 - struct xrt_quat gyro_q_mag; 71 - struct xrt_vec3 mag_bias; 72 - 73 - struct xrt_vec3 scale_accel; 74 - struct xrt_vec3 scale_gyro; 75 - struct xrt_vec3 scale_mag; 76 - 77 - float imu_noises[4]; 78 - }; 79 - 80 - /*! 81 - * A parsed single gyroscope, accelerometer and 82 - * magnetometer sample with their corresponding 83 - * factors for conversion from raw data. 84 - * 85 - * @ingroup drv_na 86 - */ 87 - struct na_parsed_sample 88 - { 89 - struct xrt_vec3_i32 accel; 90 - struct xrt_vec3_i32 gyro; 91 - struct xrt_vec3_i32 mag; 92 - 93 - int16_t accel_multiplier; 94 - int16_t gyro_multiplier; 95 - int16_t mag_multiplier; 96 - 97 - int32_t accel_divisor; 98 - int32_t gyro_divisor; 99 - int32_t mag_divisor; 100 - }; 101 - 102 - /*! 103 - * Over the wire sensor packet from the glasses. 104 - * 105 - * @ingroup drv_na 106 - */ 107 - struct na_parsed_sensor 108 - { 109 - int16_t temperature; 110 - uint64_t timestamp; 111 - 112 - struct na_parsed_sample sample; 113 - }; 114 - 115 - /*! 116 - * Over the wire sensor control data packet from the glasses. 117 - * 118 - * @ingroup drv_na 119 - */ 120 - struct na_parsed_sensor_control_data 121 - { 122 - uint16_t length; 123 - uint8_t msgid; 124 - 125 - uint8_t data[56]; 126 - }; 127 - 128 - /*! 129 - * A control packet from the glasses in wire format. 130 - * 131 - * @ingroup drv_na 132 - */ 133 - struct na_parsed_control 134 - { 135 - uint16_t length; 136 - uint64_t timestamp; 137 - uint16_t action; 138 - 139 - uint8_t data[42]; 140 - }; 141 - 142 - /*! 143 - * Create Nreal Air glasses. 144 - * 145 - * @ingroup drv_na 146 - */ 147 - struct xrt_device * 148 - na_hmd_create_device(struct os_hid_device *sensor_device, 149 - struct os_hid_device *control_device, 150 - enum u_logging_level log_level); 151 - 152 - bool 153 - na_parse_calibration_buffer(struct na_parsed_calibration *calibration, const char *buffer, size_t size); 154 - 155 - bool 156 - na_parse_sensor_packet(struct na_parsed_sensor *sensor, const uint8_t *buffer, int size); 157 - 158 - bool 159 - na_parse_sensor_control_data_packet(struct na_parsed_sensor_control_data *data, const uint8_t *buffer, int size); 160 - 161 - bool 162 - na_parse_control_packet(struct na_parsed_control *control, const uint8_t *buffer, int size); 163 - 164 - #ifdef __cplusplus 165 - } 166 - #endif
-53
src/xrt/drivers/nreal_air/na_interface.h
··· 1 - // Copyright 2023, Tobias Frisch 2 - // SPDX-License-Identifier: BSL-1.0 3 - /*! 4 - * @file 5 - * @brief Nreal Air packet parsing implementation. 6 - * @author Tobias Frisch <thejackimonster@gmail.com> 7 - * @ingroup drv_na 8 - */ 9 - 10 - #pragma once 11 - 12 - #ifdef __cplusplus 13 - extern "C" { 14 - #endif 15 - 16 - /*! 17 - * @defgroup drv_na Nreal Air driver 18 - * @ingroup drv 19 - * 20 - * @brief Driver for the Nreal Air HMD. 21 - */ 22 - 23 - /*! 24 - * Vendor id for Nreal Air. 25 - * 26 - * @ingroup drv_na 27 - */ 28 - #define NA_VID 0x3318 29 - 30 - /*! 31 - * Product id for Nreal Air. 32 - * 33 - * @ingroup drv_na 34 - */ 35 - #define NA_PID 0x0424 36 - 37 - /*! 38 - * Builder setup for Nreal Air glasses. 39 - * 40 - * @ingroup drv_na 41 - */ 42 - struct xrt_builder * 43 - nreal_air_builder_create(void); 44 - 45 - /*! 46 - * @dir drivers/nreal_air 47 - * 48 - * @brief nreal_air files. 49 - */ 50 - 51 - #ifdef __cplusplus 52 - } 53 - #endif
+11 -9
src/xrt/drivers/nreal_air/na_packet.c src/xrt/drivers/xreal_air/xreal_air_packet.c
··· 1 - // Copyright 2023, Tobias Frisch 1 + // Copyright 2023-2024, Tobias Frisch 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file 5 - * @brief Nreal Air packet parsing implementation. 5 + * @brief Xreal Air packet parsing implementation. 6 6 * @author Tobias Frisch <thejackimonster@gmail.com> 7 - * @ingroup drv_na 7 + * @ingroup drv_xreal_air 8 8 */ 9 9 10 10 #include "xrt/xrt_compiler.h" 11 11 12 - #include "na_hmd.h" 12 + #include "xreal_air_hmd.h" 13 13 14 14 #include <cjson/cJSON.h> 15 15 #include <string.h> ··· 203 203 */ 204 204 205 205 static void 206 - read_sample(const uint8_t **buffer, struct na_parsed_sample *sample) 206 + read_sample(const uint8_t **buffer, struct xreal_air_parsed_sample *sample) 207 207 { 208 208 read_i16(buffer, &sample->gyro_multiplier); 209 209 read_i32(buffer, &sample->gyro_divisor); ··· 235 235 */ 236 236 237 237 bool 238 - na_parse_calibration_buffer(struct na_parsed_calibration *calibration, const char *buffer, size_t size) 238 + xreal_air_parse_calibration_buffer(struct xreal_air_parsed_calibration *calibration, const char *buffer, size_t size) 239 239 { 240 240 cJSON *root = cJSON_ParseWithLength(buffer, size); 241 241 ··· 259 259 } 260 260 261 261 bool 262 - na_parse_sensor_packet(struct na_parsed_sensor *sensor, const uint8_t *buffer, int size) 262 + xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, const uint8_t *buffer, int size) 263 263 { 264 264 const uint8_t *start = buffer; 265 265 ··· 293 293 } 294 294 295 295 bool 296 - na_parse_sensor_control_data_packet(struct na_parsed_sensor_control_data *data, const uint8_t *buffer, int size) 296 + xreal_air_parse_sensor_control_data_packet(struct xreal_air_parsed_sensor_control_data *data, 297 + const uint8_t *buffer, 298 + int size) 297 299 { 298 300 const uint8_t *start = buffer; 299 301 ··· 320 322 } 321 323 322 324 bool 323 - na_parse_control_packet(struct na_parsed_control *control, const uint8_t *buffer, int size) 325 + xreal_air_parse_control_packet(struct xreal_air_parsed_control *control, const uint8_t *buffer, int size) 324 326 { 325 327 const uint8_t *start = buffer; 326 328
+168
src/xrt/drivers/xreal_air/xreal_air_hmd.h
··· 1 + // Copyright 2023-2024, Tobias Frisch 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Xreal Air packet parsing implementation. 6 + * @author Tobias Frisch <thejackimonster@gmail.com> 7 + * @ingroup drv_xreal_air 8 + */ 9 + 10 + #pragma once 11 + 12 + #include "xrt/xrt_device.h" 13 + #include "xrt/xrt_prober.h" 14 + 15 + #include "os/os_hid.h" 16 + 17 + #include "util/u_logging.h" 18 + 19 + #ifdef __cplusplus 20 + extern "C" { 21 + #endif 22 + 23 + #define XREAL_AIR_HANDLE_IFACE 3 24 + #define XREAL_AIR_CONTROL_IFACE 4 25 + 26 + #define XREAL_AIR_MSG_R_BRIGHTNESS 0x03 27 + #define XREAL_AIR_MSG_W_BRIGHTNESS 0x04 28 + #define XREAL_AIR_MSG_R_DISP_MODE 0x07 29 + #define XREAL_AIR_MSG_W_DISP_MODE 0x08 30 + 31 + #define XREAL_AIR_MSG_P_START_HEARTBEAT 0x6c02 32 + #define XREAL_AIR_MSG_P_BUTTON_PRESSED 0x6C05 33 + #define XREAL_AIR_MSG_P_END_HEARTBEAT 0x6c12 34 + #define XREAL_AIR_MSG_P_ASYNC_TEXT_LOG 0x6c09 35 + 36 + #define XREAL_AIR_BUTTON_PHYS_DISPLAY_TOGGLE 0x1 37 + #define XREAL_AIR_BUTTON_PHYS_BRIGHTNESS_UP 0x2 38 + #define XREAL_AIR_BUTTON_PHYS_BRIGHTNESS_DOWN 0x3 39 + 40 + #define XREAL_AIR_BUTTON_VIRT_DISPLAY_TOGGLE 0x1 41 + #define XREAL_AIR_BUTTON_VIRT_MENU_TOGGLE 0x3 42 + #define XREAL_AIR_BUTTON_VIRT_BRIGHTNESS_UP 0x6 43 + #define XREAL_AIR_BUTTON_VIRT_BRIGHTNESS_DOWN 0x7 44 + #define XREAL_AIR_BUTTON_VIRT_MODE_UP 0x8 45 + #define XREAL_AIR_BUTTON_VIRT_MODE_DOWN 0x9 46 + 47 + #define XREAL_AIR_BRIGHTNESS_MIN 0 48 + #define XREAL_AIR_BRIGHTNESS_MAX 7 49 + 50 + #define XREAL_AIR_DISPLAY_MODE_2D 0x1 51 + #define XREAL_AIR_DISPLAY_MODE_3D 0x3 52 + 53 + #define XREAL_AIR_TICKS_PER_SECOND (1000.0) // 1 KHz ticks 54 + #define XREAL_AIR_NS_PER_TICK (1000000) // Each tick is a millisecond 55 + 56 + #define XREAL_AIR_MSG_GET_CAL_DATA_LENGTH 0x14 57 + #define XREAL_AIR_MSG_CAL_DATA_GET_NEXT_SEGMENT 0x15 58 + #define XREAL_AIR_MSG_ALLOCATE_CAL_DATA_BUFFER 0x16 59 + #define XREAL_AIR_MSG_WRITE_CAL_DATA_SEGMENT 0x17 60 + #define XREAL_AIR_MSG_FREE_CAL_BUFFER 0x18 61 + #define XREAL_AIR_MSG_START_IMU_DATA 0x19 62 + #define XREAL_AIR_MSG_GET_STATIC_ID 0x1A 63 + #define XREAL_AIR_MSG_UNKNOWN 0x1D 64 + 65 + struct xreal_air_parsed_calibration 66 + { 67 + struct xrt_vec3 accel_bias; 68 + struct xrt_quat accel_q_gyro; 69 + struct xrt_vec3 gyro_bias; 70 + struct xrt_quat gyro_q_mag; 71 + struct xrt_vec3 mag_bias; 72 + 73 + struct xrt_vec3 scale_accel; 74 + struct xrt_vec3 scale_gyro; 75 + struct xrt_vec3 scale_mag; 76 + 77 + float imu_noises[4]; 78 + }; 79 + 80 + /*! 81 + * A parsed single gyroscope, accelerometer and 82 + * magnetometer sample with their corresponding 83 + * factors for conversion from raw data. 84 + * 85 + * @ingroup drv_xreal_air 86 + */ 87 + struct xreal_air_parsed_sample 88 + { 89 + struct xrt_vec3_i32 accel; 90 + struct xrt_vec3_i32 gyro; 91 + struct xrt_vec3_i32 mag; 92 + 93 + int16_t accel_multiplier; 94 + int16_t gyro_multiplier; 95 + int16_t mag_multiplier; 96 + 97 + int32_t accel_divisor; 98 + int32_t gyro_divisor; 99 + int32_t mag_divisor; 100 + }; 101 + 102 + /*! 103 + * Over the wire sensor packet from the glasses. 104 + * 105 + * @ingroup drv_xreal_air 106 + */ 107 + struct xreal_air_parsed_sensor 108 + { 109 + int16_t temperature; 110 + uint64_t timestamp; 111 + 112 + struct xreal_air_parsed_sample sample; 113 + }; 114 + 115 + /*! 116 + * Over the wire sensor control data packet from the glasses. 117 + * 118 + * @ingroup drv_xreal_air 119 + */ 120 + struct xreal_air_parsed_sensor_control_data 121 + { 122 + uint16_t length; 123 + uint8_t msgid; 124 + 125 + uint8_t data[56]; 126 + }; 127 + 128 + /*! 129 + * A control packet from the glasses in wire format. 130 + * 131 + * @ingroup drv_xreal_air 132 + */ 133 + struct xreal_air_parsed_control 134 + { 135 + uint16_t length; 136 + uint64_t timestamp; 137 + uint16_t action; 138 + 139 + uint8_t data[42]; 140 + }; 141 + 142 + /*! 143 + * Create Xreal Air glasses. 144 + * 145 + * @ingroup drv_xreal_air 146 + */ 147 + struct xrt_device * 148 + xreal_air_hmd_create_device(struct os_hid_device *sensor_device, 149 + struct os_hid_device *control_device, 150 + enum u_logging_level log_level); 151 + 152 + bool 153 + xreal_air_parse_calibration_buffer(struct xreal_air_parsed_calibration *calibration, const char *buffer, size_t size); 154 + 155 + bool 156 + xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, const uint8_t *buffer, int size); 157 + 158 + bool 159 + xreal_air_parse_sensor_control_data_packet(struct xreal_air_parsed_sensor_control_data *data, 160 + const uint8_t *buffer, 161 + int size); 162 + 163 + bool 164 + xreal_air_parse_control_packet(struct xreal_air_parsed_control *control, const uint8_t *buffer, int size); 165 + 166 + #ifdef __cplusplus 167 + } 168 + #endif
+67
src/xrt/drivers/xreal_air/xreal_air_interface.h
··· 1 + // Copyright 2023-2024, Tobias Frisch 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Xreal Air packet parsing implementation. 6 + * @author Tobias Frisch <thejackimonster@gmail.com> 7 + * @ingroup drv_xreal_air 8 + */ 9 + 10 + #pragma once 11 + 12 + #ifdef __cplusplus 13 + extern "C" { 14 + #endif 15 + 16 + /*! 17 + * @defgroup drv_xreal_air Xreal Air driver 18 + * @ingroup drv 19 + * 20 + * @brief Driver for the Xreal Air HMD. 21 + */ 22 + 23 + /*! 24 + * Vendor id for Xreal Air. 25 + * 26 + * @ingroup drv_xreal_air 27 + */ 28 + #define XREAL_AIR_VID 0x3318 29 + 30 + /*! 31 + * Product id for Xreal Air. 32 + * 33 + * @ingroup drv_xreal_air 34 + */ 35 + #define XREAL_AIR_PID 0x0424 36 + 37 + /*! 38 + * Product id for Xreal Air 2. 39 + * 40 + * @ingroup drv_xreal_air 41 + */ 42 + #define XREAL_AIR_2_PID 0x0428 43 + 44 + /*! 45 + * Product id for Xreal Air 2 Pro. 46 + * 47 + * @ingroup drv_xreal_air 48 + */ 49 + #define XREAL_AIR_2_PRO_PID 0x0432 50 + 51 + /*! 52 + * Builder setup for Xreal Air glasses. 53 + * 54 + * @ingroup drv_xreal_air 55 + */ 56 + struct xrt_builder * 57 + xreal_air_builder_create(void); 58 + 59 + /*! 60 + * @dir drivers/xreal_air 61 + * 62 + * @brief xreal_air files. 63 + */ 64 + 65 + #ifdef __cplusplus 66 + } 67 + #endif
+9 -9
src/xrt/targets/common/CMakeLists.txt
··· 44 44 target_sources(target_lists PRIVATE target_builder_simulavr.c) 45 45 endif() 46 46 47 - if(XRT_BUILD_DRIVER_NA) 48 - target_sources(target_lists PRIVATE target_builder_nreal_air.c) 49 - target_link_libraries(target_lists PRIVATE drv_na) 50 - endif() 51 - 52 47 if(XRT_BUILD_DRIVER_NS) 53 48 target_sources(target_lists PRIVATE target_builder_north_star.c) 54 49 target_link_libraries(target_lists PRIVATE drv_ns) ··· 62 57 if(XRT_BUILD_DRIVER_QWERTY) 63 58 target_sources(target_lists PRIVATE target_builder_qwerty.c) 64 59 target_link_libraries(target_lists PRIVATE drv_qwerty) 60 + endif() 61 + 62 + if(XRT_BUILD_DRIVER_XREAL_AIR) 63 + target_sources(target_lists PRIVATE target_builder_xreal_air.c) 64 + target_link_libraries(target_lists PRIVATE drv_xreal_air) 65 65 endif() 66 66 67 67 ### ··· 92 92 93 93 if(XRT_BUILD_DRIVER_HYDRA) 94 94 target_link_libraries(target_lists PRIVATE drv_hydra) 95 - endif() 96 - 97 - if(XRT_BUILD_DRIVER_NA) 98 - target_link_libraries(target_lists PRIVATE drv_na) 99 95 endif() 100 96 101 97 if(XRT_BUILD_DRIVER_NS) ··· 191 187 192 188 if(XRT_BUILD_DRIVER_WMR) 193 189 target_link_libraries(target_lists PRIVATE drv_wmr) 190 + endif() 191 + 192 + if(XRT_BUILD_DRIVER_XREAL_AIR) 193 + target_link_libraries(target_lists PRIVATE drv_xreal_air) 194 194 endif() 195 195 196 196 if(XRT_BUILD_DRIVER_EUROC)
-201
src/xrt/targets/common/target_builder_nreal_air.c
··· 1 - // Copyright 2023, Tobias Frisch 2 - // SPDX-License-Identifier: BSL-1.0 3 - /*! 4 - * @file 5 - * @brief Nreal Air prober code. 6 - * @author Tobias Frisch <thejackimonster@gmail.com> 7 - * @ingroup drv_na 8 - */ 9 - 10 - #include <assert.h> 11 - #include <stdio.h> 12 - #include <stdlib.h> 13 - #include <wchar.h> 14 - 15 - #include "os/os_hid.h" 16 - 17 - #include "xrt/xrt_config_drivers.h" 18 - #include "xrt/xrt_prober.h" 19 - 20 - #include "util/u_builders.h" 21 - #include "util/u_misc.h" 22 - #include "util/u_debug.h" 23 - #include "util/u_logging.h" 24 - #include "util/u_system_helpers.h" 25 - #include "util/u_trace_marker.h" 26 - 27 - #include "nreal_air/na_hmd.h" 28 - #include "nreal_air/na_interface.h" 29 - 30 - enum u_logging_level nreal_air_log_level; 31 - 32 - #define NA_WARN(...) U_LOG_IFL_W(nreal_air_log_level, __VA_ARGS__) 33 - #define NA_ERROR(...) U_LOG_IFL_E(nreal_air_log_level, __VA_ARGS__) 34 - 35 - 36 - /* 37 - * 38 - * Misc stuff. 39 - * 40 - */ 41 - 42 - DEBUG_GET_ONCE_LOG_OPTION(nreal_air_log, "NA_LOG", U_LOGGING_WARN) 43 - 44 - static const char *driver_list[] = { 45 - "nreal_air", 46 - }; 47 - 48 - 49 - /* 50 - * 51 - * Member functions. 52 - * 53 - */ 54 - 55 - static xrt_result_t 56 - nreal_air_estimate_system(struct xrt_builder *xb, 57 - cJSON *config, 58 - struct xrt_prober *xp, 59 - struct xrt_builder_estimate *estimate) 60 - { 61 - struct xrt_prober_device **xpdevs = NULL; 62 - size_t xpdev_count = 0; 63 - xrt_result_t xret = XRT_SUCCESS; 64 - 65 - U_ZERO(estimate); 66 - 67 - xret = xrt_prober_lock_list(xp, &xpdevs, &xpdev_count); 68 - if (xret != XRT_SUCCESS) { 69 - return xret; 70 - } 71 - 72 - struct xrt_prober_device *dev = 73 - u_builder_find_prober_device(xpdevs, xpdev_count, NA_VID, NA_PID, XRT_BUS_TYPE_USB); 74 - if (dev != NULL) { 75 - estimate->certain.head = true; 76 - } 77 - 78 - xret = xrt_prober_unlock_list(xp, &xpdevs); 79 - assert(xret == XRT_SUCCESS); 80 - 81 - return XRT_SUCCESS; 82 - } 83 - 84 - static xrt_result_t 85 - nreal_air_open_system_impl(struct xrt_builder *xb, 86 - cJSON *config, 87 - struct xrt_prober *xp, 88 - struct xrt_tracking_origin *origin, 89 - struct xrt_system_devices *xsysd, 90 - struct xrt_frame_context *xfctx, 91 - struct u_builder_roles_helper *ubrh) 92 - { 93 - struct xrt_prober_device **xpdevs = NULL; 94 - size_t xpdev_count = 0; 95 - xrt_result_t xret = XRT_SUCCESS; 96 - 97 - DRV_TRACE_MARKER(); 98 - 99 - nreal_air_log_level = debug_get_log_option_nreal_air_log(); 100 - 101 - xret = xrt_prober_lock_list(xp, &xpdevs, &xpdev_count); 102 - if (xret != XRT_SUCCESS) { 103 - goto unlock_and_fail; 104 - } 105 - 106 - struct xrt_prober_device *dev_hmd = 107 - u_builder_find_prober_device(xpdevs, xpdev_count, NA_VID, NA_PID, XRT_BUS_TYPE_USB); 108 - if (dev_hmd == NULL) { 109 - goto unlock_and_fail; 110 - } 111 - 112 - struct os_hid_device *hid_handle = NULL; 113 - int result = xrt_prober_open_hid_interface(xp, dev_hmd, NA_HANDLE_IFACE, &hid_handle); 114 - if (result != 0) { 115 - NA_ERROR("Failed to open Nreal Air handle interface"); 116 - goto unlock_and_fail; 117 - } 118 - 119 - struct os_hid_device *hid_control = NULL; 120 - result = xrt_prober_open_hid_interface(xp, dev_hmd, NA_CONTROL_IFACE, &hid_control); 121 - if (result != 0) { 122 - os_hid_destroy(hid_handle); 123 - NA_ERROR("Failed to open Nreal Air control interface"); 124 - goto unlock_and_fail; 125 - } 126 - 127 - unsigned char hmd_serial_no[XRT_DEVICE_NAME_LEN]; 128 - result = xrt_prober_get_string_descriptor(xp, dev_hmd, XRT_PROBER_STRING_SERIAL_NUMBER, hmd_serial_no, 129 - XRT_DEVICE_NAME_LEN); 130 - if (result < 0) { 131 - NA_WARN("Could not read Nreal Air serial number from USB"); 132 - snprintf((char *)hmd_serial_no, XRT_DEVICE_NAME_LEN, "Unknown"); 133 - } 134 - 135 - xret = xrt_prober_unlock_list(xp, &xpdevs); 136 - if (xret != XRT_SUCCESS) { 137 - goto fail; 138 - } 139 - 140 - struct xrt_device *na_device = na_hmd_create_device(hid_handle, hid_control, nreal_air_log_level); 141 - if (na_device == NULL) { 142 - NA_ERROR("Failed to initialise Nreal Air driver"); 143 - goto fail; 144 - } 145 - 146 - // Add to device list. 147 - xsysd->xdevs[xsysd->xdev_count++] = na_device; 148 - 149 - // Assign to role(s). 150 - ubrh->head = na_device; 151 - 152 - return XRT_SUCCESS; 153 - 154 - 155 - /* 156 - * Error path. 157 - */ 158 - 159 - unlock_and_fail: 160 - xret = xrt_prober_unlock_list(xp, &xpdevs); 161 - if (xret != XRT_SUCCESS) { 162 - return xret; 163 - } 164 - 165 - /* Fallthrough */ 166 - fail: 167 - return XRT_ERROR_DEVICE_CREATION_FAILED; 168 - } 169 - 170 - static void 171 - nreal_air_destroy(struct xrt_builder *xb) 172 - { 173 - free(xb); 174 - } 175 - 176 - 177 - /* 178 - * 179 - * 'Exported' functions. 180 - * 181 - */ 182 - 183 - struct xrt_builder * 184 - nreal_air_builder_create(void) 185 - { 186 - struct u_builder *ub = U_TYPED_CALLOC(struct u_builder); 187 - 188 - // xrt_builder fields. 189 - ub->base.estimate_system = nreal_air_estimate_system; 190 - ub->base.open_system = u_builder_open_system_static_roles; 191 - ub->base.destroy = nreal_air_destroy; 192 - ub->base.identifier = "nreal_air"; 193 - ub->base.name = "Nreal Air"; 194 - ub->base.driver_identifiers = driver_list; 195 - ub->base.driver_identifier_count = ARRAY_SIZE(driver_list); 196 - 197 - // u_builder fields. 198 - ub->open_system_static_roles = nreal_air_open_system_impl; 199 - 200 - return &ub->base; 201 - }
+237
src/xrt/targets/common/target_builder_xreal_air.c
··· 1 + // Copyright 2023-2024, Tobias Frisch 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Xreal Air prober code. 6 + * @author Tobias Frisch <thejackimonster@gmail.com> 7 + * @ingroup drv_xreal_air 8 + */ 9 + 10 + #include <assert.h> 11 + #include <stdint.h> 12 + #include <stdio.h> 13 + #include <stdlib.h> 14 + #include <wchar.h> 15 + 16 + #include "os/os_hid.h" 17 + 18 + #include "xrt/xrt_config_drivers.h" 19 + #include "xrt/xrt_prober.h" 20 + 21 + #include "util/u_builders.h" 22 + #include "util/u_misc.h" 23 + #include "util/u_debug.h" 24 + #include "util/u_logging.h" 25 + #include "util/u_system_helpers.h" 26 + #include "util/u_trace_marker.h" 27 + 28 + #include "xreal_air/xreal_air_hmd.h" 29 + #include "xreal_air/xreal_air_interface.h" 30 + 31 + enum u_logging_level xreal_air_log_level; 32 + 33 + #define XREAL_AIR_WARN(...) U_LOG_IFL_W(xreal_air_log_level, __VA_ARGS__) 34 + #define XREAL_AIR_ERROR(...) U_LOG_IFL_E(xreal_air_log_level, __VA_ARGS__) 35 + 36 + 37 + /* 38 + * 39 + * Misc stuff. 40 + * 41 + */ 42 + 43 + DEBUG_GET_ONCE_LOG_OPTION(xreal_air_log, "XREAL_AIR_LOG", U_LOGGING_WARN) 44 + 45 + static const char *driver_list[] = { 46 + "xreal_air", 47 + }; 48 + 49 + #define XREAL_AIR_DRIVER_PRODUCT_IDS 3 50 + 51 + static const uint16_t driver_product_ids[XREAL_AIR_DRIVER_PRODUCT_IDS] = { 52 + XREAL_AIR_PID, 53 + XREAL_AIR_2_PID, 54 + XREAL_AIR_2_PRO_PID, 55 + }; 56 + 57 + 58 + /* 59 + * 60 + * Member functions. 61 + * 62 + */ 63 + 64 + static xrt_result_t 65 + xreal_air_estimate_system(struct xrt_builder *xb, 66 + cJSON *config, 67 + struct xrt_prober *xp, 68 + struct xrt_builder_estimate *estimate) 69 + { 70 + struct xrt_prober_device **xpdevs = NULL; 71 + size_t xpdev_count = 0; 72 + xrt_result_t xret = XRT_SUCCESS; 73 + 74 + U_ZERO(estimate); 75 + 76 + xret = xrt_prober_lock_list(xp, &xpdevs, &xpdev_count); 77 + 78 + if (xret != XRT_SUCCESS) { 79 + return xret; 80 + } 81 + 82 + struct xrt_prober_device *dev = NULL; 83 + uint16_t product_index = 0; 84 + 85 + while (product_index < XREAL_AIR_DRIVER_PRODUCT_IDS) { 86 + dev = u_builder_find_prober_device(xpdevs, xpdev_count, XREAL_AIR_VID, 87 + driver_product_ids[product_index], XRT_BUS_TYPE_USB); 88 + 89 + if (dev != NULL) 90 + break; 91 + 92 + product_index++; 93 + } 94 + 95 + if (dev != NULL) { 96 + estimate->certain.head = true; 97 + } 98 + 99 + xret = xrt_prober_unlock_list(xp, &xpdevs); 100 + assert(xret == XRT_SUCCESS); 101 + 102 + return XRT_SUCCESS; 103 + } 104 + 105 + static xrt_result_t 106 + xreal_air_open_system_impl(struct xrt_builder *xb, 107 + cJSON *config, 108 + struct xrt_prober *xp, 109 + struct xrt_tracking_origin *origin, 110 + struct xrt_system_devices *xsysd, 111 + struct xrt_frame_context *xfctx, 112 + struct u_builder_roles_helper *ubrh) 113 + { 114 + struct xrt_prober_device **xpdevs = NULL; 115 + size_t xpdev_count = 0; 116 + xrt_result_t xret = XRT_SUCCESS; 117 + 118 + DRV_TRACE_MARKER(); 119 + 120 + xreal_air_log_level = debug_get_log_option_xreal_air_log(); 121 + 122 + xret = xrt_prober_lock_list(xp, &xpdevs, &xpdev_count); 123 + if (xret != XRT_SUCCESS) { 124 + goto unlock_and_fail; 125 + } 126 + 127 + struct xrt_prober_device *dev_hmd = NULL; 128 + uint16_t product_index = 0; 129 + 130 + while (product_index < XREAL_AIR_DRIVER_PRODUCT_IDS) { 131 + dev_hmd = u_builder_find_prober_device(xpdevs, xpdev_count, XREAL_AIR_VID, 132 + driver_product_ids[product_index], XRT_BUS_TYPE_USB); 133 + 134 + if (dev_hmd != NULL) 135 + break; 136 + 137 + product_index++; 138 + } 139 + 140 + if (dev_hmd == NULL) { 141 + goto unlock_and_fail; 142 + } 143 + 144 + struct os_hid_device *hid_handle = NULL; 145 + int result = xrt_prober_open_hid_interface(xp, dev_hmd, XREAL_AIR_HANDLE_IFACE, &hid_handle); 146 + 147 + if (result != 0) { 148 + XREAL_AIR_ERROR("Failed to open Xreal Air handle interface"); 149 + goto unlock_and_fail; 150 + } 151 + 152 + struct os_hid_device *hid_control = NULL; 153 + result = xrt_prober_open_hid_interface(xp, dev_hmd, XREAL_AIR_CONTROL_IFACE, &hid_control); 154 + 155 + if (result != 0) { 156 + os_hid_destroy(hid_handle); 157 + XREAL_AIR_ERROR("Failed to open Xreal Air control interface"); 158 + goto unlock_and_fail; 159 + } 160 + 161 + unsigned char hmd_serial_no[XRT_DEVICE_NAME_LEN]; 162 + result = xrt_prober_get_string_descriptor(xp, dev_hmd, XRT_PROBER_STRING_SERIAL_NUMBER, hmd_serial_no, 163 + XRT_DEVICE_NAME_LEN); 164 + 165 + if (result < 0) { 166 + XREAL_AIR_WARN("Could not read Xreal Air serial number from USB"); 167 + snprintf((char *)hmd_serial_no, XRT_DEVICE_NAME_LEN, "Unknown"); 168 + } 169 + 170 + xret = xrt_prober_unlock_list(xp, &xpdevs); 171 + if (xret != XRT_SUCCESS) { 172 + goto fail; 173 + } 174 + 175 + struct xrt_device *xreal_air_device = xreal_air_hmd_create_device(hid_handle, hid_control, xreal_air_log_level); 176 + 177 + if (xreal_air_device == NULL) { 178 + XREAL_AIR_ERROR("Failed to initialise Xreal Air driver"); 179 + goto fail; 180 + } 181 + 182 + // Add to device list. 183 + xsysd->xdevs[xsysd->xdev_count++] = xreal_air_device; 184 + 185 + // Assign to role(s). 186 + ubrh->head = xreal_air_device; 187 + 188 + return XRT_SUCCESS; 189 + 190 + 191 + /* 192 + * Error path. 193 + */ 194 + 195 + unlock_and_fail: 196 + xret = xrt_prober_unlock_list(xp, &xpdevs); 197 + if (xret != XRT_SUCCESS) { 198 + return xret; 199 + } 200 + 201 + /* Fallthrough */ 202 + fail: 203 + return XRT_ERROR_DEVICE_CREATION_FAILED; 204 + } 205 + 206 + static void 207 + xreal_air_destroy(struct xrt_builder *xb) 208 + { 209 + free(xb); 210 + } 211 + 212 + 213 + /* 214 + * 215 + * 'Exported' functions. 216 + * 217 + */ 218 + 219 + struct xrt_builder * 220 + xreal_air_builder_create(void) 221 + { 222 + struct u_builder *ub = U_TYPED_CALLOC(struct u_builder); 223 + 224 + // xrt_builder fields. 225 + ub->base.estimate_system = xreal_air_estimate_system; 226 + ub->base.open_system = u_builder_open_system_static_roles; 227 + ub->base.destroy = xreal_air_destroy; 228 + ub->base.identifier = "xreal_air"; 229 + ub->base.name = "Xreal Air"; 230 + ub->base.driver_identifiers = driver_list; 231 + ub->base.driver_identifier_count = ARRAY_SIZE(driver_list); 232 + 233 + // u_builder fields. 234 + ub->open_system_static_roles = xreal_air_open_system_impl; 235 + 236 + return &ub->base; 237 + }
+9 -9
src/xrt/targets/common/target_lists.c
··· 1 - // Copyright 2019-2023, Collabora, Ltd. 1 + // Copyright 2019-2024, Collabora, Ltd. 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file ··· 80 80 #include "depthai/depthai_interface.h" 81 81 #endif 82 82 83 - #ifdef XRT_BUILD_DRIVER_NA 84 - #include "nreal_air/na_interface.h" 85 - #endif 86 - 87 83 #ifdef XRT_BUILD_DRIVER_WMR 88 84 #include "wmr/wmr_interface.h" 89 85 #include "wmr/wmr_common.h" 86 + #endif 87 + 88 + #ifdef XRT_BUILD_DRIVER_XREAL_AIR 89 + #include "xreal_air/xreal_air_interface.h" 90 90 #endif 91 91 92 92 #ifdef XRT_BUILD_DRIVER_EUROC ··· 136 136 t_builder_lighthouse_create, 137 137 #endif // T_BUILDER_LIGHTHOUSE 138 138 139 - #ifdef XRT_BUILD_DRIVER_NA 140 - nreal_air_builder_create, 141 - #endif // T_BUILDER_NA 142 - 143 139 #ifdef T_BUILDER_NS 144 140 t_builder_north_star_create, 145 141 #endif // T_BUILDER_NS ··· 147 143 #ifdef T_BUILDER_WMR 148 144 t_builder_wmr_create, 149 145 #endif // T_BUILDER_WMR 146 + 147 + #ifdef XRT_BUILD_DRIVER_XREAL_AIR 148 + xreal_air_builder_create, 149 + #endif // T_BUILDER_XREAL_AIR 150 150 151 151 #ifdef T_BUILDER_LEGACY 152 152 t_builder_legacy_create,