Joy-Con: Difference between revisions

Unifying joy-con info since when both are paired they report identical info.
These were swapped
 
(76 intermediate revisions by 18 users not shown)
Line 1: Line 1:
== Specifications ==
Joy-Con is the name for the Switch's primary game controllers. The Joy-Con are internally called Sakyo (Left) and Ukyo (Right).
 
= Hardware =
== Sakyo ==
{| class="wikitable"
{| class="wikitable"
! Type !!  
! Component || Description
|-
| SoC || Broadcom BCM20734
|-
| IMU || STMicroelectronics LSM6DS3H
|-
| PMIC || Texas Instruments BQ24072
|-
| Storage || Macronix International MX25U4033E 4 Mb CMOS Flash
|}
 
== Ukyo ==
{| class="wikitable"
! Component || Description
|-
| SoC || Broadcom BCM20734
|-
| MCU || STMicroelectronics STM32P411
|-
| NFC || STMicroelectronics ST21NFCB
|-
| IMU || STMicroelectronics LSM6DS3H
|-
| PMIC || Texas Instruments BQ24072
|-
| Storage || Macronix International MX25U4033E 4 Mb CMOS Flash
|}
 
= Protocol =
The Joy-Con can communicate wirelessly over Bluetooth or through the rails over UART. The latter uses a Nintendo proprietary protocol called "Nwcp".
 
== NwcpPacket ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x5
| [[#HciHeader|HciHeader]]
|-
| 0x5
| 0x7
| [[#NwcpHeader|NwcpHeader]]
|-
| 0xC
| Variable
| Data
|}
 
=== HciHeader ===
This is a 5-byte packet header used by Broadcom's HCI Control Protocol.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| PacketType (always 0x19)
|-
| 0x1
| 0x1
| [[#CommandCode|CommandCode]]
|-
| 0x2
| 0x1
| GroupCode (always 0x03)
|-
| 0x3
| 0x2
| PacketLength
|}
 
==== CommandCode ====
{| class="wikitable" border="1"
! Value
! Description
|-
| 0x1 || SendToDevice
|-
| 0x81 || ReceiveFromDevice
|}
 
=== NwcpHeader ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#CommandType|CommandType]]
|-
| 0x1
| 0x1
| [[#DeviceCommand|DeviceCommand]]
|-
| 0x2
| 0x2
| DataSize
|-
| 0x4
| 0x1
| CommandResult
|-
| 0x5
| 0x1
| DataCrc (CRC8 over Data for DataSize bytes)
|-
| 0x6
| 0x1
| HeaderCrc (CRC8 over the previous 6 bytes)
|}
 
==== CommandType ====
{| class="wikitable" border="1"
! Value
! Description
|-
| 0x43 || ReportOut
|-
| 0x53 || ReportIn
|-
| 0x91 || DeviceCommandIn
|-
| 0x92 || Hid
|-
| 0x93 ||
|-
| 0x94 || DeviceCommandOut
|-
| 0x95 ||
|-
| 0x9A || Fifty
|-
| 0xA3 || ReportComplete
|-
| 0xA5 || Handshake
|}
 
== HidCommandInputReport ==
This is a 0x31-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| LatencyTimer
|-
| 0x2
| 0x1
| PowerInfo
|-
| 0x3
| 0x1
| RightPadButtonStatus
|-
| 0x4
| 0x1
| SharedButtonStatus
|-
| 0x5
| 0x1
| LeftPadButtonStatus
|-
| 0x6
| 0x3
| LeftAnalogStickData
|-
| 0x9
| 0x3
| RightAnalogStickData
|-
| 0xC
| 0x1
| MotorStatus
|-
| 0xD
| 0x1
| CommandAck
|-
| 0xE
| 0x1
| [[#HidCommand|CommandId]]
|-
| 0xF
| 0x22
| CommandReply
|}
 
== HidMcuUpdateInputReport ==
This is a 0x30-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| LatencyTimer
|-
| 0x2
| 0x1
| PowerInfo
|-
| 0x3
| 0x1
| RightPadButtonStatus
|-
| 0x4
| 0x1
| SharedButtonStatus
|-
| 0x5
| 0x1
| LeftPadButtonStatus
|-
| 0x6
| 0x3
| LeftAnalogStickData
|-
| 0x9
| 0x3
| RightAnalogStickData
|-
| 0xC
| 0x1
| MotorStatus
|-
| 0xD
| 0x23
| McuUpdateData
|}
 
== HidBasicInputReport ==
This is a 0x31-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| LatencyTimer
|-
| 0x2
| 0x1
| PowerInfo
|-
| 0x3
| 0x1
| RightPadButtonStatus
|-
| 0x4
| 0x1
| SharedButtonStatus
|-
| 0x5
| 0x1
| LeftPadButtonStatus
|-
| 0x6
| 0x3
| LeftAnalogStickData
|-
| 0x9
| 0x3
| RightAnalogStickData
|-
| 0xC
| 0x1
| MotorStatus
|-
| 0xD
| 0x24
| BasicData
|}
 
== HidMcuInputReport ==
This is a 0x16A-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| LatencyTimer
|-
| 0x2
| 0x1
| PowerInfo
|-
| 0x3
| 0x1
| RightPadButtonStatus
|-
| 0x4
| 0x1
| SharedButtonStatus
|-
| 0x5
| 0x1
| LeftPadButtonStatus
|-
| 0x6
| 0x3
| LeftAnalogStickData
|-
| 0x9
| 0x3
| RightAnalogStickData
|-
| 0xC
| 0x1
| MotorStatus
|-
| 0xD
| 0x6
| SensorAccelSample0
|-
| 0x13
| 0x6
| SensorGyroSample0
|-
| 0x19
| 0x6
| SensorAccelSample1
|-
| 0x1F
| 0x6
| SensorGyroSample1
|-
| 0x25
| 0x6
| SensorAccelSample2
|-
| 0x2B
| 0x6
| SensorGyroSample2
|-
| 0x31
| 0x139
| McuData
|}
 
== HidAttachmentInputReport ==
This is a 0x16A-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| LatencyTimer
|-
| 0x2
| 0x1
| PowerInfo
|-
| 0x3
| 0x1
| RightPadButtonStatus
|-
| 0x4
| 0x1
| SharedButtonStatus
|-
| 0x5
| 0x1
| LeftPadButtonStatus
|-
| 0x6
| 0x3
| LeftAnalogStickData
|-
| 0x9
| 0x3
| RightAnalogStickData
|-
| 0xC
| 0x1
| MotorStatus
|-
| 0xD
| 0x6
| SensorAccelSample0
|-
| 0x13
| 0x6
| SensorGyroSample0
|-
| 0x19
| 0x6
| SensorAccelSample1
|-
| 0x1F
| 0x6
| SensorGyroSample1
|-
| 0x25
| 0x6
| SensorAccelSample2
|-
| 0x2B
| 0x6
| SensorGyroSample2
|-
| 0x31
| 0x139
| AttachmentData
|}
 
== HidGenericInputReport ==
This is a 0xC-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x2
| ButtonStatus
|-
| 0x3
| 0x1
| StickHatData
|-
| 0x4
| 0x4
| LeftAnalogStickData
|-
| 0x8
| 0x4
| RightAnalogStickData
|}
 
== HidCommandOutputReport ==
This is a 0x31-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| PacketNumber
|-
| 0x2
| 0x8
| [[#HidMotorData|MotorData]]
|-
| 0xA
| 0x1
| [[#HidCommand|CommandId]]
|-
| 0xB
| 0x26
| CommandData
|}
 
== HidMcuUpdateOutputReport ==
This is a 0x13E-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| PacketNumber
|-
| 0x2
| 0x8
| [[#HidMotorData|MotorData]]
|-
| 0xA
| 0x134
| McuUpdateData
|}
 
== HidBasicOutputReport ==
This is a 0xA-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| PacketNumber
|-
| 0x2
| 0x8
| [[#HidMotorData|MotorData]]
|}
 
== HidMcuOutputReport ==
This is a 0x30-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| PacketNumber
|-
| 0x2
| 0x8
| [[#HidMotorData|MotorData]]
|-
| 0xA
| 0x26
| McuData
|}
 
== HidAttachmentOutputReport ==
This is a 0x30-byte struct.
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| [[#HidReportId|ReportId]]
|-
| 0x1
| 0x1
| PacketNumber
|-
| 0x2
| 0x8
| [[#HidMotorData|MotorData]]
|-
| 0xA
| 0x26
| AttachmentData
|}
 
== HidReportId ==
{| class="wikitable" border="1"
! Value
! Description
|-
| 0x01 || CommandOutputReport
|-
| 0x03 || McuUpdateOutputReport
|-
| 0x10 || BasicOutputReport
|-
| 0x11 || McuOutputReport
|-
| 0x12 || AttachmentOutputReport
|-
| 0x21 || CommandInputReport
|-
| 0x23 || McuUpdateInputReport
|-
| 0x30 || BasicInputReport
|-
| 0x31 || McuInputReport
|-
| 0x32 || AttachmentInputReport
|-
| 0x33 ||
|-
| 0x3F || GenericInputReport
|-
| 0x70 || OtaEnableFwuReport
|-
| 0x71 || OtaSetupReadReport
|-
| 0x72 || OtaReadReport
|-
| 0x73 || OtaEraseReport
|-
| 0x74 || OtaWriteReport
|-
| 0x75 || OtaLaunchReport
|-
| 0x80 || ExtGripOutputReport
|-
| 0x81 || ExtGripInputReport
|-
| 0x82 ||
|}
 
== HidMotorData ==
{| class="wikitable" border="1"
|-
|-
| Technology    || Bluetooth
! Offset
! Size
! Description
|-
|-
| Interface    || HID
| 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)
|}


== Left & Right Separate Joy-con ==
=== 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)
|}


When paired directly to a computer over bluetooth, the joy-con both provide identical HID input report descriptor. This does not appear to include motion controls, IR data, or NFC. They both behave as detached single-player controllers.
=== 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)
|}


HID Input Report Descriptor (Hexadecimal):
=== VibrationAmFmPackFormatThree ===
05010905A1010601FF85210921750895308102853009307508953081028531093175089669018102853209327508966901810285330933750896690
{| class="wikitable" border="1"
18102853F05091901291015002501750195108102050109391500250775049501814205097504950181010501093009310933093416000027FFFF00
! Bits
007510950481020601FF85010901750895309102851009107508953091028511091175089530910285120912750895309102C0
! 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)
|}


{| class="mw-collapsible mw-collapsed wikitable"
=== VibrationAmFmPackFormatThree7bit ===
! Parsed Bytes || Description
{| class="wikitable" border="1"
! Bits
! Description
|-
|-
|0x05, 0x01,        || Usage Page (Generic Desktop Ctrls)
| 0 || IsChannelHigh
|-
|-
|0x09, 0x05,        || Usage (Game Pad)
| 1 || IsThree7bit (must be 1)
|-
|-
|0xA1, 0x01,        || Collection (Application)
| 2 || IsFm
|-
|-
|0x06, 0x01, 0xFF,  ||   Usage Page (Vendor Defined 0xFF01)
| 3-7 || VibrationCodesHigh1
|-
|-
|0x85, 0x21,        ||   Report ID (33)
| 8-12 || VibrationCodesLow1
|-
|-
|0x09, 0x21,        ||   Usage (0x21)
| 13-17 || VibrationCodesHigh0
|-
|-
|0x75, 0x08,        ||   Report Size (8)
| 18-22 || VibrationCodesLow0
|-
|-
|0x95, 0x30,        ||   Report Count (48)
| 23-29 || ChannelAmFm
|-
|-
|0x81, 0x02,        ||   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
| 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"
|-
|-
|0x85, 0x30,        ||  Report ID (48)
! Offset
! Size
! Description
|-
|-
|0x09, 0x30,        ||   Usage (0x30)
| 0x0 || 0x4 || <nowiki>(ChannelCodesLow & 0x1F)</nowiki>
|-
|-
|0x75, 0x08,        ||   Report Size (8)
| 0x4 || 0x4 || <nowiki>(ChannelCodesHigh & 0x1F)</nowiki>
|-
|-
|0x95, 0x30,        ||   Report Count (48)
| 0x8 || 0x4 || <nowiki>(VibrationCodesLow0 & 0x1F)</nowiki>
|-
|-
|0x81, 0x02,        ||   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
| 0xC || 0x4 || <nowiki>(VibrationCodesHigh0 & 0x1F)</nowiki>
|-
|-
|0x85, 0x31,        ||   Report ID (49)
| 0x10 || 0x4 || <nowiki>(VibrationCodesLow1 & 0x1F)</nowiki>
|-
|-
|0x09, 0x31,        ||   Usage (0x31)
| 0x14 || 0x4 || <nowiki>(VibrationCodesHigh1 & 0x1F)</nowiki>
|}
 
==== AmFm7BitOneCodes ====
Converted from [[#VibrationAmFmPackFormatOne28bit|VibrationAmFmPackFormatOne28bit]].
 
{| class="wikitable" border="1"
|-
|-
|0x75, 0x08,        ||  Report Size (8)
! Offset
! Size
! Description
|-
|-
|0x96, 0x69, 0x01,  ||   Report Count (361)
| 0x0 || 0x4 || <nowiki>(((ChannelFrequencyLow & 0x7F) << 8) | (ChannelAmplitudeLow & 0x7F) | 0x8080)</nowiki>
|-
|-
|0x81, 0x02,        ||   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
| 0x4 || 0x4 || <nowiki>(((ChannelFrequencyHigh & 0x7F) << 8) | (ChannelAmplitudeHigh & 0x7F) | 0x8080)</nowiki>
|}
 
==== AmFm7BitTwoCodes ====
Converted from [[#VibrationAmFmPackFormatTwo14bitLow|VibrationAmFmPackFormatTwo14bitLow]] or [[#VibrationAmFmPackFormatTwo14bitHigh|VibrationAmFmPackFormatTwo14bitHigh]].
 
{| class="wikitable" border="1"
|-
|-
|0x85, 0x32,        ||  Report ID (50)
! Offset
! Size
! Description
|-
|-
|0x09, 0x32,        ||   Usage (0x32)
| 0x0 || 0x4 || <nowiki>IsChannelHigh ? (VibrationCodesLow0 & 0x1F) : (((ChannelFrequency & 0x7F) << 8) | (ChannelAmplitude & 0x7F) | 0x8080)</nowiki>
|-
|-
|0x75, 0x08,        ||   Report Size (8)
| 0x4 || 0x4 || <nowiki>IsChannelHigh ? (((ChannelFrequency & 0x7F) << 8) | (ChannelAmplitude & 0x7F) | 0x8080) : (VibrationCodesHigh0 & 0x1F)</nowiki>
|-
|-
|0x96, 0x69, 0x01,  ||   Report Count (361)
| 0x8 || 0x4 || <nowiki>(VibrationCodesLow1 & 0x1F)</nowiki>
|-
|-
|0x81, 0x02,        ||   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
| 0xC || 0x4 || <nowiki>(VibrationCodesHigh1 & 0x1F)</nowiki>
|-
|-
|0x85, 0x33,        ||   Report ID (51)
| 0x10 || 0x4 || <nowiki>Always 0x18</nowiki>
|-
|-
|0x09, 0x33,        ||   Usage (0x33)
| 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>
|-
|-
|0x75, 0x08,        ||   Report Size (8)
| 0x8 || 0x4 || <nowiki>(VibrationCodesLow0 & 0x1F)</nowiki>
|-
|-
|0x96, 0x69, 0x01,  ||   Report Count (361)
| 0xC || 0x4 || <nowiki>(VibrationCodesHigh0 & 0x1F)</nowiki>
|-
|-
|0x81, 0x02,        ||   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
| 0x10 || 0x4 || <nowiki>(VibrationCodesLow1 & 0x1F)</nowiki>
|-
|-
|0x85, 0x3F,        ||   Report ID (63)
| 0x14 || 0x4 || <nowiki>(VibrationCodesHigh1 & 0x1F)</nowiki>
|}
 
== DeviceCommand ==
{| class="wikitable" border="1"
! Value
! Description
|-
|-
|0x05, 0x09,        ||   Usage Page (Button)
| 0x01 || Inquiry
|-
|-
|0x19, 0x01,        ||   Usage Minimum (0x01)
| 0x02 || WriteChargerSettings
|-
|-
|0x29, 0x10,        ||   Usage Maximum (0x10)
| 0x03 || ReadChargerSettings
|-
| 0x04 || AttachmentEnable
|-
| 0x05 || IsAttachmentEnabled
|-
| 0x06 || GetBatteryVoltage
|-
| 0x07 || ReadWakeUpReason
|-
| 0x10 || CreateHidConnection
|-
| 0x11 || DisconnectHid
|-
| 0x12 || SetHidInterval
|-
| 0x13 || GetHidInterval
|-
| 0x18 || Pairing
|-
| 0x20 || UpdateUartBaudRate
|-
| 0x40 || Test
|}
 
== HidCommand ==
{| class="wikitable" border="1"
! Value
! Description
|-
| 0x01 || PairingOut
|-
| 0x02 || GetDeviceInfo
|-
| 0x03 || SetDataFormat
|-
| 0x04 || LRButtonDetection
|-
| 0x05 || Page
|-
| 0x06 || Reset
|-
| 0x07 || ClearPairingInfo
|-
| 0x08 || Shipment
|-
| 0x10 || SerialFlashRead
|-
| 0x11 || SerialFlashWrite
|-
| 0x12 || SerialFlashSectorErase
|-
| 0x20 || McuReset
|-
| 0x21 || McuWrite
|-
| 0x22 || McuResume
|-
| 0x24 || McuPollingEnable
|-
| 0x25 || McuPollingDisable
|-
| 0x28 || AttachmentWrite
|-
| 0x29 || AttachmentRead
|-
| 0x2A || AttachmentEnable
|-
| 0x2B || GetAttachmentInfo
|-
| 0x30 || SetIndicatorLed
|-
| 0x31 || GetIndicatorLed
|-
| 0x38 || SetNotificationLed
|-
| 0x40 || SensorSleep
|-
| 0x41 || SensorConfig
|-
| 0x42 || SensorWrite
|-
| 0x43 || SensorRead
|-
| 0x48 || MotorEnable
|-
| 0x50 || GetBatteryVoltage
|-
| 0x51 || WriteChargeSetting
|-
| 0x52 || ReadChargeSetting
|-
| 0x58 || ExtDevWrite
|-
| 0x59 || GetExtDevInfo
|-
| 0x5A || ExtDevPollingEnable
|-
| 0x5B || ExtDevPollingDisable
|-
| 0x5C || ExtDevInFormatConfig
|-
| 0x5D ||
|-
| 0x60 || InternalAttachmentWrite
|-
| 0x61 ||
|-
| 0x62 || InternalAttachmentEnable
|-
| 0x63 || InternalAttachmentPollingEnable
|-
| 0x64 || InternalAttachmentPollingDisable
|-
| 0x7A || AddButtonPlayData
|-
| 0x7B || StartStopButtonPlayData
|-
| 0x80 || Ack
|-
| 0x81 || PairingIn
|-
| 0x82 || DeviceInfo
|-
| 0x83 || LRButtonElapsedTime
|-
| 0x90 || SerialFlashData
|-
| 0xA0 || McuData
|-
| 0xA8 || AttachmentData
|-
| 0xA9 || AttachmentInfo
|-
| 0xAA || InternalAttachmentRead
|-
| 0xB0 || IndicatorLed
|-
| 0xC0 || SensorData
|-
| 0xD0 || BatteryVoltage
|-
| 0xD8 || ExtDevRead
|-
| 0xD9 || ExtDevInfo
|}
 
== ExtGripCommand ==
{| class="wikitable" border="1"
! Value
! Description
|-
| 0x01 || Inquiry
|-
| 0x02 || CreateHidConnection
|-
| 0x03 || DeleteHidConnection
|-
| 0x04 || StartHidData
|-
| 0x05 || StopHidData
|-
| 0x06 ||
|-
| 0x07 || GetFirmwareVersion
|-
| 0x08 ||
|-
| 0x91 || LoopbackTest
|-
| 0x92 ||
|-
| 0xA0 || SetUartClockTrim
|}
 
= Firmware =
The firmware is stored inside the flash in Broadcom's PatchRAM format as follows:
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x1000 || StaticSection
|-
| 0x1000 || 0x1000 || [[#FailsafeSection|FailsafeSection]]
|-
| 0x2000 || 0x1000 || [[#VolatileSection|VolatileSection]]
|-
| 0x3000 || 0x1000 || VolatileSectionBackup1
|-
| 0x4000 || 0x1000 || VolatileSectionBackup2
|-
| 0x5000 || 0x1000 || [[#ShipmentInfo|ShipmentInfo]]
|-
| 0x6000 || 0x1000 || [[#FactoryConfiguration|FactoryConfiguration]]
|-
| 0x7000 || 0x1000 || Reserved
|-
| 0x8000 || 0x1000 || [[#UserCalibration|UserCalibration]]
|-
| 0x9000 || 0x7000 || Reserved
|-
| 0x10000 || 0x18000 || DynamicSection1
|-
| 0x28000 || 0x18000 || DynamicSection2
|-
| 0x40000 || 0x40000 || Reserved
|}
 
== FailsafeSection ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0xFF4 || Reserved
|-
| 0xFF4 || 0x8 || Signature
|-
| 0xFFC || 0x4 || Ds2Offset
|}
 
== VolatileSection ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x26 ||
|-
| 0x26 || 0xFDA || Reserved
|}
 
== ShipmentInfo ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x1 || Shipment
|-
| 0x1 || 0xFFF || Reserved
|}
 
== FactoryConfiguration ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x10 || IdentificationCode
|-
| 0x10 || 0x2 || Reserved
|-
| 0x12 || 0x1 || [[#DeviceType|DeviceType]]
|-
| 0x13 || 0x1 || BoardRevision
|-
| 0x14 || 0x7 || Reserved
|-
| 0x1B || 0x1 || FormatVersion
|-
| 0x1C || 0x4 || Reserved
|-
| 0x20 || 0x18 || [[#Cal1|Cal1]]
|-
| 0x38 || 0x5 || Reserved
|-
| 0x3D || 0x12 || [[#Cal2|Cal2]]
|-
| 0x4F || 0x1 || Reserved
|-
| 0x50 || 0xD || [[#Design|Design]]
|-
| 0x5D || 0x23 || Reserved
|-
| 0x80 || 0x18 || [[#Model1|Model1]]
|-
| 0x98 || 0x12 || [[#Model2|Model2]]
|-
| 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
|}
 
=== DeviceType ===
{| class="wikitable" border="1"
|-
! Value
! Description
|-
| 0x01 || JoyConLeft
|-
| 0x02 || JoyConRight
|-
| 0x03 || SwitchProController
|-
| 0x04 || MiyabiLeft
|-
| 0x05 || MiyabiRight
|-
| 0x06 || Tarragon
|-
| 0x07 || LarkH1
|-
| 0x08 || LarkH2
|-
| 0x09 || LarkNL
|-
| 0x0A || LarkNR
|-
| 0x0B || Lucia
|-
| 0x0C || [12.0.0+] Lagon
|-
| 0x0D || [13.0.0+] Lager
|-
| 0x0E || [14.0.0+] Tarragon2
|-
| 0x21 || FiftyL
|-
| 0x22 || FiftyR
|}
 
=== Cal1 ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 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
|}
 
=== Cal2 ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 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
|-
| 0x7 || 0x2 || AnalogStickCalYNegative
|}
 
=== Design ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0xC || [[#ControllerColor|ControllerColor]]
|-
| 0xC || 0x1 || [[#DesignVariation|DesignVariation]]
|}
 
==== ControllerColor ====
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 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
|-
| 0x9 || 0x1 || 4thColorR
|-
| 0xA || 0x1 || 4thColorG
|-
| 0xB || 0x1 || 4thColorB
|}
 
==== DesignVariation ====
{| class="wikitable" border="1"
|-
! Value
! Name
|-
| 0x0 || LuciaJ, LagerJ
|-
| 0x1 || LuciaE, LagerE
|-
| 0x2 || LuciaU, LagerU
|}
 
=== Model1 ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x6 || [[#SixAxisSensorModelValue|SixAxisSensorModelValue]]
|-
| 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
|}
 
=== Model2 ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x12 || [[#AnalogStickModelValue|AnalogStickSubModelValue]]
|}
 
== UserCalibration ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x10 || Reserved
|-
| 0x10 || 0x16 || [[#UserCal1|UserCal1]]
|-
| 0x26 || 0x1A || [[#UserCal2|UserCal2]]
|-
| 0x40 || 0xFC0 || Reserved
|}
 
=== UserCal1 ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x2 || AnalogStickMainUserMagicNumber
|-
| 0x2 || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickMainUserCalibrationValue]]
|-
| 0xB || 0x2 || AnalogStickSubUserMagicNumber
|-
| 0xD || 0x9 || [[#AnalogStickCalibrationValue|AnalogStickSubUserCalibrationValue]]
|}
 
=== UserCal2 ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0 || 0x2 || SixAxisUserCalibrationMagicNumber
|-
| 0x2 || 0x18 || [[#SixAxisSensorCalibrationValue|SixAxisUserCalibrationValue]]
|}
 
== Colors ==
HEX codes for the colors shown in the "Controllers" menu of the Switch UI can be found in a Joy-con SPI dump starting at offset 0x6050. Body color is first followed by button color and each is 3 bytes long. These values are able to be re-written with any HEX color value to make the Joy-cons show up as different colors in the UI. The following is a list of official HEX colors recovered from SPI dumps.
 
{| class="wikitable"
! Developer Kit Joy-Con || Release || Body HEX || Button HEX
|-
|-
|0x15, 0x00,        ||   Logical Minimum (0)
| Black / ブラック || 2015.10.16 || #313131 || #0F0F0F
|-
|-
|0x25, 0x01,        ||   Logical Maximum (1)
! Standard Retail Joy-Con Color || Release || Body HEX || Button HEX
|-
|-
|0x75, 0x01,        ||   Report Size (1)
| Gray / グレー || 2017.03.03 || #828282 || #0F0F0F
|-
|-
|0x95, 0x10,        ||   Report Count (16)
| Neon Red / ネオンレッド || 2017.03.03 || #FF3C28 || #1E0A0A
|-
|-
|0x81, 0x02,        ||   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
| Neon Blue / ネオンブルー || 2017.03.03 || #0AB9E6 || #001E1E
|-
|-
|0x05, 0x01,        ||   Usage Page (Generic Desktop Ctrls)
| Neon Yellow / ネオンイエロー || 2017.06.16 || #E6FF00 || #142800
|-
|-
|0x09, 0x39,        ||   Usage (Hat switch)
| Neon Green / ネオングリーン || 2017.07.21 || #1EDC00 || #002800
|-
|-
|0x15, 0x00,        ||   Logical Minimum (0)
| Neon Pink / ネオンピンク || 2017.07.21 || #FF3278 || #28001E
|-
|-
|0x25, 0x07,        ||   Logical Maximum (7)
| Red / レッド || 2017.10.27 || #E10F00 || #280A0A
|-
|-
|0x75, 0x04,        ||   Report Size (4)
| Blue / ブルー || 2019.10.04 || #4655F5 || #00000A
|-
|-
|0x95, 0x01,        ||   Report Count (1)
| Neon Purple / ネオンパープル || 2019.10.04 || #B400E6 || #140014
|-
|-
|0x81, 0x42,        ||   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
| Neon Orange / ネオンオレンジ || 2019.10.04 || #FAA005 || #0F0A00
|-
|-
|0x05, 0x09,        ||   Usage Page (Button)
| White / ホワイト || 2021.10.08 || #E6E6E6 || #323232
|-
|-
|0x75, 0x04,        ||   Report Size (4)
| Pastel Pink / パステルピンク || 2023.06.30 || #FFAFAF || #372D2D
|-
|-
|0x95, 0x01,        ||   Report Count (1)
| Pastel Yellow / パステルイエロー || 2023.06.30 || #F5FF82 || #32332D
|-
|-
|0x81, 0x01,        ||   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
| Pastel Purple / パステルパープル || 2023.06.30 || #F0CBEB || #373037
|-
|-
|0x05, 0x01,        ||   Usage Page (Generic Desktop Ctrls)
| Pastel Green / パステルグリーン || 2023.06.30 || #BCFFC8 || #2D322D
|-
|-
|0x09, 0x30,        ||   Usage (X)
! Special Edition Joy-Con Color || Release || Body HEX || Button HEX
|-
|-
|0x09, 0x31,        ||   Usage (Y)
| Nintendo Switch Gray Joy-Con / Nintendo Switch グレー || 2017.03.03 || #828282 || #0F0F0F
|-
|-
|0x09, 0x33,        ||   Usage (Rx)
| Nintendo Switch Neon-Blue Left Joy-Con / Nintendo Switch ネオンブルー・ネオンレッド || 2017.03.03 || #0AB9E6 || #001E1E
|-
|-
|0x09, 0x34,        ||   Usage (Ry)
| Nintendo Switch Neon-Red Right Joy-Con / Nintendo Switch ネオンブルー・ネオンレッド || 2017.03.03 || #FF3C28 || #1E0A0A
|-
|-
|0x16, 0x00, 0x00,  ||   Logical Minimum (0)
| Splatoon 2 Edition Neon-Green Left Joy-Con / スプラトゥーン2 || 2017.07.21 || #1EDC00 || #002800
|-
|-
|0x27, 0xFF, 0xFF, 0x00, 0x00,  ||   Logical Maximum (65534)
| Splatoon 2 Edition Neon-Pink Right Joy-Con / スプラトゥーン2 || 2017.07.21 || #FF3278 || #28001E
|-
|-
|0x75, 0x10,        ||   Report Size (16)
| Super Mario Odyssey Edition Red Joy-Con / スーパーマリオ オデッセイ || 2017.10.27 || #E10F00 || #280A0A
|-
|-
|0x95, 0x04,        ||   Report Count (4)
| Super Smash Bros. Ultimate Edition Gray Joy-Con / 大乱闘スマッシュブラザーズ || 2018.11.02 || #828282 || #0F0F0F
|-
|-
|0x81, 0x02,        ||   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
| Pokémon: Let's Go! Edition Eevee-Brown Left Joy-Con / ポケットモンスター Let's Go! イーブイ || 2018.11.16 || #C88C32 || #281900
|-
|-
|0x06, 0x01, 0xFF,  ||   Usage Page (Vendor Defined 0xFF01)
| Pokémon: Let's Go! Edition Pikachu-Yellow Right Joy-Con / ポケットモンスター Let's Go! ピカチュウ || 2018.11.16 || #FFDC00 || #322800
|-
|-
|0x85, 0x01,        ||   Report ID (1)
| *Nintendo Labo Creators Contest Edition "Cardboard"-Colored Joy-Con || 2018. (...?) || #D7AA73 || #1E1914
|-
|-
|0x09, 0x01,        ||   Usage (0x01)
| **Dragon Quest XI S Lotto Edition Royal-Blue Joy-Con / ドラゴン クエスト XI S (ロト版) || 2019.09.27 || #1473FA || #00000F
|-
|-
|0x75, 0x08,        ||   Report Size (8)
| **Disney Tsum Tsum Festival Edition Neon-Purple Left Joy-Con / ディズニー ツムツム フェスティバル || 2019.10.10 || #B400E6 || #140014
|-
|-
|0x95, 0x30,        ||   Report Count (48)
| **Disney Tsum Tsum Festival Edition Neon-Pink Right Joy-Con / ディズニー ツムツム フェスティバル || 2019.10.10 || #FF3278 || #28001E
|-
|-
|0x91, 0x02,        ||   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
| Animal Crossing: New Horizons Edition Pastel-Green Left Joy-Con / あつまれ どうぶつの森 || 2020.03.13 || #82FF96 || #0A1E0A
|-
|-
|0x85, 0x10,        ||   Report ID (16)
| Animal Crossing: New Horizons Edition Pastel-Blue Right Joy-Con / あつまれ どうぶつの森 || 2020.03.13 || #96F5F5 || #0A1E28
|-
|-
|0x09, 0x10,        ||   Usage (0x10)
| Fortnite Wildcat Edition Yellow Left Joy-Con / フォートナイト ワイルドキャット(山猫) || 2020.10.30 || #FFCC00 || #1A1100
|-
|-
|0x75, 0x08,        ||   Report Size (8)
| Fortnite Wildcat Edition Dark-Blue Right Joy-Con / フォートナイト ワイルドキャット(山猫) || 2020.10.30 || #0084FF || #000F1E
|-
|-
|0x95, 0x30,        ||   Report Count (48)
| Mario Red × Blue Edition Red Joy-Con / マリオ レッド × ブルー || 2021.02.12 || #F04614 || #1E1914
|-
|-
|0x91, 0x02,        ||   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
| Monster Hunter Rise Edition Gray Joy-Con / モンスターハンターライズ || 2021.03.26 || #818282 || #0E0F0F
|-
|-
|0x85, 0x11,        ||   Report ID (17)
| Fortnite Fleet Force Edition Dark-Blue Left Joy-Con / フォートナイト フリート フォース(力の艦隊) || 2021.06.04 || #0084FF || #000F1E
|-
|-
|0x09, 0x11,        ||   Usage (0x11)
| Fortnite Fleet Force Edition Yellow Right Joy-Con / フォートナイト フリート フォース(力の艦隊) || 2021.06.04 || #FFCC00 || #1A1100
|-
|-
|0x75, 0x08,        ||   Report Size (8)
| Legend of Zelda: Skyward Sword Edition Dark-Blue Left Joy-Con / ゼルダの伝説 スカイウォードソード || 2021.07.16 || #2D50F0 || #1E0F46
|-
|-
|0x95, 0x30,        ||   Report Count (48)
| Legend of Zelda: Skyward Sword Edition Dark-Purple Right Joy-Con / ゼルダの伝説 スカイウォードソード || 2021.07.16 || #500FC8 || #00051E
|-
|-
|0x91, 0x02,        ||   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
| Nintendo Switch OLED Edition White Joy-Con / Nintendo Switch (有機ELモデル) ホワイト || 2021.10.08 || #E6E6E6 || #323232
|-
|-
|0x85, 0x12,        ||   Report ID (18)
| Splatoon 3 OLED Edition Blue-Gradient Left Joy-Con / (有機ELモデル) スプラトゥーン3 || 2022.08.26 || #6455F5 || #28282D
|-
|-
|0x09, 0x12,        ||   Usage (0x12)
| Splatoon 3 OLED Edition Neon-Yellow-Gradient Right Joy-Con / (有機ELモデル) スプラトゥーン3 || 2022.08.26 || #C3FA05 || #1E1E28
|-
|-
|0x75, 0x08,        ||   Report Size (8)
| Pokémon: Scarlet × Violet OLED Edition Scarlet Left Joy-Con / (有機ELモデル) ポケットモンスター スカーレット・バイオレット || 2022.11.04 || #F07341 || #322D1E
|-
|-
|0x95, 0x30,        ||   Report Count (48)
| Pokémon: Scarlet × Violet OLED Edition Violet Right Joy-Con / (有機ELモデル) ポケットモンスター スカーレット・バイオレット || 2022.11.04 || #9650AA || #32322D
|-
|-
|0x91, 0x02,        ||   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
| Legend of Zelda: Tears of the Kingdom Edition Gold Joy-Con / (有機ELモデル) ゼルダの伝説 ティアーズ オブ ザ キングダム || 2023.04.28 || #D2BE69 || #32322D
|-
|-
|0xC0,              || End Collection
| // *(Prize Awarded for Labo Contest - No Retail) // **(Available Japan Only)
|}
|}