Joy-Con: Difference between revisions

No edit summary
These were swapped
 
(11 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 Ukyo (Left) and Sakyo (Right).
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 =
== Ukyo ==
== Sakyo ==
{| class="wikitable"
{| class="wikitable"
! Component || Description
! Component || Description
Line 15: Line 15:
|}
|}


== Sakyo ==
== 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 || OtaWriteReport
| 0x73 || OtaEraseReport
|-
|-
| 0x74 || OtaEraseReport
| 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 852: Line 1,101:
! Description
! Description
|-
|-
| 0x0 || 0x1000 || PatchramConfiguration
| 0x0 || 0x1000 || StaticSection
|-
| 0x1000 || 0x1000 || [[#FailsafeSection|FailsafeSection]]
|-
| 0x2000 || 0x1000 || [[#VolatileSection|VolatileSection]]
|-
|-
| 0x1000 || 0x1000 || [[#OtaFailsafeSection|OtaFailsafeSection]]
| 0x3000 || 0x1000 || VolatileSectionBackup1
|-
|-
| 0x2000 || 0x1000 || PairingInfo
| 0x4000 || 0x1000 || VolatileSectionBackup2
|-
|-
| 0x5000 || 0x1000 || [[#ShipmentInfo|ShipmentInfo]]
| 0x5000 || 0x1000 || [[#ShipmentInfo|ShipmentInfo]]
|-
|-
| 0x6000 || 0x1000 || [[#FactoryConfiguration|FactoryConfiguration]]
| 0x6000 || 0x1000 || [[#FactoryConfiguration|FactoryConfiguration]]
|-
| 0x7000 || 0x1000 || Reserved
|-
|-
| 0x8000 || 0x1000 || [[#UserCalibration|UserCalibration]]
| 0x8000 || 0x1000 || [[#UserCalibration|UserCalibration]]
|-
|-
| 0x10000 || 0x18000 || OtaDynamicSection1
| 0x9000 || 0x7000 || Reserved
|-
| 0x10000 || 0x18000 || DynamicSection1
|-
| 0x28000 || 0x18000 || DynamicSection2
|-
|-
| 0x28000 || 0x18000 || OtaDynamicSection2
| 0x40000 || 0x40000 || Reserved
|}
|}


== OtaFailsafeSection ==
== FailsafeSection ==
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 881: Line 1,140:
|-
|-
| 0xFFC || 0x4 || Ds2Offset
| 0xFFC || 0x4 || Ds2Offset
|}
== VolatileSection ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x26 ||
|-
| 0x26 || 0xFDA || Reserved
|}
|}


Line 904: Line 1,175:
| 0x0 || 0x10 || IdentificationCode
| 0x0 || 0x10 || IdentificationCode
|-
|-
| 0x12 || 0x1 || [[#Type|Type]]
| 0x10 || 0x2 || Reserved
|-
| 0x12 || 0x1 || [[#DeviceType|DeviceType]]
|-
| 0x13 || 0x1 || BoardRevision
|-
| 0x14 || 0x7 || Reserved
|-
|-
| 0x1B || 0x1 || FormatVersion
| 0x1B || 0x1 || FormatVersion
|-
| 0x1C || 0x4 || Reserved
|-
|-
| 0x20 || 0x18 || [[#Cal1|Cal1]]
| 0x20 || 0x18 || [[#Cal1|Cal1]]
|-
| 0x38 || 0x5 || Reserved
|-
|-
| 0x3D || 0x12 || [[#Cal2|Cal2]]
| 0x3D || 0x12 || [[#Cal2|Cal2]]
Line 915: Line 1,196:
|-
|-
| 0x50 || 0xD || [[#Design|Design]]
| 0x50 || 0xD || [[#Design|Design]]
|-
| 0x5D || 0x23 || Reserved
|-
|-
| 0x80 || 0x18 || [[#Model1|Model1]]
| 0x80 || 0x18 || [[#Model1|Model1]]
Line 920: Line 1,203:
| 0x98 || 0x12 || [[#Model2|Model2]]
| 0x98 || 0x12 || [[#Model2|Model2]]
|-
|-
| 0xAA || 0xF56 || Reserved
| 0xAA || 0x1 || Reserved
|-
| 0xAB || 0x1 || AccelerometerAxisAssignment
|-
| 0xAC || 0x1 || GyroscopeAxisAssignment
|-
| 0xAD || 0x1 || AnalogStickMainAxisAssignment
|-
| 0xAE || 0x1 || AnalogStickSubAxisAssignment
|-
| 0xAF || 0x151 || Reserved
|-
| 0x200 || 0x2 || BatteryVoltage
|-
| 0x202 || 0xB7E || Reserved
|-
| 0xD80 || 0x2 || TarragonVid
|-
| 0xD82 || 0x2 || TarragonPid
|-
| 0xD84 || 0x7C || Reserved
|-
| 0xE00 || 0x100 || InspectionLog
|-
| 0xF00 || 0x100 || Reserved
|}
|}


=== Type ===
=== DeviceType ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 929: Line 1,236:
! Description
! Description
|-
|-
| 0x01 || JoyLeft
| 0x01 || JoyConLeft
|-
|-
| 0x02 || JoyRight
| 0x02 || JoyConRight
|-
|-
| 0x03 || SwitchProController
| 0x03 || SwitchProController
|-
|-
| 0x04 || ([[HID_services#DeviceTypeInternal|DeviceType]] 4)
| 0x04 || MiyabiLeft
|-
|-
| 0x05 || ([[HID_services#DeviceTypeInternal|DeviceType]] 5)
| 0x05 || MiyabiRight
|-
|-
| 0x06 || Tarragon ([[HID_services#DeviceTypeInternal|DeviceType]] 6)
| 0x06 || Tarragon
|-
|-
| 0x07 || LarkHvc1
| 0x07 || LarkH1
|-
|-
| 0x08 || LarkHvc2
| 0x08 || LarkH2
|-
|-
| 0x09 || LarkNesLeft
| 0x09 || LarkNL
|-
|-
| 0x0A || LarkNesRight
| 0x0A || LarkNR
|-
|-
| 0x0B || Lucia
| 0x0B || Lucia
Line 955: Line 1,262:
| 0x0D || [13.0.0+] Lager
| 0x0D || [13.0.0+] Lager
|-
|-
| 0x0E || [14.0.0+] ([[HID_services#DeviceTypeInternal|DeviceType]] 30)
| 0x0E || [14.0.0+] Tarragon2
|-
|-
| 0x21 || FiftyLeft ([[HID_services#DeviceTypeInternal|DeviceType]] 14)
| 0x21 || FiftyL
|-
|-
| 0x22 || FiftyRight ([[HID_services#DeviceTypeInternal|DeviceType]] 18)
| 0x22 || FiftyR
|}
|}


Line 969: Line 1,276:
! Description
! Description
|-
|-
| 0x0 || 0x18 || SixAxisSensorCalibrationValue
| 0x0 || 0x18 || [[#SixAxisSensorCalibrationValue|SixAxisSensorCalibrationValue]]
|}
 
==== SixAxisSensorCalibrationValue ====
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x2 || Accelerometer0OffsetX
|-
| 0x2 || 0x2 || Accelerometer0OffsetY
|-
| 0x4 || 0x2 || Accelerometer0OffsetZ
|-
| 0x6 || 0x2 || Accelerometer1gScaleX
|-
| 0x8 || 0x2 || Accelerometer1gScaleY
|-
| 0xA || 0x2 || Accelerometer1gScaleZ
|-
| 0xC || 0x2 || Gyroscope0OffsetX
|-
| 0xE || 0x2 || Gyroscope0OffsetY
|-
| 0x10 || 0x2 || Gyroscope0OffsetZ
|-
| 0x12 || 0x2 || Gyroscope78rpmScaleX
|-
| 0x14 || 0x2 || Gyroscope78rpmScaleY
|-
| 0x16 || 0x2 || Gyroscope78rpmScaleZ
|}
|}


Line 979: Line 1,318:
! Description
! Description
|-
|-
| 0x0 || 0x9 || LeftAnalogStickCalibrationValue
| 0x0 || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickMainCalibrationValue]]
|-
| 0x9 || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickSubCalibrationValue]]
|}
 
==== AnalogStickCalibrationValue ====
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x1 || AnalogStickCalXPositive
|-
| 0x1 || 0x2 || AnalogStickCalYPositive
|-
| 0x3 || 0x1 || AnalogStickCalX0
|-
| 0x4 || 0x2 || AnalogStickCalY0
|-
| 0x6 || 0x1 || AnalogStickCalXNegative
|-
|-
| 0x9 || 0x9 || RightAnalogStickCalibrationValue
| 0x7 || 0x2 || AnalogStickCalYNegative
|}
|}


Line 1,003: Line 1,362:
! Description
! Description
|-
|-
| 0x0 || 0x3 || Body color of controller in RGB Hex (see [[Joy-Con#Colors|Joy-Con Colors]])
| 0x0 || 0x1 || MainColorR
|-
| 0x1 || 0x1 || MainColorG
|-
| 0x2 || 0x1 || MainColorB
|-
| 0x3 || 0x1 || SubColorR
|-
| 0x4 || 0x1 || SubColorG
|-
| 0x5 || 0x1 || SubColorB
|-
| 0x6 || 0x1 || 3rdColorR
|-
| 0x7 || 0x1 || 3rdColorG
|-
| 0x8 || 0x1 || 3rdColorB
|-
|-
| 0x3 || 0x3 || Button color of controller in RGB Hex (see [[Joy-Con#Colors|Joy-Con Colors]])
| 0x9 || 0x1 || 4thColorR
|-
|-
| 0x6 || 0x3 || Left grip color of controller in RGB Hex
| 0xA || 0x1 || 4thColorG
|-
|-
| 0x9 || 0x3 || Right grip color of controller in RGB Hex
| 0xB || 0x1 || 4thColorB
|}
|}


Line 1,032: Line 1,407:
! Description
! Description
|-
|-
| 0x0 || 0x6 || SensorData
| 0x0 || 0x6 || [[#SixAxisSensorModelValue|SixAxisSensorModelValue]]
|-
|-
| 0x6 || 0x12 || AnalogStickModuleParam
| 0x6 || 0x12 || [[#AnalogStickModelValue|AnalogStickMainModelValue]]
|}
 
==== SixAxisSensorModelValue ====
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x2 || SixAxisHorizontalOffsetX
|-
| 0x2 || 0x2 || SixAxisHorizontalOffsetY
|-
| 0x4 || 0x2 || SixAxisHorizontalOffsetZ
|}
 
==== AnalogStickModelValue ====
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 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,044: Line 1,465:
! Description
! Description
|-
|-
| 0x0 || 0x12 || AnalogStickModuleParam
| 0x0 || 0x12 || [[#AnalogStickModelValue|AnalogStickSubModelValue]]
|}
|}


Line 1,054: Line 1,475:
! Description
! Description
|-
|-
| 0x10 || 0x18 || [[#UserCal1|UserCal1]]
| 0x0 || 0x10 || Reserved
|-
|-
| 0x28 || 0x18 || [[#UserCal2|UserCal2]]
| 0x10 || 0x16 || [[#UserCal1|UserCal1]]
|-
| 0x26 || 0x1A || [[#UserCal2|UserCal2]]
|-
|-
| 0x40 || 0xFC0 || Reserved
| 0x40 || 0xFC0 || Reserved
Line 1,068: Line 1,491:
! Description
! Description
|-
|-
| 0x0 || 0x2 || UserCalMagicNumber
| 0x0 || 0x2 || AnalogStickMainUserMagicNumber
|-
|-
| 0x2 || 0x9 || LeftAnalogStickCalibrationValue
| 0x2 || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickMainUserCalibrationValue]]
|-
|-
| 0xB || 0x2 || UserCalMagicNumber
| 0xB || 0x2 || AnalogStickSubUserMagicNumber
|-
|-
| 0xD || 0x9 || RightAnalogStickCalibrationValue
| 0xD || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickSubUserCalibrationValue]]
|-
| 0x16 || 0x2 || UserCalMagicNumber
|}
|}


Line 1,086: Line 1,507:
! Description
! Description
|-
|-
| 0x0 || 0x18 || SixAxisSensorCalibrationValue
| 0x0 || 0x2 || SixAxisUserCalibrationMagicNumber
|-
| 0x2 || 0x18 || [[#SixAxisSensorCalibrationValue|SixAxisUserCalibrationValue]]
|}
|}