PSVR USB Protocol

From Eleccelerator Wiki
Jump to: navigation, search

PSVR, PlayStation VR, is sold with a headset and a "processing unit". Some people report that the processing unit can be connected to any HDMI video source but with some caveats. When it is not connected to a PS4 through an USB cable: It is difficult to re-center the screen. It is impossible to adjust the virtual screen size. It is impossible to adjust the screen brightness.

Contents

Enumeration

Descriptors

Device Descriptor

0x12,        // bLength
0x01,        // bDescriptorType (Device)
0x00, 0x02,  // bcdUSB 2.00
0x00,        // bDeviceClass (Use class information in the Interface Descriptors)
0x00,        // bDeviceSubClass 
0x00,        // bDeviceProtocol 
0x40,        // bMaxPacketSize0 64
0x4C, 0x05,  // idVendor 0x054C
0xAF, 0x09,  // idProduct 0x09AF
0x07, 0x01,  // bcdDevice 2.07
0x01,        // iManufacturer (String Index)
0x02,        // iProduct (String Index)
0x00,        // iSerialNumber (String Index)
0x01,        // bNumConfigurations 1

Configuration Descriptor

0x09,        // bLength
0x02,        // bDescriptorType (Configuration)
0x7F, 0x01,  // wTotalLength 383
0x09,        // bNumInterfaces 9
0x01,        // bConfigurationValue
0x00,        // iConfiguration (String Index)
0xC0,        // bmAttributes Self Powered
0x01,        // bMaxPower 2mA

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x00,        // bInterfaceNumber 0
0x00,        // bAlternateSetting
0x00,        // bNumEndpoints 0
0xFF,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x03,        // iInterface (String Index)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x00,        // bInterfaceNumber 0
0x01,        // bAlternateSetting
0x01,        // bNumEndpoints 1
0xFF,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x03,        // iInterface (String Index)

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x01,        // bEndpointAddress (OUT/H2D)
0x05,        // bmAttributes (Isochronous, Async, Data EP)
0x00, 0x04,  // wMaxPacketSize 1024
0x01,        // bInterval 1 (unit depends on device speed)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x01,        // bInterfaceNumber 1
0x00,        // bAlternateSetting
0x00,        // bNumEndpoints 0
0x01,        // bInterfaceClass
0x01,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x04,        // iInterface (String Index)

0x0A,        // bLength
0x24,        // bDescriptorType (Unknown)
0x01, 0x00, 0x01, 0x4A, 0x00, 0x02, 0x02, 0x03, 
0x0C,        // bLength
0x24,        // bDescriptorType (Unknown)
0x02, 0x01, 0x01, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
0x09,        // bLength
0x24,        // bDescriptorType (Unknown)
0x06, 0x05, 0x01, 0x01, 0x03, 0x00, 0x00, 
0x09,        // bLength
0x24,        // bDescriptorType (Unknown)
0x03, 0x03, 0x01, 0x01, 0x00, 0x05, 0x00, 
0x0C,        // bLength
0x24,        // bDescriptorType (Unknown)
0x02, 0x02, 0x01, 0x01, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 
0x0D,        // bLength
0x24,        // bDescriptorType (Unknown)
0x06, 0x06, 0x02, 0x02, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 
0x09,        // bLength
0x24,        // bDescriptorType (Unknown)
0x03, 0x04, 0x01, 0x03, 0x00, 0x06, 0x00, 
0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x02,        // bInterfaceNumber 2
0x00,        // bAlternateSetting
0x00,        // bNumEndpoints 0
0x01,        // bInterfaceClass
0x02,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x05,        // iInterface (String Index)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x02,        // bInterfaceNumber 2
0x01,        // bAlternateSetting
0x01,        // bNumEndpoints 1
0x01,        // bInterfaceClass
0x02,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x05,        // iInterface (String Index)

