Monado OpenXR Runtime
Loading...
Searching...
No Matches
vp2_protocol.h File Reference

Vive Pro 2 HID protocol definitions. More...

#include "xrt/xrt_byte_order.h"
#include <assert.h>
#include <stdint.h>
Include dependency graph for vp2_protocol.h:

Go to the source code of this file.

Data Structures

struct  vp2_feature_header
 Header of the binary commands, the payload follows. More...
 
struct  vp2_config_read_request
 Request for VP2_COMMAND_CONFIG_READ and VP2_COMMAND_LOG_READ, sent after the report ID. More...
 
struct  vp2_transfer_start
 Payload of the start step of a write transfer. More...
 
struct  vp2_feature_event
 Payload of VP2_COMMAND_FEATURE_EVENT. More...
 
struct  vp2_feature_state
 Read with a VP2_REPORT_ID_FEATURE feature report, the MCU fills in the header itself. More...
 
struct  vp2_status_report
 Status report, sent every 50ms while VP2_FEATURE_EVENT_STATUS_REPORT is enabled. More...
 
struct  vp2_config_header
 Header of the config blob, the JSON follows. More...
 

Macros

#define VP2_DATA_SIZE   64
 Size of every report, including the report ID.
 
#define VP2_PAYLOAD_SIZE   60
 Largest payload after struct vp2_feature_header, larger ones are rejected with VP2_ACK_INVALID.
 
#define VP2_ACK_OK   "1"
 Replies of commands that only acknowledge, as ASCII after a struct vp2_feature_header with the same report ID and command.
 
#define VP2_ACK_FAILED   "-1"
 
#define VP2_ACK_INVALID   "-22"
 
#define VP2_TRANSFER_COMMAND(family, step)   ((uint16_t)(((family) << 8) | (step)))
 
#define VP2_TRANSFER_CRC_SEED   0x56697665u
 Starting value of the transfer CRC-32, "Vive" in ASCII. In zlib terms the CRC is crc32(VP2_TRANSFER_CRC_SEED, data).
 
#define VP2_CONFIG_HEADER_SIZE   128
 Size of the header in front of the JSON in the config blob, struct vp2_config_header.
 
#define VP2_CONFIG_MAX_SIZE   0x8000
 Largest config blob the MCU will return, including the header.
 
#define VP2_CONFIG_MAGIC   0x3EE4DFDCu
 Magic of struct vp2_config_header, the CRC-32 of "viveconfig".
 
#define VP2_FEATURE_EVENT_STATUS_REPORT   (1ull << 0)
 Valid mask bits of struct vp2_feature_event.
 
#define VP2_FEATURE_EVENT_AMP_GAIN   (1ull << 1)
 
#define VP2_FEATURE_EVENT_BRIGHTNESS_REFRESH   (1ull << 2)
 
#define VP2_FEATURE_EVENT_AMP_POWER_LIMIT   (1ull << 3)
 
#define VP2_FEATURE_EVENT_AUDIO_ROUTE   (1ull << 5)
 
#define VP2_FEATURE_EVENT_AUDIO_PROFILE   (1ull << 6)
 
#define VP2_FEATURE_EVENT_DISPLAY_POWER   (1ull << 48)
 
#define VP2_FEATURE_EVENT_POWER_STATE   (1ull << 49)
 
#define VP2_FEATURE_EVENT_PROXIMITY_OVERRIDE   (1ull << 50)
 
#define VP2_FEATURE_EVENT_WIRELESS_AUTH   (1ull << 51)
 
#define VP2_FEATURE_EVENT_THERMAL_WATCHDOG   (1ull << 62)
 
#define VP2_DISPLAY_POWER_XOR   0xC4
 
#define VP2_POWER_STATE_XOR   0x78
 
#define VP2_PROXIMITY_OVERRIDE_XOR   0x10
 
#define VP2_THERMAL_WATCHDOG_XOR   0x80
 
#define VP2_PROXIMITY_THRESHOLD   150
 Proximity values above this mean the headset is being worn.
 
#define VP2_IPD_UNIT_METERS   0.00001f
 Unit of vp2_status_report::ipd in meters.
 

Enumerations

enum  vp2_report_id { VP2_REPORT_ID_COMMAND = 0x01 , VP2_REPORT_ID_STRING = 0x02 , VP2_REPORT_ID_STATUS = 0x03 , VP2_REPORT_ID_FEATURE }
 Report IDs. More...
 
