The Joy-Con are internally called Ukyo (Left) and Sakyo (Right). The firmware is written in C++.
Joy-Con Firmware File
The length of the firmware must be 524288 bytes.
| 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)
|
| 0x8000 |
Mixed |
0x1000 |
User calibration (see User Calibration Sector)
|
Factory Configuration Sector
| Offset
|
Endianness
|
Size
|
Description
|
| 0x00 |
B |
0x10 |
IdentificationCode
|
| 0x12 |
B |
0x01 |
Type
|
| 0x1B |
B |
0x01 |
FormatVersion
|
| 0x20 |
B |
0x18 |
Cal1
|
| 0x3D |
B |
0x12 |
Cal2
|
| 0x4F |
B |
0x01 |
Reserved
|
| 0x50 |
B |
0x0D |
Design
|
| 0x80 |
B |
0x18 |
Model1
|
| 0x98 |
B |
0x12 |
Model2
|
Type
| Value
|
Name
|
| 0x01 |
JoyLeft
|
| 0x02 |
JoyRight
|
| 0x03 |
SwitchProController
|
| 0x04 |
Reserved (DeviceType 4)
|
| 0x05 |
Reserved (DeviceType 5)
|
| 0x06 |
Reserved (DeviceType 6)
|
| 0x07 |
LarkHvc1
|
| 0x08 |
LarkHvc2
|
| 0x09 |
LarkNesLeft
|
| 0x0A |
LarkNesRight
|
| 0x0B |
Lucia
|
| 0x0C |
Lagon
|
| 0x0D |
Lager
|
| 0x21 |
Reserved (DeviceType 14)
|
| 0x22 |
Reserved (DeviceType 18)
|
Cal1
| Offset
|
Size
|
Description
|
| 0x00 |
0x18 |
SixAxisSensorCalibrationValue
|
Cal2
| Offset
|
Size
|
Description
|
| 0x00 |
0x09 |
LeftAnalogStickCalibrationValue
|
| 0x09 |
0x09 |
RightAnalogStickCalibrationValue
|
Design
ControllerColor
| Offset
|
Size
|
Description
|
| 0x00 |
0x03 |
Body color of controller in RGB Hex (see Joy-Con Colors)
|
| 0x03 |
0x03 |
Button color of controller in RGB Hex (see Joy-Con Colors)
|
| 0x06 |
0x03 |
Left grip color of controller in RGB Hex
|
| 0x09 |
0x03 |
Right grip color of controller in RGB Hex
|
DesignVariation
| Value
|
Name
|
| 0x00 |
LuciaJ, LagerJ
|
| 0x01 |
LuciaE, LagerE
|
| 0x02 |
LuciaU, LagerU
|
Model1
| Offset
|
Size
|
Description
|
| 0x00 |
0x06 |
SensorData
|
| 0x06 |
0x12 |
AnalogStickModuleParam
|
Model2
| Offset
|
Size
|
Description
|
| 0x00 |
0x12 |
AnalogStickModuleParam
|
User Calibration Sector
| Offset
|
Endianness
|
Size
|
Description
|
| 0x10 |
B |
0x18 |
UserCal1
|
| 0x28 |
B |
0x18 |
UserCal2
|
UserCal1
| Offset
|
Size
|
Description
|
| 0x00 |
0x02 |
UserCalMagicNumber
|
| 0x02 |
0x09 |
LeftAnalogStickCalibrationValue
|
| 0x0B |
0x02 |
UserCalMagicNumber
|
| 0x0D |
0x09 |
RightAnalogStickCalibrationValue
|
| 0x16 |
0x02 |
UserCalMagicNumber
|
UserCal2
| 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.
| Offset
|
Endianness
|
Size
|
Description
|
| 0x00 |
L |
0x01 |
Record type (see Record Types)
|
| 0x01 |
L |
0x02 |
Size of data (size)
|
| 0x03 |
Mixed |
(size) |
Data
|
Record Types
Record 0x08
| 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
| Offset
|
Endianness
|
Size
|
Description
|
Note
|
| 0x00 |
L |
0x04 |
Address |
-
|
| 0x04 |
B |
(Note) |
Data |
To calculate the size do: chunk_datasize (See Firmware Chunks)-4
|
Record 0x0B
| Offset
|
Endianness
|
Size
|
Description
|
| 0x00 |
L |
0x04 |
Address
|
Memory Regions
| Offsets
|
Description
|
| 0x00-0xC8000 |
ROM 1
|
| 0x260000-0x26C000 |
ROM 2
|
| 0xD0000-0x0x0DFFFF |
RAM Low
|
| 0x200000-0x247FFF |
RAM High
|