I2C Registers: Difference between revisions
Added free RAM and fixed spelling mistake |
finally correct this awful misinformation. also make the formatting slightly better |
||
| (45 intermediate revisions by 5 users not shown) | |||
| Line 105: | Line 105: | ||
| 7 | | 7 | ||
| Start/busy (0=Ready, 1=Start/busy) | | Start/busy (0=Ready, 1=Start/busy) | ||
|} | |||
== I2C_CNTEX == | |||
{| class="wikitable" border="1" | |||
! BIT | |||
! DESCRIPTION | |||
|- | |||
| 0-1 | |||
| ? Set to 2 normally. | |||
|} | |||
== I2C_SCL == | |||
{| class="wikitable" border="1" | |||
! BIT | |||
! DESCRIPTION | |||
|- | |||
| 0-5 | |||
| ? | |||
|- | |||
| 8-12 | |||
| ? Set to 5 normally. | |||
|} | |} | ||
| Line 173: | Line 194: | ||
| 0xa6 | | 0xa6 | ||
| "i2c::HID" | | "i2c::HID" | ||
| | | Gyroscope. The device table in I2C-module had the device address changed from 0xA6 to 0xD6 with [[8.0.0-18]]. | ||
|- | |- | ||
| 10 | | 10 | ||
| Line 179: | Line 200: | ||
| 0xd0 | | 0xd0 | ||
| "i2c::HID" | | "i2c::HID" | ||
| Gyroscope | | Gyroscope (old3DS) | ||
|- | |- | ||
| 11 | | 11 | ||
| Line 185: | Line 206: | ||
| 0xd2 | | 0xd2 | ||
| "i2c::HID" | | "i2c::HID" | ||
| | | Gyroscope (2DS, new3DSXL, new2DSXL) | ||
|- | |- | ||
| 12 | | 12 | ||
| Line 191: | Line 212: | ||
| 0xa4 | | 0xa4 | ||
| "i2c::HID" | | "i2c::HID" | ||
| DebugPad | | DebugPad (slightly modified [https://wiibrew.org/wiki/Wiimote/Extension_Controllers/Classic_Controller_Pro Wii Classic Controller Pro]) | ||
|- | |- | ||
| 13 | | 13 | ||
| Line 203: | Line 224: | ||
| 0xa0 | | 0xa0 | ||
| "i2c::EEP" | | "i2c::EEP" | ||
| | | HWCAL EEPROM ([[Hardware_calibration#Header|only present on dev units where SHA256 is used for HWCAL verification]]) | ||
|- | |- | ||
| 15 | | 15 | ||
| Line 234: | Line 255: | ||
s* = shared register (explaination below this table) | s* = shared register (explaination below this table) | ||
ds = dynamic shared (explaination below this table) | ds = dynamic shared (explaination below this table) | ||
Reading or writing multiple bytes from/to single-byte registers increments the register ID along with it. For example reading two bytes from reg 0x00 reads regs 0x00 and 0x01. | |||
This is not the case for multibyte regs (0x29, 0x2D, 0x4F, 0x61 and 0x7F), plus reg 0x60. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! REGISTER | ! REGISTER | ||
| Line 254: | Line 279: | ||
| d | | d | ||
| rw | | rw | ||
| | | For bit0 and 1 values, writing will mask away/"acknowledge" the event, set to 3 by mcuMainLoop on reset if reset source is Watchdog | ||
bit0: RTC clock value got reset to defaults | bit0: RTC clock value got reset to defaults | ||
bit1: Watchdog reset happened | bit1: Watchdog reset happened | ||
bit5: TWL MCU reg: volume mode (0: 8-step, 1: 32-step) | |||
bit6: TWL MCU reg: NTR (0) vs TWL mode (1) | |||
bit7: TWL MCU reg: Uses NAND | |||
|- | |- | ||
| 0x03 | | 0x03 | ||
| ds | | ds | ||
| rw | | rw | ||
| Top screen | | Top screen Vcom | ||
|- | |- | ||
| 0x04 | | 0x04 | ||
| ds | | ds | ||
| rw | | rw | ||
| Bottom screen | | Bottom screen Vcom | ||
|- | |- | ||
| 0x05 | | 0x05 | ||
| Line 288: | Line 316: | ||
| s | | s | ||
| ro | | ro | ||
| | | Battery temperature (in Celcius?) | ||
|- | |- | ||
| 0x0B | | 0x0B | ||
| Line 298: | Line 326: | ||
| s | | s | ||
| ro | | ro | ||
| | | Battery percentage, fractional part (seems to have a resolution of around 0.1% according to tests) | ||
|- | |- | ||
| 0x0D | | 0x0D | ||
| Line 313: | Line 341: | ||
| s | | s | ||
| ro | | ro | ||
| Flags: bit7-5 are read via [[MCU_Services|mcu::GPU]]. The rest of | | Flags: bit7-5 are read via [[MCU_Services|mcu::GPU]]. The rest of them are read via [[MCU_Services|mcu::RTC]]. | ||
bit1: ShellState | |||
bit3: AdapterState | |||
bit4: BatteryChargeState | |||
bit5: Bottom screen backlight on | |||
bit6: Top screen backlight on | |||
bit7: LCD panel voltage on | |||
|- | |- | ||
| 0x10 | | 0x10 | ||
| Line 330: | Line 364: | ||
- 0x17 | - 0x17 | ||
| s | | s | ||
| rw | | rw | ||
| Unused and unreferenced free RAM! Good for userdata. | | Unused and unreferenced free RAM! Good for userdata. | ||
|- | |- | ||
| Line 338: | Line 372: | ||
| rw | | rw | ||
| Interrupt mask for register 0x10 (0=enabled,1=disabled) | | Interrupt mask for register 0x10 (0=enabled,1=disabled) | ||
bit00: Power button press | bit00: Power button press (for 27 "ticks") | ||
bit01: Power button held (the 3DS turns off regardless after a fixed time) | bit01: Power button held (for 375 "ticks"; the 3DS turns off regardless after a fixed time) | ||
bit02: HOME button press | bit02: HOME button press (for 5 "ticks") | ||
bit03: HOME button release | bit03: HOME button release | ||
bit04: WiFi switch button | bit04: WiFi switch button | ||
bit05: Shell close | bit05: Shell close | ||
bit06: Shell open | bit06: Shell open | ||
bit07: Fatal hardware condition([[Services#Notifications|?]]) | bit07: Fatal hardware condition([[Services#Notifications|?]]) (sent when the MCU gets reset by the Watchdog timer) | ||
bit08: Charger removed | bit08: Charger removed | ||
bit09: Charger plugged in | bit09: Charger plugged in | ||
bit10: | bit10: RTC alarm (when some conditions are met it's sent when the current day and month and year matches the current RTC time) | ||
bit11: ??? ( | bit11: ??? (accelerometer related) | ||
bit12: HID update | bit12: HID update | ||
bit13: Battery | bit13: Battery percentage status change (triggered at 10%, 5%, and 0% while discharging) | ||
bit14: ??? | bit14: Battery stopped charging (independent of charger state) | ||
bit15: Battery started charging | |||
Nonmaskable(?) interrupts | |||
bit16: ??? | |||
bit17: ??? (opposite even for bit16) | |||
bit22: Volume slider position change | bit22: Volume slider position change | ||
bit23: ??? Register 0x0E update | |||
bit25: | bit24: GPU off | ||
bit26: | bit25: GPU on | ||
bit27: | bit26: bottom backlight off | ||
bit28: | bit27: bottom backlight on | ||
bit29: | bit28: top backlight off | ||
bit30: | bit29: top backlight on | ||
bit31: | bit30: bit set by mcu sysmodule | ||
bit31: bit set by mcu sysmodule | |||
|- | |- | ||
| 0x1C | | 0x1C | ||
- 0x1F | - 0x1F | ||
| s | | s | ||
| rw | | rw | ||
| Unused and unreferenced free RAM! Good for userdata. | | Unused and unreferenced free RAM! Good for userdata. | ||
|- | |- | ||
| Line 375: | Line 413: | ||
| System power control: | | System power control: | ||
bit0: power off | bit0: power off | ||
bit1: reboot (unused?) | bit1: full reboot (unused). Discards things like [[CONFIG9_Registers#CFG9_BOOTENV|CFG9_BOOTENV]] | ||
bit2: reboot ( | - Asserts RESET1 via PMIC command (?) (deasserts nRESET1). This could be the reset that controls some CFG9 registers | ||
bit3: | - Asserts RESET2 (P0.1 = 0, PM0.1 = 0 (output)) (deasserts nRESET2) | ||
bit4: | - Asserts FCRAM_RESET (P3.0 = 0) (deasserts nFCRAM_RESET) | ||
Bit 4 sets a bit at a RAM address which seems to control the watcdog timer state, then this bit is immediately unmasked. This field has a bitmask of 0x0F. | bit2: normal reboot. Preserves [[CONFIG9_Registers#CFG9_BOOTENV|CFG9_BOOTENV]], etc. | ||
- Asserts RESET2 (P0.1 = 0, PM0.1 = 0) | |||
- If in NTR emulation mode (see reg 0x02), asserts FCRAM_RESET (P3.0 = 0) | |||
- Resets TWL MCU i2c registers | |||
bit3: FCRAM reset (present in by LgyBg. Unused because a system reboot does the same thing & a PDN reg also possibly implements this function) | |||
- Asserts FCRAM_RESET (P3.0 = 0) | |||
bit4: signal that sleep mode is about to be entered (used by PTM) | |||
Bit 4 sets a bit at a RAM address which seems to control the watcdog timer state, then this bit is immediately unmasked. This field has a bitmask of 0x0F. | |||
If any of the reset bits is set, the MCU waits for 5ms, then deasserts RESET1 (via PMIC), RESET2 (PM0.1 = 1 (input)) and FCRAM_RESET (P3.0 = 1), and reinitializes some other various registers after a 100ms delay. | |||
|- | |- | ||
| 0x21 | | 0x21 | ||
| d | | d | ||
| wo | | wo | ||
| | | Used in legacy mode to signal events for TWL MCU "emulation" (written to REG[0x5D])? Software then asserts the TWL MCU IRQ pin via [[#LGY_GPIOEMU_MASK|Legacy I/O registers]]. | ||
bit0: Signal TWL POWER button click | |||
bit1: Signal TWL reset | |||
bit2: Signal TWL power off | |||
bit3: Signal TWL battery low | |||
bit4: Signal TWL battery empty | |||
bit5: Signal TWL volume button click | |||
|- | |- | ||
| 0x22 | | 0x22 | ||
| d | | d | ||
| wo | | wo | ||
| Used to | | Used to turn on or turn off LCD-related boost circuits. Bits 5:2 can be read back so see whether backlight setting is in progress or not, however bits 1:0 get cleared as soon as the request gets acknowledged. | ||
bit0: | bit0: LCD panel voltage off | ||
bit1: | bit1: LCD panel voltage on | ||
bit2: | bit2: Bottom screen backlight off | ||
bit3: | bit3: Bottom screen backlight on | ||
bit4: | bit4: Top screen backlight off | ||
bit5: | bit5: Top screen backlight on | ||
Bits 4 and 5 have no effect on a 2DS because the backlight source is the bottom screen. | Bits 4 and 5 have no effect on a 2DS because the backlight source is the bottom screen. | ||
| Line 401: | Line 454: | ||
|- | |- | ||
| 0x23 | | 0x23 | ||
| | | d | ||
| wo | | wo | ||
| ? | | Writing 0x72 ('r') resets the MCU, but this is stubbed on retail? | ||
|- | |- | ||
| 0x24 | | 0x24 | ||
| Line 433: | Line 486: | ||
| sd(5) | | sd(5) | ||
| rw | | rw | ||
| Power LED | | Power mode indicator state (read-write) | ||
1 = forced default blue | |||
2 = sleep mode animation | |||
3 = "power off" mode | |||
4 = disable blue power LED and turn on red power LED | |||
5 = disable red power LED and turn on blue power LED | |||
6 = animate blue power LED off and flash red power LED | |||
anything else = automatic mode | |||
The other 4 bytes (32bits) affect the pattern of the red power LED (write only) | |||
|- | |- | ||
| 0x2A | | 0x2A | ||
| Line 447: | Line 508: | ||
1 = slowly blinking | 1 = slowly blinking | ||
2 = constantly on | 2 = constantly on | ||
3 = "TWL" mode | |||
4 = flash once | 4 = flash once | ||
5 = delay before changing to 2 | 5 = delay before changing to 2 | ||
| Line 471: | Line 533: | ||
|- | |- | ||
| 0x30 | | 0x30 | ||
- | - 0x36 | ||
| | | ds | ||
| rw | | rw | ||
| RTC time (system clock). 7 bytes are read from this. The upper nibble of each byte encodes 10s (BCD), so each byte is post-processed with (byte & 0xF) + (10 * (byte >> 4)). | | RTC time (system clock). 7 bytes are read from this. The upper nibble of each byte encodes 10s (BCD), so each byte is post-processed with (byte & 0xF) + (10 * (byte >> 4)). | ||
| Line 482: | Line 544: | ||
byte 5: months | byte 5: months | ||
byte 6: years | byte 6: years | ||
|- | |||
| 0x37 | |||
| s | |||
| rw | |||
| RTC time byte 7: leap year counter / "watch error correction" register (unused in code) | |||
|- | |- | ||
| 0x38 | | 0x38 | ||
- | - 0x3C | ||
| s | | s | ||
| rw | | rw | ||
| Line 491: | Line 557: | ||
byte 0: minutes | byte 0: minutes | ||
byte 1: hours | byte 1: hours | ||
byte 2: | byte 2: day | ||
byte 3: month | |||
byte 4: year | |||
|- | |- | ||
| 0x3B | | 0x3B | ||
| s | | s | ||
| rw | | rw | ||
| | | Could be used on extremely old MCU_FIRM versions to upload [[MCU_Services#MCU_firmware_versions|MCU firmware]] if reg 0xF == 0 and reg 0x10 == 1 (presumably major and minor version fields for mcufw 0.1 which largely predates factory firm). | ||
|- | |- | ||
| 0x3D | | 0x3D | ||
0x3E | 0x3E | ||
| | | ds | ||
| ro | | ro | ||
| RTC tick counter / "ITMC" (when resets to 0 the seconds increase) | | RTC tick counter / "ITMC" (when resets to 0 the seconds increase) | ||
| Line 511: | Line 574: | ||
|- | |- | ||
| 0x3F | | 0x3F | ||
| | | d | ||
| wo | | wo | ||
| 2 bits | | 2 bits | ||
bit0: | bit0: Asserts RESET1 (P0.0 = 0, PM0.0 = 0 (output)) but does NOT deassert it (wtf?). This seems to kill the entire SoC: is it because it doesn't deassert it, or does it not deassert it because the SoC hangs anyway? This is the pin that controls some security-critical regs like CFG9_BOOTENV! | ||
bit1: turns on a prohibited bit in an RTC Control register and turns P12 into an output | bit1: turns on a prohibited bit in an RTC Control register and turns P12 into an output | ||
|- | |- | ||
| Line 520: | Line 583: | ||
| s | | s | ||
| rw | | rw | ||
| | | Tilt sensor sampling mode. Bits 0 and 1 control the mode. If bits 0 or 1 are set then the tilt sensor is enabled and sampled. | ||
|- | |- | ||
| 0x41 | | 0x41 | ||
| Line 540: | Line 603: | ||
| s | | s | ||
| rw | | rw | ||
| ???, | | ???, pedoometer related(?) | ||
|- | |- | ||
| 0x45 | | 0x45 | ||
| Line 546: | Line 609: | ||
| s | | s | ||
| ro | | ro | ||
| | | Tilt sensor 3D rotation from the 12bit ADC, left shifted 4 to fit in a 16bit signed short, relative to the 3DS bottom screen | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! AXIS | ! AXIS | ||
| Line 553: | Line 616: | ||
! V=0xC0 | ! V=0xC0 | ||
|- | |- | ||
| | | X (left/right) | ||
| held vertically | | held up vertically | ||
| | | rotated left 90° like a steering wheel | ||
| | | rotated right 90° like a steering wheel | ||
|- | |- | ||
| Z? | | Y (forwards/backwards) | ||
| laid flat on the desk with the screen facing up | |||
| held up vertically | |||
| held up vertically with screen facing upside-down | |||
|- | |||
| Z (???) | |||
| ??? | | ??? | ||
| ??? | | ??? | ||
| ??? | | ??? | ||
| Line 620: | Line 683: | ||
| 0x5A | | 0x5A | ||
| s | | s | ||
| rw | | ro/rw | ||
| | | Invalid, do not use! On newer MCU_FIRM versions this is unused, but on older MCU_FIRM versions this is a read-only counter. | ||
|- | |- | ||
| 0x5B | | 0x5B | ||
| Line 630: | Line 693: | ||
|- | |- | ||
| 0x60 | | 0x60 | ||
| | | d | ||
| | | rw | ||
| Free register bank address (index) select | |||
| | Selects the index to read from in the free register bank, up to 200. Used in conjunction with reg 0x61. | ||
byte 0: bit0 = "WirelessDisabled", bit1 = "SoftwareClosed", bit2 = "PowerOffInitiated", bit3 = "LgyNativeResolution", bit4 = "LegacyJumpProhibited" | |||
byte 1: Legacy LCD data | |||
bytes 2 and 3: Local Friend Code counter | |||
bytes 4 and 5: UUID clock sequence | |||
bytes 6 and 7: Unused | |||
bytes 8 to 175: Playtime data for legacy titles | |||
bytes 176 to 188: Playtime data | |||
bytes 188 to 199: Unused | |||
|- | |- | ||
| 0x61 | | 0x61 | ||
| | | d(200) | ||
| rw | | rw | ||
| | | Free register bank, data is read from/written to here. | ||
Accessing N bytes of this register increments the selected index by N. | |||
|- | |- | ||
| 0x62 - 0x7E | | 0x62 - 0x7E | ||
| Line 649: | Line 720: | ||
|- | |- | ||
| 0x7F | | 0x7F | ||
| d(0x13) | | d(9-0x13) | ||
| ro | | ro | ||
| Various system state information | | Various system state information (debug pointer table) | ||
byte 0x00: Console type, see [[Configuration_Memory#MCU_HW_INFO|here]] | |||
byte 0x01: PMIC vendor code | |||
byte 0x02: Battery vendor code | |||
byte 0x03: MGIC version (major?) | |||
byte 0x04: MGIC version (minor?) | |||
byte 0x05: RCOMP(?) | |||
byte 0x06: battery related? (seems to decrease while charging and increase while discharging) | byte 0x06: battery related? (seems to decrease while charging and increase while discharging) | ||
byte 0x09: system model (see [[Cfg:GetSystemModel#System_Model_Values|Cfg:GetSystemModel]] for values) | byte 0x09: system model (see [[Cfg:GetSystemModel#System_Model_Values|Cfg:GetSystemModel]] for values) | ||
byte 0x0A: | byte 0x0A: Red Power LED mode (0 = off, 1 = on) | ||
byte 0x0B: Blue Power LED intensity (0x00 - 0xFF) | |||
byte 0x0D: RGB LED red intensity | byte 0x0D: RGB LED red intensity | ||
byte 0x0E: RGB LED green intensity | byte 0x0E: RGB LED green intensity | ||
| Line 660: | Line 738: | ||
byte 0x11: WiFi LED brightness | byte 0x11: WiFi LED brightness | ||
byte 0x12: raw button states? | byte 0x12: raw button states? | ||
bit0: unset while | bit0: unset while Power button is held | ||
bit1: unset while | bit1: unset while HOME button is held | ||
bit2: unset while | bit2: unset while WiFi slider is held | ||
bit5: unset while the charging LED is active | bit5: unset while the charging LED is active | ||
bit6: unset while charger is plugged in | bit6: unset while charger is plugged in | ||
On MCU_FIRM major version 1 the size of this is 9, reading past the 9th byte will yield AA instead of FF. | |||
|- | |- | ||
| 0x80 | | 0x80 | ||
| Line 680: | Line 758: | ||
Non-shared (dynamic) register: it's a register whose contents separate from the shared register pool. Messing with these registers will not affect the shared register pool at all. | Non-shared (dynamic) register: it's a register whose contents separate from the shared register pool. Messing with these registers will not affect the shared register pool at all. | ||
On old versions of MCU_FIRM none of the invalid registers are masked away by the read handler function, but are still read-only. Newer MCU_FIRM versions return the hardcoded value FF instead. | |||
== Device 5 & 6 == | == Device 5 & 6 == | ||
These are the chip-on-glass display controllers, also known as I2CLCD. | |||
=== Shared registers === | |||
These registers are the same across all known I2CLCD controllers (except Controller ID 0x00). | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Register | ! Register | ||
! Name | ! Name | ||
! Valid bits | |||
! Description | ! Description | ||
|- | |- | ||
| | | 0x01 | ||
| | | Display enable | ||
| ? | | 0x11 | ||
| Values: | |||
- 0x00 - screen off, slow burn-in | |||
- 0x01 - screen off, fast burn-in | |||
- 0x10 - screen on, color input used | |||
- 0x11 - screen on, color input not used, High-Z (display turns black or white depending on interface config) | |||
|- | |||
| 0x40 | |||
| Read address | |||
| | |||
| Write to this register to set the read address. | |||
Reading from I2CLCD is non-standard. When you read, it returns pairs of the currently read address, and then the data byte at that address. The read address auto-increments. | |||
|- | |||
| 0x54 | |||
| Checksum? trigger | |||
| 0x01 | |||
| When transitioning bit0 from 0 to 1, it seems to trigger some sort of checksum calcuation. Broken on controller 0x01, where it's oneshot. | |||
|- | |||
| 0x55 | |||
| ??? | |||
| 0x03 (all) / | |||
0x07 (2DS) | |||
| Unknown. When toggling 0x54 bit0 from 0 to 1, this register gets changed to 0x01 (all) / 0x05 (2DS). | |||
This register is sometimes seen with a value of 0x02 at initialization time on the top screen. | |||
|- | |||
| 0x56 | |||
| Checksum? | |||
| | |||
| Unknown. Read-writable with no effect (old3DS) / read-only (all). | |||
A random value is written here when 0x54 bit0 is changed from 0 to 1. Constantly updates with a seemingly random value, except on Controller ID 0x01, where it's oneshot/bugged. | |||
|- | |||
| 0x60 | |||
| ??? | |||
| 0x01 | |||
| Unknown. 0x00 is written here during init. Seems to have no effect. | |||
|- | |||
| 0x61 | |||
| Register checksum | |||
| | |||
| Some - but not all - register values are combined using an unknown algorithm into this register. | |||
It's unknown which registers influence this value, as some registers which influence this value are read-only. | |||
|- | |||
| 0x62 | |||
| ??? | |||
| 0x01 | |||
| Unknown, does nothing on known controllers. During init, gsp waits for this to become 0x01. | |||
|- | |||
| 0xFE | |||
| ??? | |||
| | |||
| Unknown, does nothing. 0xAA is written here during init. | |||
|- | |||
| 0xFF | |||
| Controller ID | |||
| | | | ||
| Upper 4bits is manufacturer. Lower 4bits is unknown, most likely revision, possibly encoded as a Johnson counter. | |||
Known IDs: | |||
- 0xC7 - new3DS, new3DSXL, new2DSXL, and some select newer old3DSXL | |||
- 0xC3 - older old3DSXL | |||
- 0xE1 - 2DS | |||
- 0x10 - some select new3DS and new3DSXL with IPS screens | |||
- 0x01 - old3DS | |||
- 0x00 - unknown, gsp compares for this exact Controller ID for an alternate initialization path | |||
Manufacturers: | |||
- 0xC - SHARP (TN) | |||
- 0x1 - JDI (LTPS IPS), found in select new3DS and new3DSXL consoles | |||
- 0xE - unknown, found in 2DS only | |||
- 0x0 - unknown, found in old3DS (non-XL) only | |||
|} | |||
=== Custom registers for controller 0x00 === | |||
This Controller ID is fully unknown, and the only reason we know about its existance is due to gsp having special handling code for it. | |||
{| class="wikitable" border="1" | |||
! Register | |||
! Name | |||
! Valid bits | |||
! Description | |||
|- | |- | ||
| 0x11 | | 0x11 | ||
| | | ??? | ||
| ? | | | ||
| Unknown. Write 0x10 to initialize. | |||
|- | |||
| 0x50 | |||
| ??? | |||
| | | | ||
| Unknown. Write 0x01 to initialize. | |||
|} | |||
=== Custom registers for controller 0x01 === | |||
{| class="wikitable" border="1" | |||
! Register | |||
! Name | |||
! Valid bits | |||
! Description | |||
|- | |||
| 0x10 | |||
| Interface config | |||
| 0xF7 | |||
| Regonfigures the input pins and pin behavior of the controller. | |||
bit0 - color value invert (D = ~D, or D = 255 - D) | |||
bit1 - color format remap (D7:D2 <-- D5:D0, that is left shift color data by 2) | |||
bit2 - ??? | |||
bit4 - ??? | |||
bit5 - ??? | |||
bit6 - ??? | |||
bit7 - DS-style undriven screen (it will be white instead of black, see shared register 0x01) | |||
|- | |- | ||
| | | 0x11 | ||
| | | Image config | ||
| | | 0x7F | ||
| | | Image filters and pixel clock control. | ||
bit0 - Horizontal Flip (scan from right to left) | |||
bit1 - red-blue swap | |||
bit2 - ??? | |||
bit3 - ??? | |||
bit4 - ??? | |||
bit5 - ??? | |||
bit6 - ??? | |||
|- | |- | ||
| | | 0x1D | ||
| | | ??? | ||
| | | 0x0F | ||
| | | Unknown, bit0 enables registers 0x12 to 0x19 to control some analog timing controls to the display panel itself. | ||
|- | |- | ||
| 0x50 | | 0x50 | ||
| | | ??? | ||
| ? | | 0x11 | ||
| Unknown. Has no effect on bottom screen. On the top screen, bit4 blanks out the display (LVDS disable?). | |||
|- | |||
| 0x53 | |||
| ??? | |||
| 0x73 | |||
| Unknown. While other bits seem to have no effect, bit0 kills the controller until a power cycle. | |||
|} | |||
=== Custom registers for controller 0xC3 === | |||
Basically the same as Controller ID 0xC7. | |||
=== Custom registers for controller 0xC7 === | |||
This is the most common non-old3DS display controller. Quite overclockable. | |||
Note: on the 0xC7 controller unlocking the factory controls at register 0x03 glitches out most of the standard controls (like registers 0x50 to 0x56), so use with caution. | |||
{| class="wikitable" border="1" | |||
! Register | |||
! Name | |||
! Valid bits | |||
! Description | |||
|- | |||
| 0x03 | |||
| Factory key 2 | |||
| | |||
| Write 0xAA here to unlock a second set of factory controls. | |||
|- | |||
| 0xAF | |||
| Factory key | |||
| | |||
| Write 0xAA here to unlock factory controls. | |||
|} | |||
Factory mode registers for unlock register 0x03: | |||
{| class="wikitable" border="1" | |||
! Register | |||
! Name | |||
! Valid bits | |||
! Description | |||
|- | |||
| 0x10 | |||
| Image control? | |||
| 0xD7 | |||
| Most bits are unknown. | |||
bit0 - color invert | |||
bit1 - slight gamma increase | |||
|- | |||
| 0x11 | |||
| Image transform? | |||
| 0x7F | |||
| Mostly unknown. | |||
bit0 - Invert horizontal scan direction (0 = left to right, 1 = right to left) | |||
bit1 - red-blue swap | |||
bit2 - Invert vertical scan direction (0 = top to bottom, 1 = bottom to top) | |||
bit3 - Invert the order of each scanline pair (might be needed if bit2 is toggled) | |||
bit4 - Enable interlaced signal (use bit3 to swap fields) | |||
bit5 - ??? | |||
bit6 - ??? | |||
|- | |||
| 0x70-0x83 | |||
| Color curve red | |||
| rowspan=3 | | |||
| rowspan=3 | These registers are used for fine-tuning the analog driving curve of the screen | |||
Positive: | |||
- byte 00 (0xFF) - ??? | |||
- byte 01 (0xFF) - ??? | |||
- byte 02 (0x3F) - ??? | |||
- byte 03 (0x3F) - ??? | |||
- byte 04 (0x3F) - ??? | |||
- byte 05 (0x3F) - ??? | |||
- byte 06 (0x3F) - ??? | |||
- byte 07 (0x3F) - ??? | |||
- byte 08 (0x3F) - ??? | |||
- byte 09 (0x3F) - ??? | |||
Negative: | |||
- byte 10 (0xFF) - ??? | |||
- byte 11 (0xFF) - ??? | |||
- byte 12 (0x3F) - ??? | |||
- byte 13 (0x3F) - ??? | |||
- byte 14 (0x3F) - ??? | |||
- byte 15 (0x3F) - ??? | |||
- byte 16 (0x3F) - ??? | |||
- byte 17 (0x3F) - ??? | |||
- byte 18 (0x3F) - ??? | |||
- byte 19 (0x3F) - ??? | |||
|- | |||
| 0x84-0x97 | |||
| Color curve green | |||
|- | |||
| 0x98-0xAB | |||
| Color curve blue | |||
|} | |||
=== Custom registers for controller 0xE1 === | |||
This controller is designed to drive a split panel. As such, the factory controls have been slightly altered to accomodate this. | |||
This is the only I2CLCD which responds on both I2CLCD addresses. The dominant screen is the bottom one. | |||
Most registers are similar to controller 0xC7, but there are some differences due to the split shared panel nature. | |||
{| class="wikitable" border="1" | |||
! Register | |||
! Name | |||
! Valid bits | |||
! Description | |||
|- | |||
| 0x03 | |||
| Factory key 2 | |||
| | |||
| Write 0xAA here to unlock a 2nd set of factory controls. | |||
|- | |||
| 0xAF | |||
| Factory key | |||
| | |||
| Write 0xAA here to unlock factory controls. | |||
|} | |||
Factory mode registers for unlock register 0x03: | |||
{| class="wikitable" border="1" | |||
! Register | |||
! Name | |||
! Valid bits | |||
! Description | |||
|- | |||
| 0x10 | |||
| Image control? | |||
| 0xD7 | |||
| Most bits are unknown. This applies to the whole display panel. | |||
bit0 - color invert | |||
bit1 - slight gamma increase | |||
|- | |||
| 0x11 | |||
| Image transform | |||
| 0x33 | |||
| | |||
bit0 - top half horizontal flip | |||
bit1 - top half red-blue swap | |||
bit4 - bottom half horizontal flip | |||
bit5 - bottom half red-blue swap | |||
|- | |||
| 0x70-0x83 | |||
| Analog curve top | |||
| rowspan=2 | | |||
| rowspan=2 | Consists of two unknown curve values. Seems to be nonstandard. | |||
Pair 1: | |||
byte 00 (0xFF) - ??? | |||
byte 01 (0xFF) - ??? | |||
byte 02 (0xFF) - ??? | |||
byte 03 (0xFF) - ??? | |||
byte 04 (0x3F) - ??? | |||
byte 05 (0x3F) - ??? | |||
byte 06 (0x3F) - ??? | |||
byte 07 (0x3F) - ??? | |||
byte 08 (0x3F) - ??? | |||
byte 09 (0x3F) - ??? | |||
Part 2: | |||
byte 10 (0xFF) - ??? | |||
byte 11 (0xFF) - ??? | |||
byte 12 (0xFF) - ??? | |||
byte 13 (0xFF) - ??? | |||
byte 14 (0x3F) - ??? | |||
byte 15 (0x3F) - ??? | |||
byte 16 (0x3F) - ??? | |||
byte 17 (0x3F) - ??? | |||
byte 18 (0x3F) - ??? | |||
byte 19 (0x3F) - ??? | |||
|- | |||
| 0x84-0x97 | |||
| Analog curve bottom | |||
|} | |||
=== Custom registers for controller 0x10 === | |||
JDI IPS controller. | |||
Warning: on the JDI controller, unlocking any of the factory mode registers overshadows some other registers, so don't write to "standard" locations (other than register 0x40) before locking factory mode back! | |||
{| class="wikitable" border="1" | |||
! Register | |||
! Name | |||
! Valid bits | |||
! Description | |||
|- | |||
| 0x03 | |||
| Factory key 2 | |||
| | |||
| Write 0xAA here to unlock advanced IPS curve controls. | |||
|- | |||
| 0xAF | |||
| Factory key | |||
| | |||
| Write 0xAA here to unlock factory controls. | |||
|} | |||
Factory mode registers unlocked by register 0xAF: | |||
* 0x41 - 0x4F | |||
* 0x58 - 0x5F | |||
* 0x67 - 0x6F | |||
* 0xD0 - 0xEF | |||
* unknown... | |||
Factory mode registers unlocked by register 0x03: | |||
* 0x04 - 0x0F | |||
* unknown... | |||
{| class="wikitable" border="1" | |||
! Register | |||
! Name | |||
! Valid bits | |||
! Description | |||
|- | |||
| 0x70-0x7F | |||
| Driving curve 1-1 | |||
| | |||
| | |||
|- | |||
| 0x80-0x8F | |||
| Driving curve 1-2 | |||
| | |||
| | |||
|- | |||
| 0x90-0x9F | |||
| Driving curve 2-1 | |||
| | |||
| | |||
|- | |||
| 0xA0-0xAF | |||
| Driving curve 2-2 | |||
| | |||
| | | | ||
|- | |- | ||
| | | 0xB0-0xBF | ||
| | | Driving curve 3-1 | ||
| | | | ||
| | | | ||
|- | |- | ||
| | | 0xC0-0xCF | ||
| | | Driving curve 3-2 | ||
| | | | ||
| | | | ||
|} | |} | ||
== Device 10 == | == Device 10 == | ||
See the datasheet linked to on the [[Hardware]] page for reference. | |||
== Device 11 == | |||
See the datasheet linked to on the [[Hardware]] page for reference. | See the datasheet linked to on the [[Hardware]] page for reference. | ||
| Line 740: | Line 1,179: | ||
|} | |} | ||
This is | This is a [https://wiibrew.org/wiki/Wiimote/Extension_Controllers/Classic_Controller_Pro Wii Classic Controller Pro] which was slightly modified to have an encrypted device type of 0xF0 [https://wiibrew.org/wiki/Wiimote/Extension_Controllers#The_New_Way instead of 0xFD]. | ||
See [[HID_Shared_Memory#Offset_0x238|here]] for the HID shared memory report format. | |||
== Device 13 == | == Device 13 == | ||