|  |     | 
| (4 intermediate revisions by the same user not shown) | 
| Line 1: | Line 1: | 
|  | The Joy-Con are internally called Ukyo (Left) and Sakyo (Right). The firmware is written in C++.
 |  | #REDIRECT [[Joy-Con]] | 
|  |   |  | 
|  | = Joy-Con Firmware File =
 |  | 
|  | The length of the firmware must be 524288 bytes.
 |  | 
|  |   |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Endianness
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || B || 0x14 || Magic number??
 |  | 
|  | |-
 |  | 
|  | | 0x15 || L || 0x06 || Unique MAC Address of controller
 |  | 
|  | |-
 |  | 
|  | | 0x3B3 || L || 0x04 || Offset to Factory Firmware
 |  | 
|  | |-
 |  | 
|  | | 0x1FF4 || B || 0x08 || OTA Magic, if the controller is Over-The-Air updated.
 |  | 
|  | |-
 |  | 
|  | | 0x1FFC || L || 0x04 || Offset to OTA Firmware, if OTA Magic is valid.
 |  | 
|  | |-
 |  | 
|  | | 0x6000 || Mixed || 0x1000 || Factory configuration (see [[#Factory Configuration Sector|Factory Configuration Sector]])
 |  | 
|  | |-
 |  | 
|  | | 0x8000 || Mixed || 0x1000 || User calibration (see [[#User Calibration Sector|User Calibration Sector]])
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | == Factory Configuration Sector ==
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Endianness
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || B || 0x10 || IdentificationCode
 |  | 
|  | |-
 |  | 
|  | | 0x12 || B || 0x01 || [[#Type|Type]]
 |  | 
|  | |-
 |  | 
|  | | 0x1B || B || 0x01 || FormatVersion
 |  | 
|  | |-
 |  | 
|  | | 0x20 || B || 0x18 || [[#Cal1|Cal1]]
 |  | 
|  | |-
 |  | 
|  | | 0x3D || B || 0x12 || [[#Cal2|Cal2]]
 |  | 
|  | |-
 |  | 
|  | | 0x4F || B || 0x01 || Reserved
 |  | 
|  | |-
 |  | 
|  | | 0x50 || B || 0x0D || [[#Design|Design]]
 |  | 
|  | |-
 |  | 
|  | | 0x80 || B || 0x18 || [[#Model1|Model1]]
 |  | 
|  | |-
 |  | 
|  | | 0x98 || B || 0x12 || [[#Model2|Model2]]
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Type ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Value
 |  | 
|  | ! Name
 |  | 
|  | |-
 |  | 
|  | | 0x01 || JoyLeft
 |  | 
|  | |-
 |  | 
|  | | 0x02 || JoyRight
 |  | 
|  | |-
 |  | 
|  | | 0x03 || SwitchProController
 |  | 
|  | |-
 |  | 
|  | | 0x04 || Reserved ([[HID_services#DeviceTypeInternal|DeviceType]] 4)
 |  | 
|  | |-
 |  | 
|  | | 0x05 || Reserved ([[HID_services#DeviceTypeInternal|DeviceType]] 5)
 |  | 
|  | |-
 |  | 
|  | | 0x06 || Reserved ([[HID_services#DeviceTypeInternal|DeviceType]] 6)
 |  | 
|  | |-
 |  | 
|  | | 0x07 || LarkHvc1
 |  | 
|  | |-
 |  | 
|  | | 0x08 || LarkHvc2
 |  | 
|  | |-
 |  | 
|  | | 0x09 || LarkNesLeft
 |  | 
|  | |-
 |  | 
|  | | 0x0A || LarkNesRight
 |  | 
|  | |-
 |  | 
|  | | 0x0B || Lucia
 |  | 
|  | |-
 |  | 
|  | | 0x0C || Lagon
 |  | 
|  | |-
 |  | 
|  | | 0x0D || Lager
 |  | 
|  | |-
 |  | 
|  | | 0x21 || Reserved ([[HID_services#DeviceTypeInternal|DeviceType]] 14)
 |  | 
|  | |-
 |  | 
|  | | 0x22 || Reserved ([[HID_services#DeviceTypeInternal|DeviceType]] 18)
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Cal1 ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || 0x18 || SixAxisSensorCalibrationValue
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Cal2 ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || 0x09 || LeftAnalogStickCalibrationValue
 |  | 
|  | |-
 |  | 
|  | | 0x09 || 0x09 || RightAnalogStickCalibrationValue
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Design ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || 0x0C || [[#ControllerColor|ControllerColor]]
 |  | 
|  | |-
 |  | 
|  | | 0x0C || 0x01 || [[#DesignVariation|DesignVariation]]
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | ==== ControllerColor ====
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || 0x03 || Body color of controller in RGB Hex (see [[Joy-Con#Colors|Joy-Con Colors]])
 |  | 
|  | |-
 |  | 
|  | | 0x03 || 0x03 || Button color of controller in RGB Hex (see [[Joy-Con#Colors|Joy-Con Colors]])
 |  | 
|  | |-
 |  | 
|  | | 0x06 || 0x03 || Left grip color of controller in RGB Hex
 |  | 
|  | |-
 |  | 
|  | | 0x09 || 0x03 || Right grip color of controller in RGB Hex
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | ==== DesignVariation ====
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Value
 |  | 
|  | ! Name
 |  | 
|  | |-
 |  | 
|  | | 0x00 || LuciaJ, LagerJ
 |  | 
|  | |-
 |  | 
|  | | 0x01 || LuciaE, LagerE
 |  | 
|  | |-
 |  | 
|  | | 0x02 || LuciaU, LagerU
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Model1 ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || 0x06 || SensorData
 |  | 
|  | |-
 |  | 
|  | | 0x06 || 0x12 || AnalogStickModuleParam
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Model2 ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || 0x12 || AnalogStickModuleParam
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | == User Calibration Sector ==
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Endianness
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x10 || B || 0x18 || UserCal1
 |  | 
|  | |-
 |  | 
|  | | 0x28 || B || 0x18 || UserCal2
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === UserCal1 ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || 0x02 || UserCalMagicNumber
 |  | 
|  | |-
 |  | 
|  | | 0x02 || 0x09 || LeftAnalogStickCalibrationValue
 |  | 
|  | |-
 |  | 
|  | | 0x0B || 0x02 || UserCalMagicNumber
 |  | 
|  | |-
 |  | 
|  | | 0x0D || 0x09 || RightAnalogStickCalibrationValue
 |  | 
|  | |-
 |  | 
|  | | 0x16 || 0x02 || UserCalMagicNumber
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === UserCal2 ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || 0x18 || SixAxisSensorCalibrationValue
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | = Firmware Chunks =
 |  | 
|  | The firmware itself is stored in PatchRAM chunks, located at the Factory Offset or the OTA Offset. Each chunk has a Record Type, Size and Data.
 |  | 
|  |   |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Endianness
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || L || 0x01 || Record type (see [[#Record Types|Record Types]])
 |  | 
|  | |-
 |  | 
|  | | 0x01 || L || 0x02 || Size of data (size)
 |  | 
|  | |-
 |  | 
|  | | 0x03 || Mixed || (size) || Data
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | == Record Types ==
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Value
 |  | 
|  | ! Record name
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x08 || REC8 || ROM1 Patches (See [[#Record 0x08|Record 0x08]] and [[#Memory Regions|Memory Regions]])
 |  | 
|  | |-
 |  | 
|  | | 0x0A || RECA || RAM (Ram Low and Ram High) Patches (See [[#Record 0x0A|Record 0x0A]] and [[#Memory Regions|Memory Regions]])
 |  | 
|  | |-
 |  | 
|  | | 0x0B || RECB || Unknown
 |  | 
|  | |-
 |  | 
|  | | 0xFE || END || End of chunk stream
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Record 0x08 ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Endianness
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || L || 0x01 || Index
 |  | 
|  | |-
 |  | 
|  | | 0x01 || L || 0x04 || Address
 |  | 
|  | |-
 |  | 
|  | | 0x05 || B || 0x04 || Data
 |  | 
|  | |-
 |  | 
|  | | 0x09 || L || 0x02 || Unk1?
 |  | 
|  | |-
 |  | 
|  | | 0x0B || L || 0x02 || Unk2?
 |  | 
|  | |-
 |  | 
|  | | 0x0D || L || 0x02 || Body size???
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Record 0x0A ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Endianness
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | ! Note
 |  | 
|  | |-
 |  | 
|  | | 0x00 || L || 0x04 || Address || -
 |  | 
|  | |-
 |  | 
|  | | 0x04 || B || (Note) || Data || To calculate the size do: chunk_datasize (See [[#Firmware Chunks|Firmware Chunks]])-4
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | === Record 0x0B ===
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offset
 |  | 
|  | ! Endianness
 |  | 
|  | ! Size
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00 || L || 0x04 || Address
 |  | 
|  | |}
 |  | 
|  |   |  | 
|  | == Memory Regions ==
 |  | 
|  | {| class="wikitable" border="1"
 |  | 
|  | |-
 |  | 
|  | ! Offsets
 |  | 
|  | ! Description
 |  | 
|  | |-
 |  | 
|  | | 0x00-0xC8000 || ROM 1
 |  | 
|  | |-
 |  | 
|  | | 0x260000-0x26C000 || ROM 2
 |  | 
|  | |-
 |  | 
|  | | 0xD0000-0x0x0DFFFF || RAM Low
 |  | 
|  | |-
 |  | 
|  | | 0x200000-0x247FFF || RAM High
 |  | 
|  | |}
 |  |