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 |
0x19 |
Cal2
|
0x50 |
B |
0x0D |
DesignInfo
|
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)
|
DesignInfo
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
|
User Calibration Sector
Offset
|
Endianness
|
Size
|
Description
|
0x10 |
B |
0x0B |
LeftAnalogStickUserCal
|
0x1B |
B |
0x0B |
RightAnalogStickUserCal
|
0x26 |
B |
0x1A |
SixAxisSensorUserCal
|
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
|