enum  vp2_command {
  VP2_COMMAND_GET_SOFTWARE_VERSION , VP2_COMMAND_DISPLAY_REQUEST = 0x2970 , VP2_COMMAND_CODEC_REQUEST = 0x2971 , VP2_COMMAND_FEATURE_EVENT = 0x2978 ,
  VP2_COMMAND_FEATURE_STATE = 0x2987 , VP2_COMMAND_STATUS_REPORT = 0x2CD0 , VP2_COMMAND_DEBUG_REPORT = 0x2CD2 , VP2_COMMAND_SYSTEM_REBOOT = 0x5566 ,
  VP2_COMMAND_REPORT = 0x7788 , VP2_COMMAND_LOG_READ_START = 0xB0EA , VP2_COMMAND_LOG_READ = 0xB0EB , VP2_COMMAND_LOG_READ_ABORT = 0xB0EC ,
  VP2_COMMAND_LOG_READ_END = 0xB0ED , VP2_COMMAND_CONFIG_READ_START = 0xB1EA , VP2_COMMAND_CONFIG_READ = 0xB1EB , VP2_COMMAND_CONFIG_READ_ABORT = 0xB1EC ,
  VP2_COMMAND_CONFIG_READ_END = 0xB1ED
}
 Binary commands, the sub_id of struct vp2_feature_header. More...
 
enum  vp2_transfer_family {
  VP2_TRANSFER_APP = 0xA0 , VP2_TRANSFER_IAP = 0xA1 , VP2_TRANSFER_FPGA = 0xA2 , VP2_TRANSFER_AUDIO = 0xA3 ,
  VP2_TRANSFER_VBRIDGE = 0xA4 , VP2_TRANSFER_CONFIG_WRITE = 0xA5 , VP2_TRANSFER_LOG_READ = 0xB0 , VP2_TRANSFER_CONFIG_READ = 0xB1
}
 Transfers, the family is the high byte of the command and the step is the low byte, see VP2_TRANSFER_COMMAND. More...
 
enum  vp2_transfer_step { VP2_TRANSFER_STEP_START = 0xEA , VP2_TRANSFER_STEP_WORK = 0xEB , VP2_TRANSFER_STEP_ABORT = 0xEC , VP2_TRANSFER_STEP_END = 0xED }
 
enum  vp2_power_state { VP2_POWER_STATE_READY = 2 , VP2_POWER_STATE_IDLE = 3 , VP2_POWER_STATE_STANDBY = 4 , VP2_POWER_STATE_SLEEP = 5 }
 Power states for VP2_FEATURE_EVENT_POWER_STATE, the HTC driver uses ready, idle and standby. More...
 
enum  vp2_display_flags { VP2_DISPLAY_FLAG_ON = 1 << 0 , VP2_DISPLAY_FLAG_BRIDGE_ON = 1 << 5 , VP2_DISPLAY_FLAG_PANELS_INITIALIZED = 1 << 6 , VP2_DISPLAY_FLAG_WIRELESS = 1 << 7 }
 Bits of vp2_feature_state::display_flags. More...
 
enum  vp2_thermal_watchdog_flags { VP2_THERMAL_WATCHDOG_SKIP_CHECK = 1 << 0 , VP2_THERMAL_WATCHDOG_ALWAYS_FEED = 1 << 1 }
 Bits of vp2_feature_event::thermal_watchdog, before the XOR. More...
 
enum  vp2_audio_button { VP2_AUDIO_BUTTON_NONE = 0 , VP2_AUDIO_BUTTON_VOLUME_UP = 1 , VP2_AUDIO_BUTTON_VOLUME_DOWN = 2 , VP2_AUDIO_BUTTON_MUTE_MIC = 4 }
 Audio buttons in struct vp2_status_report, only one is reported at a time. More...
 
enum  vp2_proximity_trend { VP2_PROXIMITY_TREND_STEADY = 0 , VP2_PROXIMITY_TREND_FALLING = 1 , VP2_PROXIMITY_TREND_RISING = 2 }
 vp2_status_report::proximity_trend More...
 

Detailed Description

Vive Pro 2 HID protocol definitions.

Author
Beyley Cardellio ep1cm.nosp@m.1n10.nosp@m.n123@.nosp@m.gmai.nosp@m.l.com

Macro Definition Documentation

◆ VP2_ACK_OK

#define VP2_ACK_OK   "1"

Replies of commands that only acknowledge, as ASCII after a struct vp2_feature_header with the same report ID and command.

Unknown commands get VP2_ACK_INVALID.

◆ VP2_CONFIG_HEADER_SIZE

#define VP2_CONFIG_HEADER_SIZE   128

Size of the header in front of the JSON in the config blob, struct vp2_config_header.

◆ VP2_CONFIG_MAGIC