0x07,        // bLength
0x24,        // bDescriptorType (Unknown)
0x01, 0x03, 0x00, 0x01, 0x00, 
0x0B,        // bLength
0x24,        // bDescriptorType (Unknown)
0x02, 0x01, 0x01, 0x02, 0x10, 0x01, 0x80, 0xBB, 0x00, 
0x09,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x82,        // bEndpointAddress (IN/D2H)
0x05,        // bmAttributes (Isochronous, Async, Data EP)
0xC0, 0x00,  // wMaxPacketSize 192
0x04,        // bInterval 4 (unit depends on device speed)
0x00, 0x00, 
0x07,        // bLength
0x25,        // bDescriptorType (Unknown)
0x01, 0x80, 0x00, 0x00, 0x00, 
0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x03,        // bInterfaceNumber 3
0x00,        // bAlternateSetting
0x00,        // bNumEndpoints 0
0x01,        // bInterfaceClass
0x02,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x06,        // iInterface (String Index)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x03,        // bInterfaceNumber 3
0x01,        // bAlternateSetting
0x01,        // bNumEndpoints 1
0x01,        // bInterfaceClass
0x02,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x06,        // iInterface (String Index)

0x07,        // bLength
0x24,        // bDescriptorType (Unknown)
0x01, 0x02, 0x00, 0x01, 0x00, 
0x0B,        // bLength
0x24,        // bDescriptorType (Unknown)
0x02, 0x01, 0x02, 0x02, 0x10, 0x01, 0x80, 0xBB, 0x00, 
0x09,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x02,        // bEndpointAddress (OUT/H2D)
0x05,        // bmAttributes (Isochronous, Async, Data EP)
0xC0, 0x00,  // wMaxPacketSize 192
0x04,        // bInterval 4 (unit depends on device speed)
0x00, 0x00, 
0x07,        // bLength
0x25,        // bDescriptorType (Unknown)
0x01, 0x80, 0x00, 0x00, 0x00, 
0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x04,        // bInterfaceNumber 4
0x00,        // bAlternateSetting
0x01,        // bNumEndpoints 1
0x03,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x07,        // iInterface (String Index)

0x09,        // bLength
0x21,        // bDescriptorType (HID)
0x11, 0x01,  // bcdHID 1.11
0x00,        // bCountryCode
0x01,        // bNumDescriptors
0x22,        // bDescriptorType[0] (HID)
0x15, 0x00,  // wDescriptorLength[0] 21

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x83,        // bEndpointAddress (IN/D2H)
0x03,        // bmAttributes (Interrupt)
0x40, 0x00,  // wMaxPacketSize 64
0x03,        // bInterval 3 (unit depends on device speed)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x05,        // bInterfaceNumber 5
0x00,        // bAlternateSetting
0x02,        // bNumEndpoints 2
0x03,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x08,        // iInterface (String Index)

0x09,        // bLength
0x21,        // bDescriptorType (HID)
0x11, 0x01,  // bcdHID 1.11
0x00,        // bCountryCode
0x01,        // bNumDescriptors
0x22,        // bDescriptorType[0] (HID)
0x17, 0x00,  // wDescriptorLength[0] 23

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x84,        // bEndpointAddress (IN/D2H)
0x03,        // bmAttributes (Interrupt)
0x40, 0x00,  // wMaxPacketSize 64
0x04,        // bInterval 4 (unit depends on device speed)

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x04,        // bEndpointAddress (OUT/H2D)
0x03,        // bmAttributes (Interrupt)
0x40, 0x00,  // wMaxPacketSize 64
0x04,        // bInterval 4 (unit depends on device speed)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x06,        // bInterfaceNumber 6
0x00,        // bAlternateSetting
0x00,        // bNumEndpoints 0
0xFF,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x09,        // iInterface (String Index)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x06,        // bInterfaceNumber 6
0x01,        // bAlternateSetting
0x01,        // bNumEndpoints 1
0xFF,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x09,        // iInterface (String Index)

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x05,        // bEndpointAddress (OUT/H2D)
0x05,        // bmAttributes (Isochronous, Async, Data EP)
0x00, 0x04,  // wMaxPacketSize 1024
0x03,        // bInterval 3 (unit depends on device speed)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x06,        // bInterfaceNumber 6
0x02,        // bAlternateSetting
0x01,        // bNumEndpoints 1
0xFF,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x00,        // iInterface (String Index)

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x05,        // bEndpointAddress (OUT/H2D)
0x05,        // bmAttributes (Isochronous, Async, Data EP)
0x00, 0x04,  // wMaxPacketSize 1024
0x02,        // bInterval 2 (unit depends on device speed)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x06,        // bInterfaceNumber 6
0x03,        // bAlternateSetting
0x01,        // bNumEndpoints 1
0xFF,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x00,        // iInterface (String Index)

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x05,        // bEndpointAddress (OUT/H2D)
0x05,        // bmAttributes (Isochronous, Async, Data EP)
0x00, 0x04,  // wMaxPacketSize 1024
0x01,        // bInterval 1 (unit depends on device speed)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x07,        // bInterfaceNumber 7
0x00,        // bAlternateSetting
0x01,        // bNumEndpoints 1
0xFF,        // bInterfaceClass
0x01,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x0A,        // iInterface (String Index)

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x87,        // bEndpointAddress (IN/D2H)
0x02,        // bmAttributes (Bulk)
0x00, 0x02,  // wMaxPacketSize 512
0x00,        // bInterval 0 (unit depends on device speed)

