Common Structures[]
enum Direction : uint8_t {
North = 0,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest,
None = 8
};
template<int N> struct BTCRC {
uint8_t Buff[N-4];
uint32_t CRC;
};
template<int N> struct BTAudio {
uint16_t FrameNumber;
uint8_t AudioTarget; // 0x02 speaker?, 0x24 headset?, 0x03 mic?
uint8_t SBCData[N-3];
};
Input Reports[]
template<int N> struct BTGetStateDataAndAudio {
BTGetStateData State;
BTAudio<N-75> Audio;
};
struct TouchFingerData {
uint8_t Index : 7;
uint8_t NotTouching : 1;
uint16_t FingerX : 12;
uint16_t FingerY : 12;
};
struct TouchData {
uint8_t Timestamp;
TouchFingerData Finger[2];
};
struct BasicGetStateData {
/*0 */ uint8_t LeftStickX;
/*1 */ uint8_t LeftStickY;
/*2 */ uint8_t RightStickX;
/*3 */ uint8_t RightStickY;
/*4.0*/ Direction DPad : 4;
/*4.4*/ uint8_t ButtonSquare : 1;
/*4.5*/ uint8_t ButtonCross : 1;
/*4.6*/ uint8_t ButtonCircle : 1;
/*4.7*/ uint8_t ButtonTriangle : 1;
/*5.0*/ uint8_t ButtonL1 : 1;
/*5.1*/ uint8_t ButtonR1 : 1;
/*5.2*/ uint8_t ButtonL2 : 1;
/*5.3*/ uint8_t ButtonR2 : 1;
/*5.4*/ uint8_t ButtonShare : 1;
/*5.5*/ uint8_t ButtonOptions : 1;
/*5.6*/ uint8_t ButtonL3 : 1;
/*5.7*/ uint8_t ButtonR3 : 1;
/*6.0*/ uint8_t ButtonHome : 1;
/*6.1*/ uint8_t ButtonPad : 1;
/*6.2*/ uint8_t Counter : 6; // always 0 on USB, counts up with some skips on BT
/*7 */ uint8_t TriggerLeft;
/*8 */ uint8_t TriggerRight;
};
struct GetStateData : BasicGetStateData {
/* 9 */ uint16_t Timestamp; // in 5.33us units?
/*11 */ uint8_t Temperture;
/*12 */ int16_t AngularVelocityX;
/*14 */ int16_t AngularVelocityZ;
/*16 */ int16_t AngularVelocityY;
/*18 */ int16_t AccelerometerX;
/*20 */ int16_t AccelerometerY;
/*22 */ int16_t AccelerometerZ;
/*24 */ uint8_t[5] ExtData; // range can be set by EXT device
/*29 */ uint8_t PowerPercent : 4; // 0x00-0x0A or 0x01-0x0B if plugged int
/*29.4*/ uint8_t PluggedPowerCable : 1;
/*29.5*/ uint8_t PluggedHeadphones : 1;
/*29.6*/ uint8_t PluggedMic : 1;
/*29,7*/ uint8_t PluggedExt : 1;
/*30.0*/ uint8_t UnkExt1 : 1; // ExtCapableOfExtraData?
/*30.1*/ uint8_t UnkExt2 : 1; // ExtHasExtraData?
/*30.2*/ uint8_t NotConnected : 1; // Used by dongle to indicate no controller
/*30.3*/ uint8_t Unk1 : 5;
/*31 */ uint8_t Unk2; // unused?
/*32 */ uint8_t TouchCount;
};
struct USBGetStateData : GetStateData {
TouchData TouchData[3];
uint8_t Pad[3];
};
struct BTGetStateData : GetStateData {
TouchData TouchData[4];
uint8_t Pad[6];
};
HID Report 0x01 Input USB/Dongle[]
struct ReportIn01USB {
uint8_t ReportID; // 0x01
USBGetStateData State;
};
HID Report 0x01 Input BT[]
struct ReportIn01BT {
uint8_t ReportID; // 0x01
BasicGetStateData State;
};
HID Report 0x11 Input BT[]
struct ReportIn11 {
union {
BTCRC<78> CRC;
struct {
uint8_t ReportID; // 0x11
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateData State;
BTAudio<75> Audio;
};
} Data;
};
};
HID Report 0x12 Input BT[]
struct ReportIn12 {
union {
BTCRC<142> CRC;
struct {
uint8_t ReportID; // 0x12
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateDataAndAudio<139> State;
BTAudio<139> Audio;
};
} Data;
};
};
HID Report 0x13 Input BT[]
struct ReportIn13 {
union {
BTCRC<206> CRC;
struct {
uint8_t ReportID; // 0x13
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateDataAndAudio<203> State;
BTAudio<203> Audio;
};
} Data;
};
};
HID Report 0x14 Input BT[]
struct ReportIn14 {
union {
BTCRC<270> CRC;
struct {
uint8_t ReportID; // 0x14
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateDataAndAudio<267> State;
BTAudio<267> Audio;
};
} Data;
};
};
HID Report 0x15 Input BT[]
struct ReportIn15 {
union {
BTCRC<334> CRC;
struct {
uint8_t ReportID; // 0x15
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateDataAndAudio<331> State;
BTAudio<331> Audio;
};
} Data;
};
};
HID Report 0x16 Input BT[]
struct ReportIn16 {
union {
BTCRC<398> CRC;
struct {
uint8_t ReportID; // 0x16
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateDataAndAudio<395> State;
BTAudio<395> Audio;
};
} Data;
};
};
HID Report 0x17 Input BT[]
struct ReportIn17 {
union {
BTCRC<462> CRC;
struct {
uint8_t ReportID; // 0x17
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateDataAndAudio<459> State;
BTAudio<459> Audio;
};
} Data;
};
};
HID Report 0x18 Input BT[]
struct ReportIn18 {
union {
BTCRC<526> CRC;
struct {
uint8_t ReportID; // 0x18
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateDataAndAudio<523> State;
BTAudio<523> Audio;
};
} Data;
};
};
HID Report 0x19 Input BT[]
struct ReportIn19 {
union {
BTCRC<547> CRC;
struct {
uint8_t ReportID; // 0x19
uint8_t Unk1 : 6;
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t Unk2 : 7;
uint8_t EnableAudio : 1;
union {
BTGetStateDataAndAudio<544> State;
BTAudio<544> Audio;
};
} Data;
};
};
Output Reports[]
template<int N> struct BTSetStateDataAndAudio {
BTSetStateData State;
BTAudio<N-75> Audio;
};
struct USBSetStateData {
uint8_t EnableRumbleUpdate : 1;
uint8_t EnableLedUpdate : 1;
uint8_t EnableLedBlink : 1;
uint8_t EnableExtWrite : 1;
uint8_t EnableVolumeLeftUpdate : 1;
uint8_t EnableVolumeRightUpdate : 1;
uint8_t EnableVolumeMicUpdate : 1;
uint8_t EnableVolumeSpeakerUpdate : 1;
uint8_t UNK_RESET1: 1; // unknown reset, both set high by Remote Play
uint8_t UNK_RESET2: 1; // unknown reset, both set high by Remote Play
uint8_t UNK1: 1;
uint8_t UNK2: 1;
uint8_t UNK3: 1;
uint8_t UNKPad: 3;
uint8_t Empty1;
uint8_t RumbleRight; // weak
uint8_t RumbleLeft; // strong
uint8_t LedRed;
uint8_t LedGreen;
uint8_t LedBlue;
uint8_t LedFlashOnPeriod;
uint8_t LedFlashOffPeriod;
uint8_t ExtDataSend[8]; // sent to I2C EXT port, stored in 8x8 byte block
uint8_t VolumeLeft; // 0x00 - 0x4F inclusive
uint8_t VolumeRight; // 0x00 - 0x4F inclusive
uint8_t VolumeMic; // 0x00, 0x01 - 0x40 inclusive (0x00 is special behavior)
uint8_t VolumeSpeaker; // 0x00 - 0x4F
uint8_t UNK_AUDIO1 : 7; // clamped to 1-64 inclusive, appears to be set to 5 for audio
uint8_t UNK_AUDIO2: 1; // unknown, appears to be set to 1 for audio
uint8_t Pad[8];
};
struct BTSetStateData {
uint8_t EnableRumbleUpdate : 1;
uint8_t EnableLedUpdate : 1;
uint8_t EnableLedBlink : 1;
uint8_t EnableExtWrite : 1;
uint8_t EnableVolumeLeftUpdate : 1;
uint8_t EnableVolumeRightUpdate : 1;
uint8_t EnableVolumeMicUpdate : 1;
uint8_t EnableVolumeSpeakerUpdate : 1;
uint8_t UNK_RESET1: 1; // unknown reset, both set high by Remote Play
uint8_t UNK_RESET2: 1; // unknown reset, both set high by Remote Play
uint8_t UNK1: 1;
uint8_t UNK2: 1;
uint8_t UNK3: 1;
uint8_t UNKPad: 3;
uint8_t Empty1;
uint8_t RumbleRight; // weak
uint8_t RumbleLeft; // strong
uint8_t LedRed;
uint8_t LedGreen
uint8_t LedBlue;
uint8_t LedFlashOnPeriod;
uint8_t LedFlashOffPeriod;
uint8_t ExtDataSend[8]; // sent to I2C EXT port, stored in 8x8 byte block
uint8_t VolumeLeft; // 0x00 - 0x4F inclusive
uint8_t VolumeRight; // 0x00 - 0x4F inclusive
uint8_t VolumeMic; // 0x00, 0x01 - 0x40 inclusive (0x00 is special behavior)
uint8_t VolumeSpeaker; // 0x00 - 0x4F
uint8_t UNK_AUDIO1 : 7; // clamped to 1-64 inclusive, appears to be set to 5 for audio
uint8_t UNK_AUDIO2: 1; // unknown, appears to be set to 1 for audio
uint8_t Pad[52];
};
HID Report 0x05 Output USB/Dongle[]
struct ReportIn05 {
uint8_t ReportID; // 0x05
USBSetStateData State;
};
HID Report 0x11 Output BT[]
struct ReportOut11 {
union {
BTCRC<78> CRC;
struct {
uint8_t ReportID; // 0x11
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateData State;
BTAudio<75> Audio;
};
} Data;
};
};
HID Report 0x12 Output BT[]
struct ReportOut12 {
union {
BTCRC<142> CRC;
struct {
uint8_t ReportID; // 0x12
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateDataAndAudio<139> State;
BTAudio<139> Audio;
};
} Data;
};
};
HID Report 0x13 Output BT[]
struct ReportOut13 {
union {
BTCRC<206> CRC;
struct {
uint8_t ReportID; // 0x13
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateDataAndAudio<203> State;
BTAudio<203> Audio;
};
} Data;
};
};
HID Report 0x14 Output BT[]
struct ReportOut14 {
union {
BTCRC<270> CRC;
struct {
uint8_t ReportID; // 0x14
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateDataAndAudio<267> State;
BTAudio<267> Audio;
};
} Data;
};
};
HID Report 0x15 Output BT[]
struct ReportOut15 {
union {
BTCRC<334> CRC;
struct {
uint8_t ReportID; // 0x15
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateDataAndAudio<331> State;
BTAudio<331> Audio;
};
} Data;
};
};
HID Report 0x16 Output BT[]
struct ReportOut16 {
union {
BTCRC<398> CRC;
struct {
uint8_t ReportID; // 0x16
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateDataAndAudio<395> State;
BTAudio<395> Audio;
};
} Data;
};
};
HID Report 0x17 Output BT[]
struct ReportOut17 {
union {
BTCRC<462> CRC;
struct {
uint8_t ReportID; // 0x17
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateDataAndAudio<459> State;
BTAudio<459> Audio;
};
} Data;
};
};
HID Report 0x18 Output BT[]
struct ReportOut18 {
union {
BTCRC<526> CRC;
struct {
uint8_t ReportID; // 0x18
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateDataAndAudio<523> State;
BTAudio<523> Audio;
};
} Data;
};
};
HID Report 0x19 Output BT[]
struct ReportOut19 {
union {
BTCRC<547> CRC;
struct {
uint8_t ReportID; // 0x19
uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
uint8_t EnableCRC : 1;
uint8_t EnableHID : 1;
uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
uint8_t UnkA4 : 1;
uint8_t UnkB1 : 1;
uint8_t UnkB2 : 1; // seems to always be 1
uint8_t UnkB3 : 1;
uint8_t EnableAudio : 1;
union {
BTSetStateDataAndAudio<544> State;
BTAudio<544> Audio;
};
} Data;
};
};
Feature Reports[]
Calibration[]
Reading calibration is required to switch input reports from the truncated 0x01 report to the expanded 0x11-0x19 reports.
Linux hid-sony.c
/* Set gyroscope calibration and normalization parameters.
* Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s.
*/
speed_2x = (gyro_speed_plus + gyro_speed_minus);
sc->ds4_calib_data[0].abs_code = ABS_RX;
sc->ds4_calib_data[0].bias = gyro_pitch_bias;
sc->ds4_calib_data[0].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
sc->ds4_calib_data[0].sens_denom = gyro_pitch_plus - gyro_pitch_minus;
sc->ds4_calib_data[1].abs_code = ABS_RY;
sc->ds4_calib_data[1].bias = gyro_yaw_bias;
sc->ds4_calib_data[1].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
sc->ds4_calib_data[1].sens_denom = gyro_yaw_plus - gyro_yaw_minus;
sc->ds4_calib_data[2].abs_code = ABS_RZ;
sc->ds4_calib_data[2].bias = gyro_roll_bias;
sc->ds4_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
sc->ds4_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus;
/* Set accelerometer calibration and normalization parameters.
* Data values will be normalized to 1/DS4_ACC_RES_PER_G G.
*/
range_2g = acc_x_plus - acc_x_minus;
sc->ds4_calib_data[3].abs_code = ABS_X;
sc->ds4_calib_data[3].bias = acc_x_plus - range_2g / 2;
sc->ds4_calib_data[3].sens_numer = 2*DS4_ACC_RES_PER_G;
sc->ds4_calib_data[3].sens_denom = range_2g;
range_2g = acc_y_plus - acc_y_minus;
sc->ds4_calib_data[4].abs_code = ABS_Y;
sc->ds4_calib_data[4].bias = acc_y_plus - range_2g / 2;
sc->ds4_calib_data[4].sens_numer = 2*DS4_ACC_RES_PER_G;
sc->ds4_calib_data[4].sens_denom = range_2g;
range_2g = acc_z_plus - acc_z_minus;
sc->ds4_calib_data[5].abs_code = ABS_Z;
sc->ds4_calib_data[5].bias = acc_z_plus - range_2g / 2;
sc->ds4_calib_data[5].sens_numer = 2*DS4_ACC_RES_PER_G;
sc->ds4_calib_data[5].sens_denom = range_2g;
In Remote Play, version 17 controllers lock GyroSpeedPlus and GyroSpeedMinus to 540
In Remote Play, a version of 18 or lower sets MotionDataTimestampUnits to 7.0999999
In Remote Play, a version over 18 sets MotionDataTimestampUnits to 5.3299999
What this value is used for is unclear.
Version comes from the device's revision number and is bashed from hex to decimal. (0x1F93 -> 1993)
USB 0x02[]
struct ReportFeatureInCalibrateUSB {
uint8_t ReportID; // 0x02
int16_t GyroPitchBias;
int16_t GyroYawBias;
int16_t GyroRollBias;
int16_t GyroPitchPlus;
int16_t GyroPitchMinus;
int16_t GyroYawPlus;
int16_t GyroYawMinus;
int16_t GyroRollPlus;
int16_t GyroRollMinus;
int16_t GyroSpeedPlus;
int16_t GyroSpeedMinus;
int16_t AccelXPlus;
int16_t AccelXMinus;
int16_t AccelYPlus;
int16_t AccelYMinus;
int16_t AccelZPlus;
int16_t AccelZMinus;
int16_t Unknown;
};
Bluetooth 0x05[]
struct ReportFeatureInCalibrateBT {
union {
BTCRC<41> CRC;
struct {
uint8_t ReportID; // 0x05
int16_t GyroPitchBias;
int16_t GyroYawBias;
int16_t GyroRollBias;
int16_t GyroPitchPlus;
int16_t GyroYawPlus;
int16_t GyroRollPlus;
int16_t GyroPitchMinus;
int16_t GyroYawMinus;
int16_t GyroRollMinus;
int16_t GyroSpeedPlus;
int16_t GyroSpeedMinus;
int16_t AccelXPlus;
int16_t AccelXMinus;
int16_t AccelYPlus;
int16_t AccelYMinus;
int16_t AccelZPlus;
int16_t AccelZMinus;
int16_t Unknown;
} Data;
}
};
Dongle 0x02[]
struct ReportFeatureInCalibrateDongle {
uint8_t ReportID; // 0x02
int16_t GyroPitchBias;
int16_t GyroYawBias;
int16_t GyroRollBias;
int16_t GyroPitchPlus;
int16_t GyroYawPlus;
int16_t GyroRollPlus;
int16_t GyroPitchMinus;
int16_t GyroYawMinus;
int16_t GyroRollMinus;
int16_t GyroSpeedPlus;
int16_t GyroSpeedMinus;
int16_t AccelXPlus;
int16_t AccelXMinus;
int16_t AccelYPlus;
int16_t AccelYMinus;
int16_t AccelZPlus;
int16_t AccelZMinus;
int16_t Unknown;
};
MAC[]
Need to confirm these on BT
Get All MAC USB/Dongle 0x12[]
struct ReportFeatureInMacAll {
uint8_t ReportID; // 0x12 (0x09 for BT)
uint8_t[6] ClientMac; // Right to Left
uint8_t Hard08;
uint8_t Hard25;
uint8_t Hard00;
uint8_t[6] HostMac; // Right to Left
};
Get All MAC BT 0x09[]
struct ReportFeatureInMacAllBT {
union {
BTCRC<53> CRC;
ReportFeatureInControllerVersion Data; // with ReportID 0x09
}
};
Get Client MAC USB/Dongle 0x81[]
struct ReportFeatureInMacClient {
uint8_t ReportID; // 0x81
uint8_t[6] ClientMac; // Right to Left
};
Get Host Dongle 0xE5[]
struct ReportFeatureInMacHost {
uint8_t ReportID; // 0xE5
uint8_t[6] HostMac; // Right to Left
};
Set Host MAC and Linkkey USB 0x13[]
struct ReportFeatureOutMacHost {
uint8_t ReportID; // 0x13
uint8_t[6] ClientMac; // Right to Left
uint8_t[16] Linkkey;
};
Set Client MAC USB 0x80[]
struct ReportFeatureOutMacClient {
uint8_t ReportID; // 0x80
uint8_t[6] ClientMac; // Right to Left
};
Date and Version[]
Controller Date/Version Dongle/USB 0xA3[]
struct ReportFeatureInControllerVersion {
uint8_t ReportID; // 0xA3 (0x06 for BT)
char[16] Date; // string
char[16] Time; // string
uint16_t HardwareVersionMajor; // %04x.%04x AKA DevRel
uint16_t HardwareVersionMinor; // Must be >= 0x3100u for Remote Play
// might be bitwise anded with 0xFFC0
uint32_t SoftwareVersionMajor; // firmware ignores this for debug terminal output a hardcode of 3
uint16_t SoftwareVersionMinor; // written %08x.%04x, 3, sw_ver_minor
uint16_t SoftwareSeries; // %04x
uint32_t CodeSize;
};
Controller Date/Version Bluetooth 0x06[]
struct ReportFeatureInControllerVersionBT {
union {
BTCRC<53> CRC;
ReportFeatureInControllerVersion Data; // with ReportID 0x06
}
};
Dongle Date/Version Dongle 0xE1[]
struct ReportFeatureInDongleVersion {
uint8_t ReportID; // 0xE1
char[16] Date; // string
char[16] Time; // string
uint16_t HardwareVersionMajor;
uint16_t HardwareVersionMinor;
uint32_t SoftwareVersionMajor;
uint16_t SoftwareVersionMinor;
uint16_t SoftwareSeries;
uint32_t CodeSize;
};
Other[]
Controller VID/PID Dongle 0xE3[]
Access controller's VID/PID to determine what controller is connected to dongle. Note: Dongle's revision number is used.
struct ReportFeatureInControllerVidPidDongle {
uint8_t ReportID; // 0xE3
uint16_t VID; // Ex: 0x054C
uint16_t PID; // Ex: 0x09CC
};
Get Audio Chip Ident 0xAF[]
Confirm if this is USB only
struct ReportFeatureInMacClient {
uint8_t ReportID; // 0xAF
uint16_t Ident; // 0x1801 for WM1801
};
Get AC_ON_STATE 0xAE[]
Confirm if this is USB only, this is of unknown purpose
struct ReportFeatureInMacClient {
uint8_t ReportID; // 0xAE
uint8_t Value; // 0x00 - L, 0x01 - H
};
Dongle Set Audio Output Dongle 0xE0[]
// Note that the headset output does not downmix, so mono only comes from the left
enum AudioOutput : uint8_t {
HeadsetStereo = 0, // Left and Right to headphones
HeadsetMono, // Left to headphones
HeadsetMonoSpeaker, // Left to headphones, Right to speaker
Speaker, // Right to speaker
Disabled = 4
};
struct ReportFeatureInDongleSetAudio {
uint8_t ReportID; // 0xE0
uint8_t Unknown; // 0x00
AudioOutput Output;
};