diff options
Diffstat (limited to 'src/input_common/helpers/joycon_protocol/joycon_types.h')
-rw-r--r-- | src/input_common/helpers/joycon_protocol/joycon_types.h | 187 |
1 files changed, 136 insertions, 51 deletions
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h index e2d47349f..b91934990 100644 --- a/src/input_common/helpers/joycon_protocol/joycon_types.h +++ b/src/input_common/helpers/joycon_protocol/joycon_types.h @@ -19,20 +19,24 @@ namespace InputCommon::Joycon { constexpr u32 MaxErrorCount = 50; constexpr u32 MaxBufferSize = 368; -constexpr u32 MaxResponseSize = 49; -constexpr u32 MaxSubCommandResponseSize = 64; constexpr std::array<u8, 8> DefaultVibrationBuffer{0x0, 0x1, 0x40, 0x40, 0x0, 0x1, 0x40, 0x40}; using MacAddress = std::array<u8, 6>; using SerialNumber = std::array<u8, 15>; -enum class ControllerType { - None, - Left, - Right, - Pro, - Grip, - Dual, +enum class ControllerType : u8 { + None = 0x00, + Left = 0x01, + Right = 0x02, + Pro = 0x03, + Dual = 0x05, // TODO: Verify this id + LarkHvc1 = 0x07, + LarkHvc2 = 0x08, + LarkNesLeft = 0x09, + LarkNesRight = 0x0A, + Lucia = 0x0B, + Lagon = 0x0C, + Lager = 0x0D, }; enum class PadAxes { @@ -99,14 +103,6 @@ enum class OutputReport : u8 { USB_CMD = 0x80, }; -enum class InputReport : u8 { - SUBCMD_REPLY = 0x21, - STANDARD_FULL_60HZ = 0x30, - NFC_IR_MODE_60HZ = 0x31, - SIMPLE_HID_MODE = 0x3F, - INPUT_USB_RESPONSE = 0x81, -}; - enum class FeatureReport : u8 { Last_SUBCMD = 0x02, OTA_GW_UPGRADE = 0x70, @@ -129,6 +125,7 @@ enum class SubCommand : u8 { LOW_POWER_MODE = 0x08, SPI_FLASH_READ = 0x10, SPI_FLASH_WRITE = 0x11, + SPI_SECTOR_ERASE = 0x12, RESET_MCU = 0x20, SET_MCU_CONFIG = 0x21, SET_MCU_STATE = 0x22, @@ -142,9 +139,10 @@ enum class SubCommand : u8 { ENABLE_VIBRATION = 0x48, GET_REGULATED_VOLTAGE = 0x50, SET_EXTERNAL_CONFIG = 0x58, - UNKNOWN_RINGCON = 0x59, - UNKNOWN_RINGCON2 = 0x5A, - UNKNOWN_RINGCON3 = 0x5C, + GET_EXTERNAL_DEVICE_INFO = 0x59, + ENABLE_EXTERNAL_POLLING = 0x5A, + DISABLE_EXTERNAL_POLLING = 0x5B, + SET_EXTERNAL_FORMAT_CONFIG = 0x5C, }; enum class UsbSubCommand : u8 { @@ -158,26 +156,31 @@ enum class UsbSubCommand : u8 { SEND_UART = 0x92, }; -enum class CalMagic : u8 { +enum class CalibrationMagic : u8 { USR_MAGIC_0 = 0xB2, USR_MAGIC_1 = 0xA1, - USRR_MAGI_SIZE = 2, }; -enum class CalAddr { - SERIAL_NUMBER = 0X6000, - DEVICE_TYPE = 0X6012, - COLOR_EXIST = 0X601B, - FACT_LEFT_DATA = 0X603d, - FACT_RIGHT_DATA = 0X6046, - COLOR_DATA = 0X6050, - FACT_IMU_DATA = 0X6020, - USER_LEFT_MAGIC = 0X8010, - USER_LEFT_DATA = 0X8012, - USER_RIGHT_MAGIC = 0X801B, - USER_RIGHT_DATA = 0X801D, - USER_IMU_MAGIC = 0X8026, - USER_IMU_DATA = 0X8028, +enum class SpiAddress : u16 { + MAGIC = 0x0000, + MAC_ADDRESS = 0x0015, + PAIRING_INFO = 0x2000, + SHIPMENT = 0x5000, + SERIAL_NUMBER = 0x6000, + DEVICE_TYPE = 0x6012, + FORMAT_VERSION = 0x601B, + FACT_IMU_DATA = 0x6020, + FACT_LEFT_DATA = 0x603d, + FACT_RIGHT_DATA = 0x6046, + COLOR_DATA = 0x6050, + DESIGN_VARIATION = 0x605C, + SENSOR_DATA = 0x6080, + USER_LEFT_MAGIC = 0x8010, + USER_LEFT_DATA = 0x8012, + USER_RIGHT_MAGIC = 0x801B, + USER_RIGHT_DATA = 0x801D, + USER_IMU_MAGIC = 0x8026, + USER_IMU_DATA = 0x8028, }; enum class ReportMode : u8 { @@ -185,10 +188,12 @@ enum class ReportMode : u8 { ACTIVE_POLLING_NFC_IR_CAMERA_CONFIGURATION = 0x01, ACTIVE_POLLING_NFC_IR_CAMERA_DATA_CONFIGURATION = 0x02, ACTIVE_POLLING_IR_CAMERA_DATA = 0x03, + SUBCMD_REPLY = 0x21, MCU_UPDATE_STATE = 0x23, STANDARD_FULL_60HZ = 0x30, NFC_IR_MODE_60HZ = 0x31, SIMPLE_HID_MODE = 0x3F, + INPUT_USB_RESPONSE = 0x81, }; enum class GyroSensitivity : u8 { @@ -359,10 +364,16 @@ enum class IrRegistersAddress : u16 { DenoiseColor = 0x6901, }; +enum class ExternalDeviceId : u16 { + RingController = 0x2000, + Starlink = 0x2800, +}; + enum class DriverResult { Success, WrongReply, Timeout, + InvalidParameters, UnsupportedControllerType, HandleInUse, ErrorReadingData, @@ -395,10 +406,35 @@ struct MotionData { u64 delta_timestamp{}; }; +// Output from SPI read command containing user calibration magic +struct MagicSpiCalibration { + CalibrationMagic first; + CalibrationMagic second; +}; +static_assert(sizeof(MagicSpiCalibration) == 0x2, "MagicSpiCalibration is an invalid size"); + +// Output from SPI read command containing left joystick calibration +struct JoystickLeftSpiCalibration { + std::array<u8, 3> max; + std::array<u8, 3> center; + std::array<u8, 3> min; +}; +static_assert(sizeof(JoystickLeftSpiCalibration) == 0x9, + "JoystickLeftSpiCalibration is an invalid size"); + +// Output from SPI read command containing right joystick calibration +struct JoystickRightSpiCalibration { + std::array<u8, 3> center; + std::array<u8, 3> min; + std::array<u8, 3> max; +}; +static_assert(sizeof(JoystickRightSpiCalibration) == 0x9, + "JoystickRightSpiCalibration is an invalid size"); + struct JoyStickAxisCalibration { - u16 max{1}; - u16 min{1}; - u16 center{0}; + u16 max; + u16 min; + u16 center; }; struct JoyStickCalibration { @@ -406,6 +442,14 @@ struct JoyStickCalibration { JoyStickAxisCalibration y; }; +struct ImuSpiCalibration { + std::array<s16, 3> accelerometer_offset; + std::array<s16, 3> accelerometer_scale; + std::array<s16, 3> gyroscope_offset; + std::array<s16, 3> gyroscope_scale; +}; +static_assert(sizeof(ImuSpiCalibration) == 0x18, "ImuSpiCalibration is an invalid size"); + struct RingCalibration { s16 default_value; s16 max_value; @@ -452,7 +496,7 @@ static_assert(sizeof(MCUConfig) == 0x26, "MCUConfig is an invalid size"); #pragma pack(push, 1) struct InputReportPassive { - InputReport report_mode; + ReportMode report_mode; u16 button_input; u8 stick_state; std::array<u8, 10> unknown_data; @@ -460,7 +504,7 @@ struct InputReportPassive { static_assert(sizeof(InputReportPassive) == 0xE, "InputReportPassive is an invalid size"); struct InputReportActive { - InputReport report_mode; + ReportMode report_mode; u8 packet_id; Battery battery_status; std::array<u8, 3> button_input; @@ -474,7 +518,7 @@ struct InputReportActive { static_assert(sizeof(InputReportActive) == 0x29, "InputReportActive is an invalid size"); struct InputReportNfcIr { - InputReport report_mode; + ReportMode report_mode; u8 packet_id; Battery battery_status; std::array<u8, 3> button_input; @@ -487,14 +531,6 @@ struct InputReportNfcIr { static_assert(sizeof(InputReportNfcIr) == 0x29, "InputReportNfcIr is an invalid size"); #pragma pack(pop) -struct IMUCalibration { - std::array<s16, 3> accelerometer_offset; - std::array<s16, 3> accelerometer_scale; - std::array<s16, 3> gyroscope_offset; - std::array<s16, 3> gyroscope_scale; -}; -static_assert(sizeof(IMUCalibration) == 0x18, "IMUCalibration is an invalid size"); - struct NFCReadBlock { u8 start; u8 end; @@ -580,9 +616,11 @@ static_assert(sizeof(FirmwareVersion) == 0x2, "FirmwareVersion is an invalid siz struct DeviceInfo { FirmwareVersion firmware; + std::array<u8, 2> unknown_1; MacAddress mac_address; + std::array<u8, 2> unknown_2; }; -static_assert(sizeof(DeviceInfo) == 0x8, "DeviceInfo is an invalid size"); +static_assert(sizeof(DeviceInfo) == 0xC, "DeviceInfo is an invalid size"); struct MotionStatus { bool is_enabled; @@ -598,6 +636,53 @@ struct RingStatus { s16 min_value; }; +struct VibrationPacket { + OutputReport output_report; + u8 packet_counter; + std::array<u8, 0x8> vibration_data; +}; +static_assert(sizeof(VibrationPacket) == 0xA, "VibrationPacket is an invalid size"); + +struct SubCommandPacket { + OutputReport output_report; + u8 packet_counter; + INSERT_PADDING_BYTES(0x8); // This contains vibration data + SubCommand sub_command; + std::array<u8, 0x26> command_data; +}; +static_assert(sizeof(SubCommandPacket) == 0x31, "SubCommandPacket is an invalid size"); + +#pragma pack(push, 1) +struct ReadSpiPacket { + SpiAddress spi_address; + INSERT_PADDING_BYTES(0x2); + u8 size; +}; +static_assert(sizeof(ReadSpiPacket) == 0x5, "ReadSpiPacket is an invalid size"); + +struct SubCommandResponse { + InputReportPassive input_report; + SubCommand sub_command; + union { + std::array<u8, 0x30> command_data; + SpiAddress spi_address; // Reply from SPI_FLASH_READ subcommand + ExternalDeviceId external_device_id; // Reply from GET_EXTERNAL_DEVICE_INFO subcommand + DeviceInfo device_info; // Reply from REQ_DEV_INFO subcommand + }; + u8 crc; // This is never used +}; +static_assert(sizeof(SubCommandResponse) == 0x40, "SubCommandResponse is an invalid size"); +#pragma pack(pop) + +struct MCUCommandResponse { + InputReportNfcIr input_report; + INSERT_PADDING_BYTES(0x8); + MCUReport mcu_report; + std::array<u8, 0x13D> mcu_data; + u8 crc; +}; +static_assert(sizeof(MCUCommandResponse) == 0x170, "MCUCommandResponse is an invalid size"); + struct JoyconCallbacks { std::function<void(Battery)> on_battery_data; std::function<void(Color)> on_color_data; |