0x09,        // bLength
0x04,        // bDescriptorType (Interface)
0x08,        // bInterfaceNumber 8
0x00,        // bAlternateSetting
0x02,        // bNumEndpoints 2
0x03,        // bInterfaceClass
0x00,        // bInterfaceSubClass
0x00,        // bInterfaceProtocol
0x0B,        // iInterface (String Index)

0x09,        // bLength
0x21,        // bDescriptorType (HID)
0x11, 0x01,  // bcdHID 1.11
0x00,        // bCountryCode
0x01,        // bNumDescriptors
0x22,        // bDescriptorType[0] (HID)
0x9F, 0x00,  // wDescriptorLength[0] 159

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x86,        // bEndpointAddress (IN/D2H)
0x03,        // bmAttributes (Interrupt)
0x40, 0x00,  // wMaxPacketSize 64
0x04,        // bInterval 4 (unit depends on device speed)

0x07,        // bLength
0x05,        // bDescriptorType (Endpoint)
0x06,        // bEndpointAddress (OUT/H2D)
0x03,        // bmAttributes (Interrupt)
0x40, 0x00,  // wMaxPacketSize 64
0x04,        // bInterval 4 (unit depends on device speed)

// 383 bytes

HID Report Descriptors

Index 4

0x06, 0x01, 0xFF,  // Usage Page (Vendor Defined 0xFF01)
0x09, 0x01,        // Usage (0x01)
0xA1, 0x01,        // Collection (Application)
0x09, 0x10,        //   Usage (0x10)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x40,        //   Report Count (64)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

// 21 bytes

Index 5

0x06, 0x00, 0xFF,  // Usage Page (Vendor Defined 0xFF00)
0x15, 0x00,        // Logical Minimum (0)
0x26, 0xFF, 0x00,  // Logical Maximum (255)
0x09, 0x08,        // Usage (0x08)
0xA1, 0x01,        // Collection (Application)
0x09, 0x80,        //   Usage (0x80)
0x85, 0x40,        //   Report ID (64)
0x75, 0x08,        //   Report Size (8)
0x95, 0x04,        //   Report Count (4)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 23 bytes

Index 8

