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 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 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) |
− | *v = volatile (survives reboots)
| |
| {| class="wikitable" border="1" | | {| class="wikitable" border="1" |
| ! REGISTER | | ! REGISTER |
Line 261: |
Line 281: |
| | 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 313: |
Line 333: |
| | 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 325: |
Line 351: |
| | s | | | s |
| | ro | | | ro |
− | | ? | + | | Unused and unwritable byte :( |
| |- | | |- |
| | 0x15 | | | 0x15 |
| + | - 0x17 |
| | s | | | s |
− | | rw v | + | | rw |
− | | ? | + | | Unused and unreferenced free RAM! Good for userdata. |
− | |-
| |
− | | 0x16
| |
− | | s
| |
− | | rw v
| |
− | | ?
| |
− | |-
| |
− | | 0x17
| |
− | | s
| |
− | | rw v
| |
− | | ?
| |
| |- | | |- |
| | 0x18 | | | 0x18 |
Line 347: |
Line 364: |
| | 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: ??? (Power Management related?) | + | 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: ??? (HID related) | + | bit11: ??? (accelerometer related) |
| bit12: HID update | | bit12: HID update |
− | bit13: Battery dead(?) | + | bit13: Battery percentage status change (triggered at 10%, 5%, and 0% while discharging) |
− | bit14: ??? (Power Management related?) | + | bit14: Battery stopped charging (independent of charger state) |
− | bit15: ??? (Power Management related?) | + | bit15: Battery started charging |
| + | Nonmaskable(?) interrupts |
| + | bit16: ??? |
| + | bit17: ??? (opposite even for bit16) |
| bit22: Volume slider position change | | bit22: Volume slider position change |
− | bit24: ??? (???) | + | bit23: ??? Register 0x0E update |
− | bit25: ??? (???) | + | bit24: ??? (the off event for below bit) |
| + | bit25: ??? (triggered when something related to the GPU is turned on, most likely backlight) |
| bit26: ??? (???) | | bit26: ??? (???) |
| bit27: ??? (???) | | bit27: ??? (???) |
| bit28: ??? (???) | | bit28: ??? (???) |
− | bit29: ??? (???) | + | bit29: ??? backlight on? |
− | bit30: forced off my mcu sysmodule | + | bit30: bit set by mcu sysmodule |
− | bit31: forced off my mcu sysmodule | + | bit31: bit set by mcu sysmodule |
| |- | | |- |
| | 0x1C | | | 0x1C |
| + | - 0x1F |
| | s | | | s |
− | | rw v | + | | rw |
− | | ? | + | | Unused and unreferenced free RAM! Good for userdata. |
− | |-
| |
− | | 0x1D
| |
− | | s
| |
− | | rw v
| |
− | | ?
| |
− | |-
| |
− | | 0x1E
| |
− | | s
| |
− | | rw v
| |
− | | ?
| |
− | |-
| |
− | | 0x1F
| |
− | | s
| |
− | | rw v
| |
− | | ?
| |
| |- | | |- |
| | 0x20 | | | 0x20 |
Line 455: |
Line 462: |
| | 0x29 | | | 0x29 |
| | sd(5) | | | sd(5) |
− | | 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 470: |
Line 485: |
| 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 494: |
Line 510: |
| |- | | |- |
| | 0x30 | | | 0x30 |
− | - 0x37 | + | - 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)). | | | 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 505: |
Line 521: |
| byte 5: months | | byte 5: months |
| byte 6: years | | byte 6: years |
− | byte 7: leap year counter / "watch error correction" register (unused)
| + | |- |
| + | | 0x37 |
| + | | s |
| + | | rw |
| + | | RTC time byte 7: leap year counter / "watch error correction" register (unused in code) |
| |- | | |- |
| | 0x38 | | | 0x38 |
− | - 0x3A | + | - 0x3C |
| | s | | | s |
| | rw | | | rw |
Line 514: |
Line 534: |
| byte 0: minutes | | byte 0: minutes |
| byte 1: hours | | byte 1: hours |
− | byte 2: week | + | byte 2: day |
| + | byte 3: month |
| + | byte 4: year |
| |- | | |- |
| | 0x3B | | | 0x3B |
| | s | | | s |
| | rw | | | rw |
− | | Register 0x3B could be used to upload [[MCU_Services#MCU_firmware_versions|MCU firmware]] if some conditions are met. | + | | Could be used on very old MCU_FIRM versions to upload [[MCU_Services#MCU_firmware_versions|MCU firmware]] if some conditions are met. |
− | |-
| |
− | | 0x3C
| |
− | | s
| |
− | | ro
| |
− | | ???
| |
| |- | | |- |
| | 0x3D | | | 0x3D |
| 0x3E | | 0x3E |
− | | s | + | | 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 543: |
Line 560: |
| | s | | | s |
| | rw | | | rw |
− | | Pedometer state (?) | + | | Gyro sampling mode. Bits 0 and 1 control the gyro. If bits 0 or 1 are non-zero then gyro sampling is enabled. |
| |- | | |- |
| | 0x41 | | | 0x41 |
Line 563: |
Line 580: |
| | s | | | s |
| | rw | | | rw |
− | | ???, accelometer related | + | | ???, pedoometer related(?) |
| |- | | |- |
| | 0x45 | | | 0x45 |
Line 576: |
Line 593: |
| ! V=0xC0 | | ! V=0xC0 |
| |- | | |- |
− | | Y (=roll) | + | | X (left/right) |
| | held vertically | | | held vertically |
− | | vertical right side | + | | rotated or tilted left |
− | | vertical left side | + | | rotated or tilted right |
| + | |- |
| + | | Y (forwards/backwards) |
| + | | laid flat |
| + | | held up |
| + | | helf up upside-down |
| |- | | |- |
− | | Z? (=yaw) | + | | Z (???) |
| | ??? | | | ??? |
− | | ???
| |
− | | ???
| |
− | |-
| |
− | | X? (=pitch)
| |
− | | held vertically
| |
| | ??? | | | ??? |
| | ??? | | | ??? |
Line 643: |
Line 660: |
| | 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 653: |
Line 670: |
| |- | | |- |
| | 0x60 | | | 0x60 |
− | | ds(1) | + | | ds |
− | | ro | + | | rw |
− | first byte is wo
| |
| | Looping queue register | | | Looping queue register |
| Writing to first byte resets the queue position to the nth element | | Writing to first byte resets the queue position to the nth element |
Line 664: |
Line 680: |
| | rw | | | rw |
| | Writing to this register pushes values on top of register 0x60's stack. Reading from this register doesn't advance the stack. | | | Writing to this register pushes values on top of register 0x60's stack. Reading from this register doesn't advance the stack. |
− | 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. | + | 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. |
| |- | | |- |
| | 0x62 - 0x7E | | | 0x62 - 0x7E |
Line 672: |
Line 688: |
| |- | | |- |
| | 0x7F | | | 0x7F |
− | | d(0x13) | + | | d(9-0x13) |
| | ro | | | ro |
− | | Various system state information. | + | | Various system state information (debug pointer table) |
| 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 683: |
Line 700: |
| 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. |
| |- | | |- |
| | 0x80 | | | 0x80 |
Line 703: |
Line 720: |
| | | |
| 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 == |