Joy-Con: Difference between revisions
These were swapped |
|||
(8 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
Joy-Con is the name for the Switch's primary game controllers. The Joy-Con are internally called | Joy-Con is the name for the Switch's primary game controllers. The Joy-Con are internally called Sakyo (Left) and Ukyo (Right). | ||
= Hardware = | = Hardware = | ||
== | == Sakyo == | ||
{| class="wikitable" | {| class="wikitable" | ||
! Component || Description | ! Component || Description | ||
Line 15: | Line 15: | ||
|} | |} | ||
== | == Ukyo == | ||
{| class="wikitable" | {| class="wikitable" | ||
! Component || Description | ! Component || Description | ||
Line 127: | Line 127: | ||
! Value | ! Value | ||
! Description | ! Description | ||
|- | |||
| 0x43 || ReportOut | |||
|- | |||
| 0x53 || ReportIn | |||
|- | |- | ||
| 0x91 || DeviceCommandIn | | 0x91 || DeviceCommandIn | ||
Line 138: | Line 142: | ||
| 0x95 || | | 0x95 || | ||
|- | |- | ||
| 0x9A || | | 0x9A || Fifty | ||
|- | |- | ||
| 0xA3 || | | 0xA3 || ReportComplete | ||
|- | |- | ||
| 0xA5 || Handshake | | 0xA5 || Handshake | ||
Line 500: | Line 504: | ||
| 0x2 | | 0x2 | ||
| 0x8 | | 0x8 | ||
| MotorData | | [[#HidMotorData|MotorData]] | ||
|- | |- | ||
| 0xA | | 0xA | ||
Line 530: | Line 534: | ||
| 0x2 | | 0x2 | ||
| 0x8 | | 0x8 | ||
| MotorData | | [[#HidMotorData|MotorData]] | ||
|- | |- | ||
| 0xA | | 0xA | ||
Line 556: | Line 560: | ||
| 0x2 | | 0x2 | ||
| 0x8 | | 0x8 | ||
| MotorData | | [[#HidMotorData|MotorData]] | ||
|} | |} | ||
Line 578: | Line 582: | ||
| 0x2 | | 0x2 | ||
| 0x8 | | 0x8 | ||
| MotorData | | [[#HidMotorData|MotorData]] | ||
|- | |- | ||
| 0xA | | 0xA | ||
Line 604: | Line 608: | ||
| 0x2 | | 0x2 | ||
| 0x8 | | 0x8 | ||
| MotorData | | [[#HidMotorData|MotorData]] | ||
|- | |- | ||
| 0xA | | 0xA | ||
Line 646: | Line 650: | ||
| 0x72 || OtaReadReport | | 0x72 || OtaReadReport | ||
|- | |- | ||
| 0x73 || | | 0x73 || OtaEraseReport | ||
|- | |- | ||
| 0x74 || | | 0x74 || OtaWriteReport | ||
|- | |- | ||
| 0x75 || OtaLaunchReport | | 0x75 || OtaLaunchReport | ||
Line 657: | Line 661: | ||
|- | |- | ||
| 0x82 || | | 0x82 || | ||
|} | |||
== HidMotorData == | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || [[#VibrationAmFmPackTag|JoyLeftVibrationAmFmPackTag]] | |||
|- | |||
| 0x4 || 0x8 || [[#VibrationAmFmPackTag|JoyRightVibrationAmFmPackTag]] | |||
|} | |||
== VibrationAmFmPackTag == | |||
This is "nn::xcd::VibrationAmFmPackTag". This is a BitPack object. | |||
=== VibrationAmFmPackFormatZero === | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-29 || Reserved | |||
|- | |||
| 30-31 || PackFormat (must be 0) | |||
|} | |||
=== VibrationAmFmPackFormatOne === | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-19 || Reserved | |||
|- | |||
| 20-24 || ChannelCodesHigh | |||
|- | |||
| 25-29 || ChannelCodesLow | |||
|- | |||
| 30-31 || PackFormat (must be 1) | |||
|} | |||
=== VibrationAmFmPackFormatOne28bit === | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-1 || Reserved | |||
|- | |||
| 2-8 || ChannelFrequencyHigh | |||
|- | |||
| 9-15 || ChannelAmplitudeHigh | |||
|- | |||
| 16-22 || ChannelFrequencyLow | |||
|- | |||
| 23-29 || ChannelAmplitudeLow | |||
|- | |||
| 30-31 || PackFormat (must be 1) | |||
|} | |||
=== VibrationAmFmPackFormatTwo === | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-9 || Reserved | |||
|- | |||
| 10-14 || VibrationCodesHigh | |||
|- | |||
| 15-19 || VibrationCodesLow | |||
|- | |||
| 20-24 || ChannelCodesHigh | |||
|- | |||
| 25-29 || ChannelCodesLow | |||
|- | |||
| 30-31 || PackFormat (must be 2) | |||
|} | |||
=== VibrationAmFmPackFormatTwo14bitLow === | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0 || IsChannelHigh (must be 0) | |||
|- | |||
| 1-7 || ChannelFrequency | |||
|- | |||
| 8-12 || VibrationCodesHigh1 | |||
|- | |||
| 13-17 || VibrationCodesLow1 | |||
|- | |||
| 18-22 || VibrationCodesHigh0 | |||
|- | |||
| 23-29 || ChannelAmplitude | |||
|- | |||
| 30-31 || PackFormat (must be 2) | |||
|} | |||
=== VibrationAmFmPackFormatTwo14bitHigh === | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0 || IsChannelHigh (must be 1) | |||
|- | |||
| 1-7 || ChannelFrequency | |||
|- | |||
| 8-12 || VibrationCodesHigh1 | |||
|- | |||
| 13-17 || VibrationCodesLow1 | |||
|- | |||
| 18-22 || VibrationCodesLow0 | |||
|- | |||
| 23-29 || ChannelAmplitude | |||
|- | |||
| 30-31 || PackFormat (must be 2) | |||
|} | |||
=== VibrationAmFmPackFormatThree === | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-4 || VibrationCodesHigh1 | |||
|- | |||
| 5-9 || VibrationCodesLow1 | |||
|- | |||
| 10-14 || VibrationCodesHigh0 | |||
|- | |||
| 15-19 || VibrationCodesLow0 | |||
|- | |||
| 20-24 || ChannelCodesHigh | |||
|- | |||
| 25-29 || ChannelCodesLow | |||
|- | |||
| 30-31 || PackFormat (must be 3) | |||
|} | |||
=== VibrationAmFmPackFormatThree7bit === | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0 || IsChannelHigh | |||
|- | |||
| 1 || IsThree7bit (must be 1) | |||
|- | |||
| 2 || IsFm | |||
|- | |||
| 3-7 || VibrationCodesHigh1 | |||
|- | |||
| 8-12 || VibrationCodesLow1 | |||
|- | |||
| 13-17 || VibrationCodesHigh0 | |||
|- | |||
| 18-22 || VibrationCodesLow0 | |||
|- | |||
| 23-29 || ChannelAmFm | |||
|- | |||
| 30-31 || PackFormat (must be 1, instead of 3) | |||
|} | |||
== AmFmCodes == | |||
These are 32-bit values used by the Joy-Con firmware to represent combinations of amplitude/frequency pairs for vibration. | |||
=== Unpacking === | |||
The Joy-Con firmware receives vibration data packed as [[#VibrationAmFmPackTag|VibrationAmFmPackTag]] from output reports. Depending on the packing format, these tags are then converted to an array of AmFmCodes as follows. | |||
==== AmFm5BitCodes ==== | |||
Converted from [[#VibrationAmFmPackFormatOne|VibrationAmFmPackFormatOne]], [[#VibrationAmFmPackFormatTwo|VibrationAmFmPackFormatTwo]] or [[#VibrationAmFmPackFormatThree|VibrationAmFmPackFormatThree]]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || <nowiki>(ChannelCodesLow & 0x1F)</nowiki> | |||
|- | |||
| 0x4 || 0x4 || <nowiki>(ChannelCodesHigh & 0x1F)</nowiki> | |||
|- | |||
| 0x8 || 0x4 || <nowiki>(VibrationCodesLow0 & 0x1F)</nowiki> | |||
|- | |||
| 0xC || 0x4 || <nowiki>(VibrationCodesHigh0 & 0x1F)</nowiki> | |||
|- | |||
| 0x10 || 0x4 || <nowiki>(VibrationCodesLow1 & 0x1F)</nowiki> | |||
|- | |||
| 0x14 || 0x4 || <nowiki>(VibrationCodesHigh1 & 0x1F)</nowiki> | |||
|} | |||
==== AmFm7BitOneCodes ==== | |||
Converted from [[#VibrationAmFmPackFormatOne28bit|VibrationAmFmPackFormatOne28bit]]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || <nowiki>(((ChannelFrequencyLow & 0x7F) << 8) | (ChannelAmplitudeLow & 0x7F) | 0x8080)</nowiki> | |||
|- | |||
| 0x4 || 0x4 || <nowiki>(((ChannelFrequencyHigh & 0x7F) << 8) | (ChannelAmplitudeHigh & 0x7F) | 0x8080)</nowiki> | |||
|} | |||
==== AmFm7BitTwoCodes ==== | |||
Converted from [[#VibrationAmFmPackFormatTwo14bitLow|VibrationAmFmPackFormatTwo14bitLow]] or [[#VibrationAmFmPackFormatTwo14bitHigh|VibrationAmFmPackFormatTwo14bitHigh]]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || <nowiki>IsChannelHigh ? (VibrationCodesLow0 & 0x1F) : (((ChannelFrequency & 0x7F) << 8) | (ChannelAmplitude & 0x7F) | 0x8080)</nowiki> | |||
|- | |||
| 0x4 || 0x4 || <nowiki>IsChannelHigh ? (((ChannelFrequency & 0x7F) << 8) | (ChannelAmplitude & 0x7F) | 0x8080) : (VibrationCodesHigh0 & 0x1F)</nowiki> | |||
|- | |||
| 0x8 || 0x4 || <nowiki>(VibrationCodesLow1 & 0x1F)</nowiki> | |||
|- | |||
| 0xC || 0x4 || <nowiki>(VibrationCodesHigh1 & 0x1F)</nowiki> | |||
|- | |||
| 0x10 || 0x4 || <nowiki>Always 0x18</nowiki> | |||
|- | |||
| 0x14 || 0x4 || <nowiki>Always 0x18</nowiki> | |||
|} | |||
==== AmFm7BitThreeCodes ==== | |||
Converted from [[#VibrationAmFmPackFormatThree7bit|VibrationAmFmPackFormatThree7bit]]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || <nowiki>IsChannelHigh ? 0x18 : (IsFm ? (((ChannelAmFm & 0x7F) << 8) | 0x8000) : ((ChannelAmFm & 0x7F) | 0x80))</nowiki> | |||
|- | |||
| 0x4 || 0x4 || <nowiki>IsChannelHigh ? (IsFm ? (((ChannelAmFm & 0x7F) << 8) | 0x8000) : ((ChannelAmFm & 0x7F) | 0x80)) : 0x18</nowiki> | |||
|- | |||
| 0x8 || 0x4 || <nowiki>(VibrationCodesLow0 & 0x1F)</nowiki> | |||
|- | |||
| 0xC || 0x4 || <nowiki>(VibrationCodesHigh0 & 0x1F)</nowiki> | |||
|- | |||
| 0x10 || 0x4 || <nowiki>(VibrationCodesLow1 & 0x1F)</nowiki> | |||
|- | |||
| 0x14 || 0x4 || <nowiki>(VibrationCodesHigh1 & 0x1F)</nowiki> | |||
|} | |} | ||
Line 865: | Line 1,114: | ||
|- | |- | ||
| 0x6000 || 0x1000 || [[#FactoryConfiguration|FactoryConfiguration]] | | 0x6000 || 0x1000 || [[#FactoryConfiguration|FactoryConfiguration]] | ||
|- | |||
| 0x7000 || 0x1000 || Reserved | |||
|- | |- | ||
| 0x8000 || 0x1000 || [[#UserCalibration|UserCalibration]] | | 0x8000 || 0x1000 || [[#UserCalibration|UserCalibration]] | ||
Line 926: | Line 1,177: | ||
| 0x10 || 0x2 || Reserved | | 0x10 || 0x2 || Reserved | ||
|- | |- | ||
| 0x12 || 0x1 || [[# | | 0x12 || 0x1 || [[#DeviceType|DeviceType]] | ||
|- | |- | ||
| 0x13 || 0x1 || BoardRevision | | 0x13 || 0x1 || BoardRevision | ||
Line 958: | Line 1,209: | ||
| 0xAC || 0x1 || GyroscopeAxisAssignment | | 0xAC || 0x1 || GyroscopeAxisAssignment | ||
|- | |- | ||
| 0xAD || 0x1 || | | 0xAD || 0x1 || AnalogStickMainAxisAssignment | ||
|- | |- | ||
| 0xAE || 0x1 || | | 0xAE || 0x1 || AnalogStickSubAxisAssignment | ||
|- | |- | ||
| 0xAF || 0x151 || Reserved | | 0xAF || 0x151 || Reserved | ||
Line 975: | Line 1,226: | ||
|- | |- | ||
| 0xE00 || 0x100 || InspectionLog | | 0xE00 || 0x100 || InspectionLog | ||
|- | |||
| 0xF00 || 0x100 || Reserved | |||
|} | |} | ||
=== | === DeviceType === | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 983: | Line 1,236: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x01 || | | 0x01 || JoyConLeft | ||
|- | |- | ||
| 0x02 || | | 0x02 || JoyConRight | ||
|- | |- | ||
| 0x03 || SwitchProController | | 0x03 || SwitchProController | ||
|- | |- | ||
| 0x04 || | | 0x04 || MiyabiLeft | ||
|- | |- | ||
| 0x05 || | | 0x05 || MiyabiRight | ||
|- | |- | ||
| 0x06 || Tarragon | | 0x06 || Tarragon | ||
|- | |- | ||
| 0x07 || | | 0x07 || LarkH1 | ||
|- | |- | ||
| 0x08 || | | 0x08 || LarkH2 | ||
|- | |- | ||
| 0x09 || | | 0x09 || LarkNL | ||
|- | |- | ||
| 0x0A || | | 0x0A || LarkNR | ||
|- | |- | ||
| 0x0B || Lucia | | 0x0B || Lucia | ||
Line 1,009: | Line 1,262: | ||
| 0x0D || [13.0.0+] Lager | | 0x0D || [13.0.0+] Lager | ||
|- | |- | ||
| 0x0E || [14.0.0+] | | 0x0E || [14.0.0+] Tarragon2 | ||
|- | |- | ||
| 0x21 || | | 0x21 || FiftyL | ||
|- | |- | ||
| 0x22 || | | 0x22 || FiftyR | ||
|} | |} | ||
Line 1,039: | Line 1,292: | ||
| 0x4 || 0x2 || Accelerometer0OffsetZ | | 0x4 || 0x2 || Accelerometer0OffsetZ | ||
|- | |- | ||
| 0x6 || 0x2 || | | 0x6 || 0x2 || Accelerometer1gScaleX | ||
|- | |- | ||
| 0x8 || 0x2 || | | 0x8 || 0x2 || Accelerometer1gScaleY | ||
|- | |- | ||
| 0xA || 0x2 || | | 0xA || 0x2 || Accelerometer1gScaleZ | ||
|- | |- | ||
| 0xC || 0x2 || Gyroscope0OffsetX | | 0xC || 0x2 || Gyroscope0OffsetX | ||
Line 1,051: | Line 1,304: | ||
| 0x10 || 0x2 || Gyroscope0OffsetZ | | 0x10 || 0x2 || Gyroscope0OffsetZ | ||
|- | |- | ||
| 0x12 || 0x2 || | | 0x12 || 0x2 || Gyroscope78rpmScaleX | ||
|- | |- | ||
| 0x14 || 0x2 || | | 0x14 || 0x2 || Gyroscope78rpmScaleY | ||
|- | |- | ||
| 0x16 || 0x2 || | | 0x16 || 0x2 || Gyroscope78rpmScaleZ | ||
|} | |} | ||
Line 1,065: | Line 1,318: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x9 || [[# | | 0x0 || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickMainCalibrationValue]] | ||
|- | |- | ||
| 0x9 || 0x9 || [[# | | 0x9 || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickSubCalibrationValue]] | ||
|} | |} | ||
==== | ==== AnalogStickCalibrationValue ==== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 1,077: | Line 1,330: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || | | 0x0 || 0x1 || AnalogStickCalXPositive | ||
|- | |- | ||
| | | 0x1 || 0x2 || AnalogStickCalYPositive | ||
|- | |- | ||
| 0x3 || 0x1 || AnalogStickCalX0 | |||
| | |||
|- | |- | ||
| 0x4 || 0x2 || AnalogStickCalY0 | |||
|- | |- | ||
| | | 0x6 || 0x1 || AnalogStickCalXNegative | ||
|- | |- | ||
| | | 0x7 || 0x2 || AnalogStickCalYNegative | ||
|} | |} | ||
Line 1,117: | Line 1,362: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || | | 0x0 || 0x1 || MainColorR | ||
|- | |- | ||
| | | 0x1 || 0x1 || MainColorG | ||
|- | |- | ||
| | | 0x2 || 0x1 || MainColorB | ||
|- | |- | ||
| 0x9 || | | 0x3 || 0x1 || SubColorR | ||
|- | |||
| 0x4 || 0x1 || SubColorG | |||
|- | |||
| 0x5 || 0x1 || SubColorB | |||
|- | |||
| 0x6 || 0x1 || 3rdColorR | |||
|- | |||
| 0x7 || 0x1 || 3rdColorG | |||
|- | |||
| 0x8 || 0x1 || 3rdColorB | |||
|- | |||
| 0x9 || 0x1 || 4thColorR | |||
|- | |||
| 0xA || 0x1 || 4thColorG | |||
|- | |||
| 0xB || 0x1 || 4thColorB | |||
|} | |} | ||
Line 1,146: | Line 1,407: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x6 || [[# | | 0x0 || 0x6 || [[#SixAxisSensorModelValue|SixAxisSensorModelValue]] | ||
|- | |- | ||
| 0x6 || 0x12 || [[# | | 0x6 || 0x12 || [[#AnalogStickModelValue|AnalogStickMainModelValue]] | ||
|} | |} | ||
==== | ==== SixAxisSensorModelValue ==== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 1,158: | Line 1,419: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x2 || | | 0x0 || 0x2 || SixAxisHorizontalOffsetX | ||
|- | |- | ||
| 0x2 || 0x2 || | | 0x2 || 0x2 || SixAxisHorizontalOffsetY | ||
|- | |- | ||
| 0x4 || 0x2 || | | 0x4 || 0x2 || SixAxisHorizontalOffsetZ | ||
|} | |} | ||
==== | ==== AnalogStickModelValue ==== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 1,172: | Line 1,433: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x3 || | | 0x0 || 0x1 || AnalogStickModelNoise | ||
|- | |||
| 0x1 || 0x2 || AnalogStickModelTypicalStroke | |||
|- | |||
| 0x3 || 0x1 || AnalogStickModelCenterDeadZoneSize | |||
|- | |||
| 0x4 || 0x2 || AnalogStickModelCircuitDeadZoneScale | |||
|- | |||
| 0x6 || 0x1 || AnalogStickModelMinimumStrokeXPositive | |||
|- | |||
| 0x7 || 0x2 || AnalogStickModelMinimumStrokeYPositive | |||
|- | |||
| 0x9 || 0x1 || AnalogStickModelMinimumStrokeXNegative | |||
|- | |- | ||
| | | 0xA || 0x2 || AnalogStickModelMinimumStrokeYNegative | ||
|- | |- | ||
| | | 0xC || 0x1 || AnalogStickModelCenterRangeXPositive | ||
|- | |- | ||
| | | 0xD || 0x2 || AnalogStickModelCenterRangeYPositive | ||
|- | |- | ||
| | | 0xF || 0x1 || AnalogStickModelCenterRangeXNegative | ||
|- | |- | ||
| | | 0x10 || 0x2 || AnalogStickModelCenterRangeYNegative | ||
|} | |} | ||
Line 1,192: | Line 1,465: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x12 || [[# | | 0x0 || 0x12 || [[#AnalogStickModelValue|AnalogStickSubModelValue]] | ||
|} | |} | ||
Line 1,218: | Line 1,491: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x2 || | | 0x0 || 0x2 || AnalogStickMainUserMagicNumber | ||
|- | |- | ||
| 0x2 || 0x9 || [[# | | 0x2 || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickMainUserCalibrationValue]] | ||
|- | |- | ||
| 0xB || 0x2 || | | 0xB || 0x2 || AnalogStickSubUserMagicNumber | ||
|- | |- | ||
| 0xD || 0x9 || [[# | | 0xD || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickSubUserCalibrationValue]] | ||
|} | |} | ||
Line 1,234: | Line 1,507: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x2 || | | 0x0 || 0x2 || SixAxisUserCalibrationMagicNumber | ||
|- | |- | ||
| 0x2 || 0x18 || [[#SixAxisSensorCalibrationValue| | | 0x2 || 0x18 || [[#SixAxisSensorCalibrationValue|SixAxisUserCalibrationValue]] | ||
|} | |} | ||