0x06, 0xF0, 0xFF,  // Usage Page (Vendor Defined 0xFFF0)
0x15, 0x00,        // Logical Minimum (0)
0x26, 0xFF, 0x00,  // Logical Maximum (255)
0x75, 0x08,        // Report Size (8)
0x95, 0x3F,        // Report Count (63)
0x09, 0x01,        // Usage (0x01)
0xA1, 0x01,        // Collection (Application)
0x85, 0xD0,        //   Report ID (208)
0x09, 0xD0,        //   Usage (0xD0)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xD1,        //   Report ID (209)
0x09, 0xD1,        //   Usage (0xD1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xD2,        //   Report ID (210)
0x09, 0xD2,        //   Usage (0xD2)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xD3,        //   Report ID (211)
0x09, 0xD3,        //   Usage (0xD3)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection
0x09, 0x02,        // Usage (0x02)
0xA1, 0x01,        // Collection (Application)
0x85, 0xE0,        //   Report ID (224)
0x09, 0xE0,        //   Usage (0xE0)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE1,        //   Report ID (225)
0x09, 0xE1,        //   Usage (0xE1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE2,        //   Report ID (226)
0x09, 0xE2,        //   Usage (0xE2)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE3,        //   Report ID (227)
0x09, 0xE3,        //   Usage (0xE3)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE4,        //   Report ID (228)
0x09, 0xE4,        //   Usage (0xE4)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE5,        //   Report ID (229)
0x09, 0xE5,        //   Usage (0xE5)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE6,        //   Report ID (230)
0x09, 0xE6,        //   Usage (0xE6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE7,        //   Report ID (231)
0x09, 0xE7,        //   Usage (0xE7)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE8,        //   Report ID (232)
0x09, 0xE8,        //   Usage (0xE8)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE9,        //   Report ID (233)
0x09, 0xE9,        //   Usage (0xE9)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xEF,        //   Report ID (239)
0x09, 0xEF,        //   Usage (0xEF)
0x95, 0x04,        //   Report Count (4)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection
0x09, 0x40,        // Usage (0x40)
0xA1, 0x01,        // Collection (Application)
0x85, 0xF0,        //   Report ID (240)
0x09, 0x47,        //   Usage (0x47)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF1,        //   Report ID (241)
0x09, 0x48,        //   Usage (0x48)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF2,        //   Report ID (242)
0x09, 0x49,        //   Usage (0x49)
0x95, 0x0F,        //   Report Count (15)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF3,        //   Report ID (243)
0x0A, 0x01, 0x47,  //   Usage (0x4701)
0x95, 0x07,        //   Report Count (7)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 159 bytes

Functions

For now, we are only interested in the functions I've analyzed below. This is enough to make a portable battery powered PSVR "backpack" without a PS4.

Center Screen

Endpoint 4, direction is OUT (host to device), data is

1B 00 AA 00

Adjust Screen Size/Brightness

My theory is that if the PSVR is showing the USB error icon, sending this HID packet will initialize the screen.

Endpoint 4, direction is OUT (host to device), data is

21 00 AA 10 XX YY 19 14 00 00 00 00 00 00 ZZ 00 00 00 00 00

Where XX YY changes screen size

Small:  XX YY = 00 1A
Medium: XX YY = C0 24
Large:  XX YY = C0 32

Where ZZ is screen brightness, a range between 0x00 and 0x20 (0 to 32), in steps of 1 0x00 = dimmest 0x20 = brightest

Volume Buttons

Endpoint 4, direction is IN (device to host), data is

F0 00 AA 10 XX YY 00 00 00 FF 00 00 02 00 00 00 00 00 00 00

XX is a byte containing bit flags, so far, I can see the earbuds and the mic mute button flags

No earbuds and unmuted:  XX = 0x87
No earbuds and muted:    XX = 0xA7
Yes earbuds and unmuted: XX = 0x97
Yes earbuds and muted:   XX = 0xB7

YY seems to be the volume, between 0x00 and 0x32 in steps of 2

Head Detector

Endpoint 4, direction is IN (device to host)

Same packet as above in "volume buttons"

No earbuds and unmuted, head is in:  XX = 0x87
No earbuds and unmuted, head is out: XX = 0x85

Motion Tracking

I can't identify what packet correlates to motion, even when a game is running. I think the PS4 renders everything without caring about where you are looking, and the processing unit simply has to decide which part to show you. This makes perfect sense when you think about how they are able to achieve 120FPS with reprojection and have low enough latency to not make you motion sick.

This means the long proprietary cable between the headset and the processing unit carries the data somehow.

Microphone

Endpoint 2 seems to be just 16 bit mic data. That's all I know. Take a look at the descriptor for more info.

Cryptographic Authentication

Sony is using a similar cryptographic challenge and response scheme for authenticating a PSVR. This means it is almost impossible to clone a PSVR. I am not going to investigate this any further, it's just not worth the effort.

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox