Line 1: |
Line 1: |
− | Joy-Con is the name for the Switch's primary game controllers. The controllers communicate to the console through bluetooth and can be disconnected from the main unit. | + | Joy-Con is the name for the Switch's primary game controllers. The Joy-Con are internally called Ukyo (Left) and Sakyo (Right). |
| | | |
| = Hardware = | | = Hardware = |
− | The controllers themselves are simple to disassemble and identify.
| + | == Ukyo == |
− | [[File:JoyconFront.jpg|400px|thumb|The front of the Joy-Con internal[https://www.ifixit.com/Teardown/Nintendo+Switch+Teardown/78263]]]
| |
− | [[File:JoyconRear.jpg|400px|thumb|The rear of the Joy-Con internal[https://www.ifixit.com/Teardown/Nintendo+Switch+Teardown/78263]]]
| |
| {| class="wikitable" | | {| class="wikitable" |
− | ! Color || Item | + | ! Component || Description |
| |- | | |- |
− | | Red || Broadcom BCM20734 Bluetooth 4.1/2.4 GHz Transceiver | + | | SoC || Broadcom BCM20734 |
| |- | | |- |
− | | Orange || STMicroelectronics NFCBEA 812006 33 (Likely NFC reader IC) | + | | IMU || STMicroelectronics LSM6DS3H |
| |- | | |- |
− | | Yellow|| Macronix International MX25U4033E 4 Mb CMOS Flash | + | | PMIC || Texas Instruments BQ24072 |
| + | |- |
| + | | Storage || Macronix International MX25U4033E 4 Mb CMOS Flash |
| |} | | |} |
| | | |
− | = Firmware = | + | == Sakyo == |
− | ''See also: [[Joy-Con Firmware]]''
| |
− | | |
− | The firmware of the Joy-Cons seems to be generic across all instances. Details such as the handedness of the controller and the color is just indicated in a configuration part of the flash. Judging by quick glance at the firmware, it's probably identical to that used on the Pro Controller as well.
| |
| {| class="wikitable" | | {| class="wikitable" |
− | ! Controller || 1.0.0 | + | ! Component || Description |
| |- | | |- |
− | | Joy-Con Left (Blue) || [[:File:pad.L.bin|flash dump]] | + | | SoC || Broadcom BCM20734 |
| |- | | |- |
− | | Joy-Con Right (Red) || [[:File:pad.R.bin|flash dump]] | + | | MCU || STMicroelectronics STM32P411 |
| + | |- |
| + | | NFC || STMicroelectronics ST21NFCB |
| + | |- |
| + | | IMU || STMicroelectronics LSM6DS3H |
| + | |- |
| + | | PMIC || Texas Instruments BQ24072 |
| + | |- |
| + | | Storage || Macronix International MX25U4033E 4 Mb CMOS Flash |
| |} | | |} |
− |
| |
− | The flash is in a patch-ram format. Tools for dealing with it are available [https://github.com/shuffle2/nxpad].
| |
− | A dump of the ROM region (taken while firmware was running) can be found [[:File:bcm20734_rom.bin|here]]. Note this is the same SoC used on the other controller models, as well.
| |
| | | |
| = Protocol = | | = Protocol = |
Line 295: |
Line 297: |
| |} | | |} |
| | | |
− | == Left & Right Separate Joy-con == | + | = Firmware = |
− | 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.
| + | The firmware is stored inside the flash in Broadcom's PatchRAM format as follows: |
| | | |
− | HID Input Report Descriptor (Hexadecimal):
| + | {| class="wikitable" border="1" |
− | <pre>
| |
− | 00000000: 05010905 A1010601 FF852109 21750895 ....¡...ÿ…!.!u.•
| |
− | 00000010: 30810285 30093075 08953081 02853109 0..…0.0u.•0..…1.
| |
− | 00000020: 31750896 69018102 85320932 75089669 1u.–i...…2.2u.–i
| |
− | 00000030: 01810285 33093375 08966901 8102853F ...…3.3u.–i...…?
| |
− | 00000040: 05091901 29101500 25017501 95108102 ....)...%.u.•...
| |
− | 00000050: 05010939 15002507 75049501 81420509 ...9..%.u.•..B..
| |
− | 00000060: 75049501 81010501 09300931 09330934 u.•......0.1.3.4
| |
− | 00000070: 16000027 FFFF0000 75109504 81020601 ...'ÿÿ..u.•.....
| |
− | 00000080: FF850109 01750895 30910285 10091075 ÿ…...u.•0‘.…...u
| |
− | 00000090: 08953091 02851109 11750895 30910285 .•0‘.…...u.•0‘.…
| |
− | 000000A0: 12091275 08953091 02C0 ...u.•0‘.À
| |
− | </pre>
| |
− | | |
− | {| class="wikitable" | |
− | ! Parsed Bytes || Description
| |
| |- | | |- |
− | |0x05, 0x01, || Usage Page (Generic Desktop Ctrls)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x09, 0x05, || Usage (Game Pad) | + | | 0x00 || 0x14 || Magic number?? |
| |- | | |- |
− | |0xA1, 0x01, || Collection (Application) | + | | 0x15 || 0x06 || Unique MAC Address of controller |
| |- | | |- |
− | |0x06, 0x01, 0xFF, || Usage Page (Vendor Defined 0xFF01) | + | | 0x3B3 || 0x04 || Offset to Factory Firmware |
| |- | | |- |
− | |0x85, 0x21, || Report ID (33) | + | | 0x1FF4 || 0x08 || OTA Magic, if the controller is Over-The-Air updated. |
| |- | | |- |
− | |0x09, 0x21, || Usage (0x21) | + | | 0x1FFC || 0x04 || Offset to OTA Firmware, if OTA Magic is valid. |
| |- | | |- |
− | |0x75, 0x08, || Report Size (8) | + | | 0x2000 || 0x1000 || PairingInfo |
| |- | | |- |
− | |0x95, 0x30, || Report Count (48) | + | | 0x5000 || 0x1 || Shipment |
| |- | | |- |
− | |0x81, 0x02, || Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) | + | | 0x6000 || 0x1000 || [[#FactoryConfiguration|FactoryConfiguration]] |
| |- | | |- |
− | |0x85, 0x30, || Report ID (48) | + | | 0x8000 || 0x1000 || [[#UserCalibration|UserCalibration]] |
| + | |} |
| + | |
| + | == FactoryConfiguration == |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x09, 0x30, || Usage (0x30)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x75, 0x08, || Report Size (8) | + | | 0x00 || 0x10 || IdentificationCode |
| |- | | |- |
− | |0x95, 0x30, || Report Count (48) | + | | 0x12 || 0x01 || [[#Type|Type]] |
| |- | | |- |
− | |0x81, 0x02, || Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) | + | | 0x1B || 0x01 || FormatVersion |
| |- | | |- |
− | |0x85, 0x31, || Report ID (49) | + | | 0x20 || 0x18 || [[#Cal1|Cal1]] |
| |- | | |- |
− | |0x09, 0x31, || Usage (0x31) | + | | 0x3D || 0x12 || [[#Cal2|Cal2]] |
| |- | | |- |
− | |0x75, 0x08, || Report Size (8) | + | | 0x4F || 0x01 || Reserved |
| |- | | |- |
− | |0x96, 0x69, 0x01, || Report Count (361) | + | | 0x50 || 0x0D || [[#Design|Design]] |
| |- | | |- |
− | |0x81, 0x02, || Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) | + | | 0x80 || 0x18 || [[#Model1|Model1]] |
| |- | | |- |
− | |0x85, 0x32, || Report ID (50) | + | | 0x98 || 0x12 || [[#Model2|Model2]] |
| + | |} |
| + | |
| + | === Type === |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x09, 0x32, || Usage (0x32)
| + | ! Value |
| + | ! Description |
| |- | | |- |
− | |0x75, 0x08, || Report Size (8) | + | | 0x01 || JoyLeft |
| |- | | |- |
− | |0x96, 0x69, 0x01, || Report Count (361) | + | | 0x02 || JoyRight |
| |- | | |- |
− | |0x81, 0x02, || Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) | + | | 0x03 || SwitchProController |
| |- | | |- |
− | |0x85, 0x33, || Report ID (51) | + | | 0x04 || ([[HID_services#DeviceTypeInternal|DeviceType]] 4) |
| |- | | |- |
− | |0x09, 0x33, || Usage (0x33) | + | | 0x05 || ([[HID_services#DeviceTypeInternal|DeviceType]] 5) |
| |- | | |- |
− | |0x75, 0x08, || Report Size (8) | + | | 0x06 || ([[HID_services#DeviceTypeInternal|DeviceType]] 6) |
| |- | | |- |
− | |0x96, 0x69, 0x01, || Report Count (361) | + | | 0x07 || LarkHvc1 |
| |- | | |- |
− | |0x81, 0x02, || Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) | + | | 0x08 || LarkHvc2 |
| |- | | |- |
− | |0x85, 0x3F, || Report ID (63) | + | | 0x09 || LarkNesLeft |
| |- | | |- |
− | |0x05, 0x09, || Usage Page (Button) | + | | 0x0A || LarkNesRight |
| |- | | |- |
− | |0x19, 0x01, || Usage Minimum (0x01) | + | | 0x0B || Lucia |
| |- | | |- |
− | |0x29, 0x10, || Usage Maximum (0x10) | + | | 0x0C || [12.0.0+] Lagon |
| |- | | |- |
− | |0x15, 0x00, || Logical Minimum (0) | + | | 0x0D || [13.0.0+] Lager |
| |- | | |- |
− | |0x25, 0x01, || Logical Maximum (1) | + | | 0x0E || [14.0.0+] ([[HID_services#DeviceTypeInternal|DeviceType]] 30) |
| |- | | |- |
− | |0x75, 0x01, || Report Size (1) | + | | 0x21 || FiftyLeft ([[HID_services#DeviceTypeInternal|DeviceType]] 14) |
| |- | | |- |
− | |0x95, 0x10, || Report Count (16) | + | | 0x22 || FiftyRight ([[HID_services#DeviceTypeInternal|DeviceType]] 18) |
| + | |} |
| + | |
| + | === Cal1 === |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x81, 0x02, || Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x05, 0x01, || Usage Page (Generic Desktop Ctrls) | + | | 0x00 || 0x18 || SixAxisSensorCalibrationValue |
| + | |} |
| + | |
| + | === Cal2 === |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x09, 0x39, || Usage (Hat switch)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x15, 0x00, || Logical Minimum (0) | + | | 0x00 || 0x09 || LeftAnalogStickCalibrationValue |
| |- | | |- |
− | |0x25, 0x07, || Logical Maximum (7) | + | | 0x09 || 0x09 || RightAnalogStickCalibrationValue |
| + | |} |
| + | |
| + | === Design === |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x75, 0x04, || Report Size (4)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x95, 0x01, || Report Count (1) | + | | 0x00 || 0x0C || [[#ControllerColor|ControllerColor]] |
| |- | | |- |
− | |0x81, 0x42, || Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State) | + | | 0x0C || 0x01 || [[#DesignVariation|DesignVariation]] |
| + | |} |
| + | |
| + | ==== ControllerColor ==== |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x05, 0x09, || Usage Page (Button)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x75, 0x04, || Report Size (4) | + | | 0x00 || 0x03 || Body color of controller in RGB Hex (see [[Joy-Con#Colors|Joy-Con Colors]]) |
| |- | | |- |
− | |0x95, 0x01, || Report Count (1) | + | | 0x03 || 0x03 || Button color of controller in RGB Hex (see [[Joy-Con#Colors|Joy-Con Colors]]) |
| |- | | |- |
− | |0x81, 0x01, || Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) | + | | 0x06 || 0x03 || Left grip color of controller in RGB Hex |
| |- | | |- |
− | |0x05, 0x01, || Usage Page (Generic Desktop Ctrls) | + | | 0x09 || 0x03 || Right grip color of controller in RGB Hex |
| + | |} |
| + | |
| + | ==== DesignVariation ==== |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x09, 0x30, || Usage (X)
| + | ! Value |
| + | ! Name |
| |- | | |- |
− | |0x09, 0x31, || Usage (Y) | + | | 0x00 || LuciaJ, LagerJ |
| |- | | |- |
− | |0x09, 0x33, || Usage (Rx) | + | | 0x01 || LuciaE, LagerE |
| |- | | |- |
− | |0x09, 0x34, || Usage (Ry) | + | | 0x02 || LuciaU, LagerU |
| + | |} |
| + | |
| + | === Model1 === |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x16, 0x00, 0x00, || Logical Minimum (0)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x27, 0xFF, 0xFF, 0x00, 0x00, || Logical Maximum (65534) | + | | 0x00 || 0x06 || SensorData |
| |- | | |- |
− | |0x75, 0x10, || Report Size (16) | + | | 0x06 || 0x12 || AnalogStickModuleParam |
| + | |} |
| + | |
| + | === Model2 === |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x95, 0x04, || Report Count (4)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x81, 0x02, || Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) | + | | 0x00 || 0x12 || AnalogStickModuleParam |
| + | |} |
| + | |
| + | == UserCalibration == |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x06, 0x01, 0xFF, || Usage Page (Vendor Defined 0xFF01)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x85, 0x01, || Report ID (1) | + | | 0x10 || 0x18 || [[#UserCal1|UserCal1]] |
| |- | | |- |
− | |0x09, 0x01, || Usage (0x01) | + | | 0x28 || 0x18 || [[#UserCal2|UserCal2]] |
| + | |} |
| + | |
| + | === UserCal1 === |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x75, 0x08, || Report Size (8)
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| |- | | |- |
− | |0x95, 0x30, || Report Count (48) | + | | 0x00 || 0x02 || UserCalMagicNumber |
| |- | | |- |
− | |0x91, 0x02, || Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) | + | | 0x02 || 0x09 || LeftAnalogStickCalibrationValue |
| |- | | |- |
− | |0x85, 0x10, || Report ID (16) | + | | 0x0B || 0x02 || UserCalMagicNumber |
| |- | | |- |
− | |0x09, 0x10, || Usage (0x10) | + | | 0x0D || 0x09 || RightAnalogStickCalibrationValue |
| |- | | |- |
− | |0x75, 0x08, || Report Size (8) | + | | 0x16 || 0x02 || UserCalMagicNumber |
| + | |} |
| + | |
| + | === UserCal2 === |
| + | {| class="wikitable" border="1" |
| |- | | |- |
− | |0x95, 0x30, || Report Count (48)
| + | ! Offset |
− | |-
| + | ! Size |
− | |0x91, 0x02, || Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
| + | ! Description |
− | |-
| |
− | |0x85, 0x11, || Report ID (17)
| |
− | |-
| |
− | |0x09, 0x11, || Usage (0x11)
| |
− | |-
| |
− | |0x75, 0x08, || Report Size (8)
| |
− | |-
| |
− | |0x95, 0x30, || Report Count (48)
| |
− | |-
| |
− | |0x91, 0x02, || Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
| |
− | |-
| |
− | |0x85, 0x12, || Report ID (18)
| |
− | |-
| |
− | |0x09, 0x12, || Usage (0x12)
| |
− | |-
| |
− | |0x75, 0x08, || Report Size (8)
| |
− | |-
| |
− | |0x95, 0x30, || Report Count (48)
| |
− | |-
| |
− | |0x91, 0x02, || Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
| |
| |- | | |- |
− | |0xC0, || End Collection | + | | 0x00 || 0x18 || SixAxisSensorCalibrationValue |
| |} | | |} |
| | | |
| == Colors == | | == 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. | | 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" | | {| class="wikitable" |
| ! Developer Kit Joy-Con || Release || Body HEX || Button HEX | | ! Developer Kit Joy-Con || Release || Body HEX || Button HEX |
Line 580: |
Line 617: |
| | // *(Prize Awarded for Labo Contest - No Retail) // **(Available Japan Only) | | | // *(Prize Awarded for Labo Contest - No Retail) // **(Available Japan Only) |
| |} | | |} |
− |
| |
− | = Additional Links =
| |
− | [https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering Reverse Engineering of the Joy-Con by Github user dekuNukem]
| |