Changes

13,277 bytes added ,  28 April
Stub for Device 17
Line 194: Line 194:  
| 0xa6
 
| 0xa6
 
| "i2c::HID"
 
| "i2c::HID"
| Unknown. 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 200: Line 200:  
| 0xd0
 
| 0xd0
 
| "i2c::HID"
 
| "i2c::HID"
| Gyroscope
+
| Gyroscope (old3DS)
 
|-
 
|-
 
| 11
 
| 11
Line 206: Line 206:  
| 0xd2
 
| 0xd2
 
| "i2c::HID"
 
| "i2c::HID"
| ?
+
| Gyroscope (2DS, new3DSXL, new2DSXL)
 
|-
 
|-
 
| 12
 
| 12
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
 
| ds
 
| ds
 
| rw
 
| rw
| Top screen flicker
+
| Top screen Vcom
 
|-
 
|-
 
| 0x04
 
| 0x04
 
| ds
 
| ds
 
| rw
 
| rw
| Bottom screen flicker
+
| Bottom screen Vcom
 
|-
 
|-
 
| 0x05
 
| 0x05
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 333: Line 341:  
| s
 
| s
 
| ro
 
| ro
| Flags: bit7-5 are read via [[MCU_Services|mcu::GPU]]. The rest of these are read via [[MCU_Services|mcu::RTC]]: bit4 = BatteryChargeState. bit3 = AdapterState. bit1 = ShellState.
+
| 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 369: 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 dead(?)
+
   bit13: Battery percentage status change (triggered at 10%, 5%, and 0% while discharging)
 
   bit14: Battery stopped charging (independent of charger state)
 
   bit14: Battery stopped charging (independent of charger state)
 
   bit15: Battery started charging
 
   bit15: Battery started charging
Line 379: 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)
+
   bit25: GPU on
   bit26: ??? (???)
+
   bit26: bottom backlight off
   bit27: ??? (???)
+
   bit27: bottom backlight on
   bit28: ??? (???)
+
   bit28: top backlight off
   bit29: Battery percentage status change (triggered at 10%, 5%, and 0% while discharging)
+
   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 399: 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: an mcu::RTC command uses this, seems to do something with the watchdog
+
    - 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 425: Line 454:  
|-
 
|-
 
| 0x23
 
| 0x23
| ??
+
| d
 
| wo
 
| wo
| ??? Seems to be stubbed, just returns the written value from the write handler function.
+
| Writing 0x72 ('r') resets the MCU, but this is stubbed on retail?
 
|-
 
|-
 
| 0x24
 
| 0x24
Line 457: Line 486:  
| sd(5)
 
| sd(5)
 
| rw
 
| rw
| Power LED state + some extra data
+
| 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 471: 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 517: Line 555:  
| rw
 
| rw
 
| RTC alarm registers
 
| RTC alarm registers
   byte 0: minutes(???)
+
   byte 0: minutes
   byte 1: hours(???)
+
   byte 1: hours
 
   byte 2: day
 
   byte 2: day
 
   byte 3: month
 
   byte 3: month
Line 526: 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 536: 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 545: Line 583:  
| s
 
| s
 
| rw
 
| rw
| Pedometer state (?)
+
| 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 565: Line 603:  
| s
 
| s
 
| rw
 
| rw
| ???, accelometer related
+
| ???, pedoometer related(?)
 
|-
 
|-
 
| 0x45
 
| 0x45
Line 571: Line 609:  
| s
 
| s
 
| ro
 
| ro
| Gyroscope 3D rotation from the 12bit ADC, left shifted 4 to fit in a 16bit signed short
+
| 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 578: Line 616:  
!  V=0xC0  
 
!  V=0xC0  
 
|-
 
|-
| Y (=roll)
+
| X (left/right)
| held vertically
+
| held up vertically
| vertical right side
+
| rotated left 90° like a steering wheel
| vertical left side
+
| rotated right 90° like a steering wheel
 +
|-
 +
| 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? (=yaw)
+
| Z (???)
| ???
   
| ???
 
| ???
| ???
  −
|-
  −
| X? (=pitch)
  −
| held vertically
   
| ???
 
| ???
 
| ???
 
| ???
Line 655: Line 693:  
|-
 
|-
 
| 0x60
 
| 0x60
| ds
+
| d
 
| rw
 
| rw
| Looping queue register
+
| Free register bank address (index) select
Writing to first byte resets the queue position to the nth element
+
Selects the index to read from in the free register bank, up to 200. Used in conjunction with reg 0x61.
Reading from this register causes the values to shift up by `readsize-1`(needs confirmation) bytes after returning `readsize-1` bytes from the top of the stack (first byte is read-only, so is always zero)
+
 
 +
  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
| ds(0x100)
+
| d(200)
 
| rw
 
| rw
| Writing to this register pushes values on top of register 0x60's stack. Reading from this register doesn't advance the stack.
+
| Free register bank, data is read from/written to here.
The first byte is used to store flags for managing FIRM/NS state - bit0 = "WirelessDisabled", bit1 = "SoftwareClosed", bit2 = "PowerOffInitiated", bit4 = "LegacyJumpProhibited". This register survives a power-off, but it resides in RAM, so its contents get lost on battery pulls. This register doesn't seem to actually control MCU behaviour by itself, it just seems to be used for storing arbitrary data.
+
 
 +
Accessing N bytes of this register increments the selected index by N.
 
|-
 
|-
 
| 0x62 - 0x7E
 
| 0x62 - 0x7E
Line 675: Line 722:  
| d(9-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: power LED related? 0 is off, 1 is red
+
   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 684: 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 power button is held
+
     bit0: unset while Power button is held
     bit1: unset while home button is held
+
     bit1: unset while HOME button is held
     bit2: unset while Wifi slider is held
+
     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
   
  −
    this byte is reset to 0 before an svcBreak takes effect
      
On MCU_FIRM major version 1 the size of this is 9, reading past the 9th byte will yield AA instead of FF.
 
On MCU_FIRM major version 1 the size of this is 9, reading past the 9th byte will yield AA instead of FF.
Line 710: 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.
 +
|-
 +
| 0x50
 +
| ???
 
|  
 
|  
 +
| Unknown. Write 0x01 to initialize.
 +
|}
 +
 +
 +
=== Custom registers for controller 0x01 ===
 +
 +
{| class="wikitable" border="1"
 +
!  Register
 +
!  Name
 +
!  Valid bits
 +
!  Description
 
|-
 
|-
| 0x40
+
| 0x10
| 8
+
| Interface config
| CMD_IN/CMD_RESULT1
+
| 0xF7
| Write to trigger a command? Seen commands: 0xFF=Reset?, 0x62=IsFinished?. Result is stored in CMD_RESULT1:CMD_RESULT0.
+
| 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
| ?
+
|  
 
|  
 
|  
 
|}
 
|}
    
== 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 768: 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 916: 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)
 
|}
 
|}