#define VP2_CONFIG_MAGIC   0x3EE4DFDCu

Magic of struct vp2_config_header, the CRC-32 of "viveconfig".

◆ VP2_CONFIG_MAX_SIZE

#define VP2_CONFIG_MAX_SIZE   0x8000

Largest config blob the MCU will return, including the header.

◆ VP2_DATA_SIZE

#define VP2_DATA_SIZE   64

Size of every report, including the report ID.

◆ VP2_FEATURE_EVENT_STATUS_REPORT

#define VP2_FEATURE_EVENT_STATUS_REPORT   (1ull << 0)

Valid mask bits of struct vp2_feature_event.

Bits 4 and 63 are accepted but do nothing.

VP2_FEATURE_EVENT_PROXIMITY_OVERRIDE and VP2_FEATURE_EVENT_WIRELESS_AUTH are only handled in wireless mode. The auth token is big endian, bit 7 of the first byte is a separate flag and the other 23 bits have to match the top 23 bits of the CRC-32 of the MCU's 12 character serial number (generated from its unique ID) followed by vp2_status_report::nonce. Once accepted the proximity override is honoured until the authentication times out.

VP2_FEATURE_EVENT_THERMAL_WATCHDOG controls a check that runs every 5 seconds: the MCU stops feeding its watchdog, and so resets itself, while vp2_status_report::thermal_adc is nonzero and below 0x371.

◆ VP2_IPD_UNIT_METERS

#define VP2_IPD_UNIT_METERS   0.00001f

Unit of vp2_status_report::ipd in meters.

◆ VP2_PAYLOAD_SIZE

#define VP2_PAYLOAD_SIZE   60

Largest payload after struct vp2_feature_header, larger ones are rejected with VP2_ACK_INVALID.

◆ VP2_PROXIMITY_THRESHOLD

#define VP2_PROXIMITY_THRESHOLD   150

Proximity values above this mean the headset is being worn.

◆ VP2_TRANSFER_CRC_SEED

#define VP2_TRANSFER_CRC_SEED   0x56697665u

Starting value of the transfer CRC-32, "Vive" in ASCII. In zlib terms the CRC is crc32(VP2_TRANSFER_CRC_SEED, data).

Enumeration Type Documentation

◆ vp2_audio_button

Audio buttons in struct vp2_status_report, only one is reported at a time.

◆ vp2_command

Binary commands, the sub_id of struct vp2_feature_header.

VP2_COMMAND_DISPLAY_REQUEST takes an ASCII request and is handled in the background, one at a time. Requests that arrive while one is still running are dropped. Some of them:

  • "wireless,<0/1>" is persisted, it has to be 0 for dtd 3 and above.
  • "dtd,<N>" selects the timing, a single digit, see enum vp2_resolution. 6 and above fall back to 0.
  • "chipreset" resets the video bridge and sets it up again with the EDID for the current dtd.
  • "setbrightness,<N>" sets the brightness, the HTC driver sends 80 to 130.
  • Getters like "fwname", "powermode", "framerate", "errcnt" and "panelstatus" put their reply in a buffer that is read with "mfg-s-hdmi" on VP2_REPORT_ID_STRING. Requests run in the same loop that handles the reports, so the reply is ready by the time the MCU handles the next report.
Enumerator
VP2_COMMAND_GET_SOFTWARE_VERSION 

Replies with the MCU version as 16 hex digits, e.g.

"0000000000203056"

VP2_COMMAND_DISPLAY_REQUEST 

ASCII display request, see above, no reply.

VP2_COMMAND_CODEC_REQUEST 

"codecreg=<reg>,<value>" or "hpampreg=<reg>,<value>" in hex, no reply

VP2_COMMAND_FEATURE_EVENT 

struct vp2_feature_event, no reply

VP2_COMMAND_FEATURE_STATE 

struct vp2_feature_state, read as a feature report

VP2_COMMAND_STATUS_REPORT 

struct vp2_status_report

VP2_COMMAND_DEBUG_REPORT 

Named by the HTC driver, never sent by the MCU.

VP2_COMMAND_SYSTEM_REBOOT 

Replies with VP2_ACK_OK, then resets the MCU.

VP2_COMMAND_REPORT 

Named by the HTC driver, never sent by the MCU.

VP2_COMMAND_LOG_READ_START 

Replies with the size of the log as a __le32, 0xFFFFFFFF if none.

VP2_COMMAND_LOG_READ 

struct vp2_config_read_request, replies with up to 60 bytes

VP2_COMMAND_LOG_READ_ABORT 

Replies with a __le32 0.

VP2_COMMAND_LOG_READ_END 

