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" |
− | | 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 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" |
− | | eeprom? | + | | HWCAL EEPROM ([[Hardware_calibration#Header|only present on dev units where SHA256 is used for HWCAL verification]]) |
| |- | | |- |
| | 15 | | | 15 |
Line 227: |
Line 248: |
| | | |
| == Device 3 == | | == Device 3 == |
| + | ro = read-only (writing is no-op) |
| + | rw = read-write |
| + | wo = write-only (reading will yield 00, FF, or unpredictable data) |
| + | |
| + | d* = dynamic register (explaination below this table) |
| + | s* = shared register (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 244: |
Line 277: |
| |- | | |- |
| | 0x02 | | | 0x02 |
− | | s | + | | d |
− | | ro | + | | 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 |
| + | 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 |
− | | s | + | | ds |
| | rw | | | rw |
− | | Top screen flicker | + | | Top screen Vcom |
| |- | | |- |
| | 0x04 | | | 0x04 |
− | | s | + | | ds |
| | rw | | | rw |
− | | Bottom screen flicker | + | | Bottom screen Vcom |
| |- | | |- |
| | 0x05 | | | 0x05 |
− | | s / 0x4003?
| + | - 0x07 |
− | | rw / ?
| |
− | | Danger zone - [[MCU_Services#MCU_firmware_versions|MCU firmware]] is uploaded here (???)
| |
− | |-
| |
− | | 0x06
| |
| | s | | | s |
| | rw | | | rw |
− | | ? | + | | Danger zone - [[MCU_Services#MCU_firmware_versions|MCU unlock sequence]] is written here. |
− | |-
| |
− | | 0x07
| |
− | | s
| |
− | | rw
| |
− | | ? | |
| |- | | |- |
| | 0x08 | | | 0x08 |
Line 287: |
Line 316: |
| | s | | | s |
| | ro | | | ro |
− | | ? (seems to be power management related?) | + | | Battery temperature (in Celcius?) |
| |- | | |- |
| | 0x0B | | | 0x0B |
Line 297: |
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 312: |
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]]. |
| + | bit01: ShellState |
| + | bit03: AdapterState |
| + | bit04: BatteryChargeState |
| + | bit05: Bottom screen backlight on |
| + | bit06: Top screen backlight on |
| + | bit07: GPU on(?) |
| |- | | |- |
| | 0x10 | | | 0x10 |
Line 318: |
Line 353: |
| | s | | | s |
| | ro | | | ro |
− | | Special HID status flags: | + | | Received interrupt bitmask, see register 0x18 for possible values |
− | bit00: power button pressed
| + | If no interrupt was received this register is 0 |
− | bit01: power button pressed long
| |
− | bit02: home button pressed
| |
− | bit03: home button released
| |
− | bit04: wifi slider pressed
| |
− | bit05: shell got closed
| |
− | bit06: shell got opened
| |
− | bit07: ???, sends srv notification 0x20C
| |
− | bit08: charger plugged in
| |
− | bit09: charger plugged out
| |
− | bit11: ???, signals an event
| |
− | bit14: ???, sends srv notification 0x210
| |
− | bit15: ???, sends srv notification 0x20F
| |
− | bit22: volume slider position changed
| |
− | If nothing has changed this register is 0 | |
| |- | | |- |
| | 0x14 | | | 0x14 |
| | s | | | s |
| | ro | | | ro |
− | | ? | + | | Unused and unwritable byte :( |
| |- | | |- |
| | 0x15 | | | 0x15 |
| + | - 0x17 |
| | s | | | s |
| | rw | | | rw |
− | | ? | + | | Unused and unreferenced free RAM! Good for userdata. |
− | |-
| |
− | | 0x16
| |
− | | s
| |
− | | rw
| |
− | | ?
| |
− | |-
| |
− | | 0x17
| |
− | | s
| |
− | | rw
| |
− | | ?
| |
| |- | | |- |
| | 0x18 | | | 0x18 |
Line 359: |
Line 371: |
| | s | | | s |
| | rw | | | rw |
− | | Interrupt mask (0=enabled,1=disabled) | + | | Interrupt mask for register 0x10 (0=enabled,1=disabled) |
− | bit11: ??? (HID related) | + | bit00: Power button press (for 27 "ticks") |
− | bit12: Accelerometer update | + | bit01: Power button held (for 375 "ticks"; the 3DS turns off regardless after a fixed time) |
− | bit30: forced off my mcu sysmodule | + | bit02: HOME button press (for 5 "ticks") |
− | bit31: forced off my mcu sysmodule | + | bit03: HOME button release |
| + | bit04: WiFi switch button |
| + | bit05: Shell close |
| + | bit06: Shell open |
| + | bit07: Fatal hardware condition([[Services#Notifications|?]]) (sent when the MCU gets reset by the Watchdog timer) |
| + | bit08: Charger removed |
| + | 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) |
| + | bit11: ??? (accelerometer related) |
| + | bit12: HID update |
| + | bit13: Battery percentage status change (triggered at 10%, 5%, and 0% while discharging) |
| + | 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 |
| + | bit23: ??? Register 0x0E update |
| + | bit24: ??? (the off event for below bit) |
| + | bit25: ??? (triggered when something related to the GPU is turned on, most likely backlight) |
| + | bit26: ??? (???) |
| + | bit27: ??? (???) |
| + | bit28: ??? (???) |
| + | bit29: ??? backlight on? |
| + | bit30: bit set by mcu sysmodule |
| + | bit31: bit set by mcu sysmodule |
| |- | | |- |
| | 0x1C | | | 0x1C |
| + | - 0x1F |
| | s | | | s |
| | rw | | | rw |
− | | ? | + | | Unused and unreferenced free RAM! Good for userdata. |
− | |-
| |
− | | 0x1D
| |
− | | s
| |
− | | rw
| |
− | | ?
| |
− | |-
| |
− | | 0x1E
| |
− | | s
| |
− | | rw
| |
− | | ?
| |
− | |-
| |
− | | 0x1F
| |
− | | s
| |
− | | rw
| |
− | | ?
| |
| |- | | |- |
| | 0x20 | | | 0x20 |
− | | s | + | | d |
| | wo | | | wo |
| | 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: doesn't seem to do anything, but an mcu::RTC command uses this | + | - Asserts FCRAM_RESET (P3.0 = 0) (deasserts nFCRAM_RESET) |
− | Other bits are unused, and seem to do nothing.
| + | 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 |
− | | s | + | | d |
− | | ro(?) | + | | 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 |
− | | s | + | | d |
| | wo | | | wo |
| | Used to set LCD states | | | Used to set LCD states |
Line 411: |
Line 449: |
| 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. |
| + | The rest of the bits are masked away. |
| |- | | |- |
| | 0x23 | | | 0x23 |
− | | s | + | | d |
− | | ro(?) | + | | wo |
− | | ?
| + | | Writing 0x72 ('r') resets the MCU, but this is stubbed on retail? |
| |- | | |- |
| | 0x24 | | | 0x24 |
| | s | | | s |
− | | ?? | + | | rw |
| | Watchdog timer. This must be set *before* the timer is triggered, otherwise the old value is used. Value zero disables the watchdog. | | | Watchdog timer. This must be set *before* the timer is triggered, otherwise the old value is used. Value zero disables the watchdog. |
| |- | | |- |
Line 433: |
Line 474: |
| |- | | |- |
| | 0x27 | | | 0x27 |
− | | s | + | | sd |
− | | ro | + | | rw |
| | Raw volume slider state | | | Raw volume slider state |
| |- | | |- |
Line 443: |
Line 484: |
| |- | | |- |
| | 0x29 | | | 0x29 |
− | | dynamic / s | + | | sd(5) |
− | | ro / rw | + | | rw |
− | | Repeat register, any byte written in the first byte gets repeated indefinitely(?, needs confirmation past 0xFF). The rest of the bytes are read-only. Setting the shared byte of this register (via overflow glitches) will also work, confirming that this is a semi-dynamic register as the first byte is stored in the shared register pool, but the rest of the bytes are fake. | + | | 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 |
| | s | | | s |
| | rw | | | rw |
− | | WiFi LED state, non-0 value turns on the WiFi LED, capped at 0x0F | + | | WiFi LED state, non-0 value turns on the WiFi LED, 4 bits wide |
| |- | | |- |
| | 0x2B | | | 0x2B |
| | s | | | s |
| | rw | | | rw |
− | | Camera LED state, 0, 3, 6-0xF = off, 1 = slowly blinking, 2 = constantly on, 4 = flash once, 5 = delay before changing to 2 | + | | Camera LED state, 4bits wide, |
| + | 0, 3, 6-0xF = off |
| + | 1 = slowly blinking |
| + | 2 = constantly on |
| + | 3 = "TWL" mode |
| + | 4 = flash once |
| + | 5 = delay before changing to 2 |
| |- | | |- |
| | 0x2C | | | 0x2C |
| | s | | | s |
| | rw | | | rw |
− | | 3D LED state, capped at 0x0F | + | | 3D LED state, 4 bits wide |
| |- | | |- |
| | 0x2D | | | 0x2D |
Line 474: |
Line 529: |
| | 0x2F | | | 0x2F |
| | s | | | s |
− | | ro(?) | + | | wo? |
− | | ? | + | | ??? The write function for this register is stubbed. |
| |- | | |- |
| | 0x30 | | | 0x30 |
| - 0x36 | | - 0x36 |
− | | s | + | | 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)). Byte 0 encodes seconds, byte 1 minutes, byte 2 hours, byte 3 is either the current day of the week or current week of month (not used by anything though), byte 4 days, byte 5 months and byte 6 years | + | | 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)). |
| + | byte 0: seconds |
| + | byte 1: minutes |
| + | byte 2: hours |
| + | byte 3: current week (unused) |
| + | byte 4: days |
| + | byte 5: months |
| + | byte 6: years |
| |- | | |- |
| | 0x37 | | | 0x37 |
| | s | | | s |
| | rw | | | rw |
− | | ? | + | | RTC time byte 7: leap year counter / "watch error correction" register (unused in code) |
| |- | | |- |
| | 0x38 | | | 0x38 |
Line 493: |
Line 555: |
| | rw | | | rw |
| | RTC alarm registers | | | RTC alarm registers |
− | Register 0x3B could be used to upload [[MCU_Services#MCU_firmware_versions|MCU firmware]] if some conditions are met.
| + | byte 0: minutes |
| + | byte 1: hours |
| + | byte 2: day |
| + | byte 3: month |
| + | byte 4: year |
| + | |- |
| + | | 0x3B |
| + | | s |
| + | | 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 |
− | | s (2) | + | | ds |
| | ro | | | ro |
− | | RTC tick counter (resets to 0 when the seconds increase) | + | | RTC tick counter / "ITMC" (when resets to 0 the seconds increase) |
| + | Only reading 0x3D will update the in-RAM value |
| |- | | |- |
| | 0x3F | | | 0x3F |
− | | s | + | | d |
| | wo | | | wo |
− | | Peripheral power related? bit0 seems to depower everything, pressing the power key afterwards instantly turns the whole 3DS off | + | | 2 bits |
| + | 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 |
| |- | | |- |
| | 0x40 | | | 0x40 |
| | 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 519: |
Line 593: |
| | s | | | s |
| | rw | | | rw |
− | | ? | + | | Unused? |
| |- | | |- |
| | 0x43 | | | 0x43 |
| | s | | | s |
| | rw | | | rw |
− | | ???, accelometer related | + | | Unused???, accelometer related |
| |- | | |- |
| | 0x44 | | | 0x44 |
| | s | | | s |
| | rw | | | rw |
− | | ???, accelometer related | + | | ???, pedoometer related(?) |
| |- | | |- |
| | 0x45 | | | 0x45 |
| + | - 0x4A |
| | s | | | s |
− | | rw | + | | 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" |
| + | ! AXIS |
| + | ! V=0x00 |
| + | ! V=0x40 |
| + | ! V=0xC0 |
| |- | | |- |
− | | 0x46 | + | | X (left/right) |
− | | s | + | | held up vertically |
− | | ro | + | | rotated left 90° like a steering wheel |
− | | Gyro Y(?) axis rotation (0x00 = flat, 0x40 = 3DS standing on right side, 0xBE = 3DS standing on left side) | + | | rotated right 90° like a steering wheel |
| |- | | |- |
− | | 0x48 | + | | Y (forwards/backwards) |
− | | s | + | | laid flat on the desk with the screen facing up |
− | | ro | + | | held up vertically |
− | | Gyro Z(?) axis rotation (0x00 = flat, 0x40 = 3DS standing horizontally, 0xBE = 3DS base is horizontally upside-down) | + | | held up vertically with screen facing upside-down |
| |- | | |- |
− | | 0x4A | + | | Z (???) |
− | | s | + | | ??? |
− | | ro | + | | ??? |
− | | Gyro X(?) axis rotation (0x00 = 3DS base facing upwards, 0x40 = face-down flat, 0xBE = standing(?) flat) | + | | ??? |
| + | |} |
| |- | | |- |
| | 0x4B | | | 0x4B |
Line 557: |
Line 638: |
| |- | | |- |
| | 0x4C | | | 0x4C |
− | | s | + | 0x4D |
| + | | ?? |
| + | | ?? |
| + | | ?? |
| + | |- |
| + | | 0x4E |
| + | | d |
| | rw | | | rw |
− | | ? | + | | ??? this = (0xFFE9E & 1) ? 0x10 : 0 |
| + | |- |
| + | | 0x4F |
| + | | d(6) |
| + | | ro |
| + | | |
| |- | | |- |
− | | 0x4D | + | | 0x50 |
| | s | | | s |
| | rw | | | rw |
− | | ? | + | | ??? |
| |- | | |- |
− | | 0x4E | + | | 0x51 |
| | s | | | s |
| | rw | | | rw |
− | | ? | + | | ??? |
| |- | | |- |
− | | 0x4F | + | | 0x52 |
− | | 6(?)
| |
− | | ro
| |
− | | Unkonwn. Reading past the 6th byte is FF-filled, so register size of 6 is assumed.
| |
− | |-
| |
− | | 0x50
| |
| - 0x57 | | - 0x57 |
| | s | | | s |
Line 585: |
Line 672: |
| | s | | | s |
| | rw | | | rw |
− | | DSP volume slider 0% volume offset (setting this to 0xFF will esentially mute the DSP as it's the volume slider's maximum raw value) | + | | Register-mapped ADC register |
| + | DSP volume slider 0% volume offset (setting this to 0xFF will esentially mute the DSP as it's the volume slider's maximum raw value) |
| |- | | |- |
| | 0x59 | | | 0x59 |
| | s | | | s |
| | rw | | | rw |
− | | DSP volume slider 100% volume offset (setting both this and the above to 0 will disable the volume slider with 100% volume, setting this to a lower value than the above will make the volume slider have only 2 states; on and off) | + | | Register-mapped ADC register |
| + | DSP volume slider 100% volume offset (setting both this and the above to 0 will disable the volume slider with 100% volume, setting this to a lower value than the above will make the volume slider have only 2 states; on and off) |
| |- | | |- |
| | 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 |
| - 0x5F | | - 0x5F |
| | s | | | s |
− | | ro(?) | + | | - |
− | | ? (these seem to be invalid regsiters) | + | | These registers are out of bounds (0xFFC00 and up), they don't exist, writing is no-op, reading will yield FFs. |
| |- | | |- |
| | 0x60 | | | 0x60 |
− | | 0x100 | + | | d |
− | | ro | + | | rw |
− | first byte is wo
| + | | Free register bank address (index) select |
− | | Looping queue register | + | Selects the index to read from in the free register bank, up to 200. Used in conjunction with reg 0x61. |
− | Writing to first byte resets the queue position to the nth element
| + | |
− | 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 |
− | | 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 power-off, but does not seem to be saved to non-volatile storage (does not survive 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 |
| | s | | | s |
− | | invalid (ro) | + | | - |
− | | These registers don't exist at all, thus reading them will yield 0xFF | + | | These registers don't exist, writing is no-op, reading will yield FFs. |
| |- | | |- |
| | 0x7F | | | 0x7F |
− | | 19(?) | + | | d(9-0x13) |
| | ro | | | ro |
− | | Various system state information. | + | | Various system state information (debug pointer table) |
− | byte 06: battery related? (seems to decrease while charging and increase while discharging) | + | byte 0x00: Console type, see [[Configuration_Memory#MCU_HW_INFO|here]] |
− | byte 09: system model (see [[Cfg:GetSystemModel#System_Model_Values|Cfg:GetSystemModel]] for values) | + | byte 0x01: PMIC vendor code |
− | byte 10: power LED related? 0 is off, 1 is red | + | byte 0x02: Battery vendor code |
− | byte 13: RGB LED red intensity | + | byte 0x03: MGIC version (major?) |
− | byte 14: RGB LED green intensity | + | byte 0x04: MGIC version (minor?) |
− | byte 15: RGB LED blue intensity | + | byte 0x05: RCOMP(?) |
− | byte 17: WiFi LED brightness | + | byte 0x06: battery related? (seems to decrease while charging and increase while discharging) |
− | byte 18: raw button states? | + | byte 0x09: system model (see [[Cfg:GetSystemModel#System_Model_Values|Cfg:GetSystemModel]] for values) |
− | bit0: unset while power button is held | + | byte 0x0A: Red Power LED mode (0 = off, 1 = on) |
− | bit1: unset while home button is held | + | byte 0x0B: Blue Power LED intensity (0x00 - 0xFF) |
− | bit2: unset while Wifi slider is held | + | byte 0x0D: RGB LED red intensity |
| + | byte 0x0E: RGB LED green intensity |
| + | byte 0x0F: RGB LED blue intensity |
| + | byte 0x11: WiFi LED brightness |
| + | byte 0x12: raw button states? |
| + | bit0: unset while Power button is held |
| + | bit1: unset while HOME button 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. |
| |- | | |- |
| | 0x80 | | | 0x80 |
| - 0xFF | | - 0xFF |
| | s | | | s |
− | | invalid (ro) | + | | - |
− | | These registers don't exist at all, thus reading them will yield 0xFF | + | | These registers don't exist, writing is no-op, reading will yield FFs. |
| |} | | |} |
| | | |
− | Note: the letter "s" in the size field means that the given register is in a "shared register pool", meaning if you read/write with size more than 1 you can read the next `readamount-1` of shared registers. It's possible to corrupt the shared value of a "non-shared" register by writing into a shared register with a size bigger than one. Writing more than 0x100 bytes into a shared register will corrupt all writable registers, including the shared portion of "non-shared" registers.
| + | Shared register: the letter "s" means that the given register is in a "shared register pool", meaning the resgister is in the register pool in RAM at address <code>0xFFBA4 + registernumber</code>. |
| + | |
| + | Dynamic register: these registers aren't in the shared pool, they just "pretend" to be there. These registers often don't retain their set value, change rapidly, or control various hardware. |
| | | |
− | Non-shared register: it's a register 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 == |
Line 699: |
Line 807: |
| | | |
| == 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 712: |
Line 823: |
| |} | | |} |
| | | |
− | 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 == |