Line 194: |
Line 194: |
| | 0xa6 | | | 0xa6 |
| | "i2c::HID" | | | "i2c::HID" |
− | | Debug(?) gyroscope. The device table in I2C-module had the device address changed from 0xA6 to 0xD6 with [[8.0.0-18]]. | + | | Gyroscope. The device table in I2C-module had the device address changed from 0xA6 to 0xD6 with [[8.0.0-18]]. |
| |- | | |- |
| | 10 | | | 10 |
Line 212: |
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 255: |
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 274: |
Line 279: |
| | d | | | d |
| | rw | | | rw |
− | | 2bit value, writing will mask away/"acknowledge" the event, set to 3 by mcuMainLoop on reset if reset source is Watchdog | + | | 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 |
Line 308: |
Line 316: |
| | s | | | s |
| | ro | | | ro |
− | | ? (seems to be power management related?) | + | | Battery temperature (in Celcius?) |
| |- | | |- |
| | 0x0B | | | 0x0B |
Line 318: |
Line 326: |
| | s | | | s |
| | ro | | | ro |
− | | ? (changes to 0 for a second when the charger is plugged in then it resets to its previous value) | + | | Battery percentage, fractional part (seems to have a resolution of around 0.1% according to tests) |
| |- | | |- |
| | 0x0D | | | 0x0D |
Line 334: |
Line 342: |
| | ro | | | ro |
| | Flags: bit7-5 are read via [[MCU_Services|mcu::GPU]]. The rest of them are read via [[MCU_Services|mcu::RTC]]. | | | Flags: bit7-5 are read via [[MCU_Services|mcu::GPU]]. The rest of them are read via [[MCU_Services|mcu::RTC]]. |
− | bit01: ShellState | + | bit1: ShellState |
− | bit03: AdapterState | + | bit3: AdapterState |
− | bit04: BatteryChargeState | + | bit4: BatteryChargeState |
− | bit05: Bottom screen backlight on | + | bit5: Bottom screen backlight on |
− | bit06: Top screen backlight on | + | bit6: Top screen backlight on |
− | bit07: GPU on(?) | + | bit7: LCD panel voltage on |
| |- | | |- |
| | 0x10 | | | 0x10 |
Line 375: |
Line 383: |
| bit09: Charger plugged in | | bit09: Charger plugged in |
| bit10: RTC alarm (when some conditions are met it's sent when the current day and month and year matches the current RTC time) | | 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: ??? (accelerometer related) | + | bit11: Accelerometer I2C read/write done [https://github.com/profi200/libn3ds/blob/083c8ffa3f56a49802fa74b6afe45a96820f0439/include/arm11/drivers/mcu_regmap.h#L124] |
| bit12: HID update | | bit12: HID update |
| bit13: Battery percentage status change (triggered at 10%, 5%, and 0% while discharging) | | bit13: Battery percentage status change (triggered at 10%, 5%, and 0% while discharging) |
Line 385: |
Line 393: |
| bit22: Volume slider position change | | bit22: Volume slider position change |
| bit23: ??? Register 0x0E update | | bit23: ??? Register 0x0E update |
− | bit24: ??? (the off event for below bit) | + | bit24: GPU off |
− | bit25: ??? (triggered when something related to the GPU is turned on, most likely backlight) | + | bit25: GPU on |
− | bit26: ??? (???) | + | bit26: bottom backlight off |
− | bit27: ??? (???) | + | bit27: bottom backlight on |
− | bit28: ??? (???) | + | bit28: top backlight off |
− | bit29: ??? backlight on? | + | bit29: top backlight on |
| bit30: bit set by mcu sysmodule | | bit30: bit set by mcu sysmodule |
| bit31: bit set by mcu sysmodule | | bit31: bit set by mcu sysmodule |
Line 405: |
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 (used by mcu sysmodule and LgyBg) | + | - Asserts RESET1 via PMIC command (?) (deasserts nRESET1). This could be the reset that controls some CFG9 registers |
− | bit3: used by LgyBg to power off, causes hangs in 3DS-mode | + | - Asserts RESET2 (P0.1 = 0, PM0.1 = 0 (output)) (deasserts nRESET2) |
− | bit4: used by PTM to signal that sleep mode is about to be entered | + | - 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 |
− | | ??? switches up input bits from <code>0123456--</code> to <code>12-0435-</code> then writes them to REG[0x5D] (<code>0xFFC02</code>) | + | | 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 set LCD states | + | | 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: don't push to LCDs | + | bit0: LCD panel voltage off |
− | bit1: push to LCDs | + | bit1: LCD panel voltage on |
− | bit2: bottom screen backlight off | + | bit2: Bottom screen backlight off |
− | bit3: bottom screen backlight on | + | bit3: Bottom screen backlight on |
− | bit4: top screen backlight off | + | bit4: Top screen backlight off |
− | bit5: top screen backlight on | + | 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 433: |
Line 456: |
| | d | | | d |
| | wo | | | wo |
− | | Writing 0x72 ('r') resets the MCU, writing 0x77 ('w') resets its WDT. Seems to require special conditions, or doesn't work on current units | + | | Writing 0x72 ('r') resets the MCU, but this is stubbed on retail? |
| |- | | |- |
| | 0x24 | | | 0x24 |
Line 462: |
Line 485: |
| | 0x29 | | | 0x29 |
| | sd(5) | | | sd(5) |
− | | ?? | + | | rw |
| | Power mode indicator state (read-write) | | | Power mode indicator state (read-write) |
| 1 = forced default blue | | 1 = forced default blue |
Line 541: |
Line 564: |
| | s | | | s |
| | rw | | | rw |
− | | Could be used on very old MCU_FIRM versions to upload [[MCU_Services#MCU_firmware_versions|MCU firmware]] if some conditions are met. | + | | 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 |
Line 551: |
Line 574: |
| |- | | |- |
| | 0x3F | | | 0x3F |
− | | s | + | | d |
| | wo | | | wo |
| | 2 bits | | | 2 bits |
− | bit0: turns off P00 and sets it to output mode (seems to kill the entire SoC) | + | 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 670: |
Line 693: |
| |- | | |- |
| | 0x60 | | | 0x60 |
− | | ds | + | | d |
| | rw | | | rw |
− | | Free register bank address select | + | | Free register bank address (index) select |
− | Selects the index to read from in the free register bank, up to 200 (?). Used with reg 0x61. | + | Selects the index to read from in the free register bank, up to 200. Used in conjunction with reg 0x61. |
− | | |
− | Reading from this register seem to read N bytes from the bank while incrementing the internal index by the same amount.
| |
| | | |
| byte 0: bit0 = "WirelessDisabled", bit1 = "SoftwareClosed", bit2 = "PowerOffInitiated", bit3 = "LgyNativeResolution", bit4 = "LegacyJumpProhibited" | | byte 0: bit0 = "WirelessDisabled", bit1 = "SoftwareClosed", bit2 = "PowerOffInitiated", bit3 = "LgyNativeResolution", bit4 = "LegacyJumpProhibited" |
Line 687: |
Line 708: |
| |- | | |- |
| | 0x61 | | | 0x61 |
− | | ds(0x100) | + | | d(200) |
| | rw | | | rw |
| | Free register bank, data is read from/written to here. | | | Free register bank, data is read from/written to here. |
| | | |
− | Writing to here seems to increment the internal index?
| + | Accessing N bytes of this register increments the selected index by N. |
| |- | | |- |
| | 0x62 - 0x7E | | | 0x62 - 0x7E |
Line 702: |
Line 723: |
| | ro | | | ro |
| | Various system state information (debug pointer table) | | | 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) |
Line 735: |
Line 762: |
| | | |
| == Device 5 & 6 == | | == Device 5 & 6 == |
− | LCD controllers for main/sub displays, most likely.
| + | 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 |
− | ! Width
| |
| ! Name | | ! Name |
| + | ! Valid bits |
| ! Description | | ! Description |
| |- | | |- |
− | | 0x1 | + | | 0x01 |
− | | 8 | + | | 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. The fields are encoded this way, most likely for the register checksum feature. |
| + | |
| + | Manufacturers: |
| + | - 0x0 - SHARP (LTPS(?) TN), old I2CLCD, found in old3DS (non-XL) only |
| + | - 0x1 - JDI (LTPS IPS), found in select new3DS and new3DSXL consoles |
| + | - 0xC - SHARP (LTPS(?) TN), new I2CLCD |
| + | - 0xE - SHARP (TFT), found in 2DS only |
| + | |
| + | Known IDs: |
| + | - 0xC7 - new3DS, new3DSXL, new2DSXL, and some select newer old3DSXL |
| + | - 0xC3 - older old3DSXL |
| + | - 0xE1 - 2DS |
| + | - LQ050B1LW10B |
| + | - LQ = normal TFT |
| + | - 050 = panel 5 inches diagonal |
| + | - B = "other" display format |
| + | - 1 = transmissive (backlight-compatible) |
| + | - L = LVDS |
| + | - W = *unknown coating type* |
| + | - 10 = model number |
| + | - B = *unknown suffix* |
| + | - 0x10 - some select new3DS and new3DSXL with IPS screens |
| + | - 0x01 - old3DS |
| + | - LS035T7LE38P (top screen) |
| + | - LS = TFT (LTPS or SI-TFT ?) |
| + | - 035 = panel 3.5 inches diagonal |
| + | - T = "other 16:9" (even though the panel is 16:10 in physical size, or 32:10 in terms of pixel count) |
| + | - 7 = *unknown backing type* |
| + | - L = LVDS |
| + | - E = *unknown coating type* |
| + | - 38 = model number |
| + | - P = *unknow suffix* |
| + | - LS030Q7DW48P (bottom screen) |
| + | - LS = TFT (LTPS or SI-TFT ?) |
| + | - 030 = panel 3 inches diagonal |
| + | - Q = QVGA (320x240) |
| + | - 7 = *unknown backing type* |
| + | - D = parallel RGB (unspecified, but it's known to be RGB888 for this display) |
| + | - W = *unknown coating type* |
| + | - 48 = model number |
| + | - P = *unknow suffix* |
| + | - 0x00 - no controller, or dead (I2CLCD always ACKs reads, but returns 00 if dead) |
| + | |} |
| + | |
| + | === 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 |
− | | 8 | + | | ??? |
− | | ?
| |
| | | | | |
| + | | Unknown. Write 0x10 to initialize. |
| |- | | |- |
− | | 0x40 | + | | 0x50 |
− | | 8 | + | | ??? |
− | | CMD_IN/CMD_RESULT1 | + | | |
− | | Write to trigger a command? Seen commands: 0xFF=Reset?, 0x62=IsFinished?. Result is stored in CMD_RESULT1:CMD_RESULT0. | + | | 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 - ??? |
| |- | | |- |
− | | 0x41 | + | | 0x1D |
− | | 8 | + | | ??? |
− | | CMD_RESULT0 | + | | 0x0F |
− | | Read result | + | | Unknown, bit0 enables registers 0x12 to 0x19 to control some analog timing controls to the display panel itself. |
| |- | | |- |
| | 0x50 | | | 0x50 |
− | | 8 | + | | ??? |
− | | ? | + | | 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 |
| + | | |
| | | | | |
| |- | | |- |
− | | 0x60 | + | | 0xB0-0xBF |
− | | 8 | + | | Driving curve 3-1 |
− | | ? | + | | |
| | | | | |
| |- | | |- |
− | | 0xFE | + | | 0xC0-0xCF |
− | | 8 | + | | Driving curve 3-2 |
− | | ? | + | | |
| | | | | |
| |} | | |} |
Line 796: |
Line 1,205: |
| |} | | |} |
| | | |
− | This is the DebugPad device, see [[HID_Shared_Memory|here]]. | + | 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 == |
Line 944: |
Line 1,355: |
| | Firmware image for this chunk, size varies. | | | Firmware image for this chunk, size varies. |
| | This is used during NFC module startup to upload the firmware image to the NFC controller. This is used repeatedly to upload multiple chunks of the image. | | | This is used during NFC module startup to upload the firmware image to the NFC controller. This is used repeatedly to upload multiple chunks of the image. |
| + | |} |
| + | |
| + | == Device 17 == |
| + | |
| + | (Stub) |
| + | |
| + | Used by New 3DS for ZL, ZR, C stick |
| + | |
| + | This device do not use registers. After writing the address, read the next several bytes. |
| + | |
| + | {| class="wikitable" border="1" |
| + | ! Offset |
| + | ! Description |
| + | |- |
| + | | 0x0 |
| + | | Fixed 0x80 |
| + | |- |
| + | | 0x1 |
| + | | Buttons (ZL = 0x4, ZR = 0x2) |
| |} | | |} |