Replies with a __le32 0.

VP2_COMMAND_CONFIG_READ_START 

Replies with the size of the config blob as a __le32.

VP2_COMMAND_CONFIG_READ 

struct vp2_config_read_request, replies with up to 60 bytes

VP2_COMMAND_CONFIG_READ_ABORT 

Replies with a __le32 0.

VP2_COMMAND_CONFIG_READ_END 

Replies with a __le32 0.

◆ vp2_display_flags

Bits of vp2_feature_state::display_flags.

Enumerator
VP2_DISPLAY_FLAG_ON 

Display on.

VP2_DISPLAY_FLAG_BRIDGE_ON 

Video bridge powered.

VP2_DISPLAY_FLAG_PANELS_INITIALIZED 

Set the first time the panels power on, never cleared.

VP2_DISPLAY_FLAG_WIRELESS 

The persisted "wireless,1" display request setting.

◆ vp2_power_state

Power states for VP2_FEATURE_EVENT_POWER_STATE, the HTC driver uses ready, idle and standby.

1 is treated the same as ready.

Enumerator
VP2_POWER_STATE_READY 

Display on.

VP2_POWER_STATE_IDLE 

Display fully powered off, stays off until ready is sent.

VP2_POWER_STATE_STANDBY 

Backlights off, the panels aren't reprogrammed when going back to ready.

VP2_POWER_STATE_SLEEP 

Display and sensors off.

◆ vp2_proximity_trend

◆ vp2_report_id

Report IDs.

VP2_REPORT_ID_COMMAND and VP2_REPORT_ID_FEATURE carry the same binary commands (struct vp2_feature_header followed by the payload), the MCU handles them the same way. Commands that reply do so with an input report on the same ID.

VP2_REPORT_ID_STRING takes an ASCII command right after the report ID and replies with [id][size][ascii]. The commands start with "mfg-", "usr-" or "eng-". "mfg-r-" reads factory data and "mfg-s-" queries the hardware, but "mfg-s-" also has commands that reboot or write protect the MCU. Unknown commands reply with "-22". For example:

  • "mfg-r-devsn", "mfg-r-pcbsn", "mfg-r-pcbid" and "mfg-r-skuid" read factory strings.
  • "mfg-r-ps_info" reads the proximity sensor and its calibration.
  • "mfg-s-bridgeid" reads the video bridge chip ID, firmware version and hotplug state.
  • "mfg-s-audioinfo" reads the audio version, amp power limit, gain, sample rate and button.
  • "mfg-s-hdmi" reads the reply of the last display request getter, see VP2_COMMAND_DISPLAY_REQUEST.
  • "mfg-s-panel" reads the display flags, power state, CPLD register 3, the frame period of each panel and the video bridge IRQ line.
  • "usr-w-brightness=<N>" doesn't set the brightness, it power cycles and reprograms the panels.
Enumerator
VP2_REPORT_ID_COMMAND 

Binary commands as output reports.

VP2_REPORT_ID_STRING 

ASCII commands.

VP2_REPORT_ID_STATUS 

struct vp2_status_report

VP2_REPORT_ID_FEATURE 

Binary commands as feature reports, reading it returns struct vp2_feature_state.

◆ vp2_thermal_watchdog_flags

Bits of vp2_feature_event::thermal_watchdog, before the XOR.

Enumerator
VP2_THERMAL_WATCHDOG_SKIP_CHECK 

Don't check the thermal ADC.

VP2_THERMAL_WATCHDOG_ALWAYS_FEED 

Keep feeding the watchdog whatever the thermal ADC says.

◆ vp2_transfer_family

Transfers, the family is the high byte of the command and the step is the low byte, see VP2_TRANSFER_COMMAND.

Write transfers start with struct vp2_transfer_start, send the data in work steps of up to 60 bytes, then end with an empty end step that checks the CRC. Every step replies with VP2_ACK_OK or VP2_ACK_FAILED.

Enumerator
VP2_TRANSFER_APP 

MCU application, only handled by the bootloader.

VP2_TRANSFER_IAP 

Rewrites the bootloader, don't use.

VP2_TRANSFER_FPGA 

CPLD image.

VP2_TRANSFER_AUDIO 

Audio codec firmware.

VP2_TRANSFER_VBRIDGE 

Video bridge firmware.

VP2_TRANSFER_CONFIG_WRITE 

Rewrites the config blob, don't use.

VP2_TRANSFER_LOG_READ 

See VP2_COMMAND_LOG_READ.

VP2_TRANSFER_CONFIG_READ 

See VP2_COMMAND_CONFIG_READ.