Registers

Old3DS Name Address Width Used by
Yes I2C1_DATA 0x10161000 1
Yes I2C1_CNT 0x10161001 1
Yes I2C1_CNTEX 0x10161002 2
Yes I2C1_SCL 0x10161004 2
Yes I2C2_DATA 0x10144000 1
Yes I2C2_CNT 0x10144001 1
Yes I2C2_CNTEX 0x10144002 2
Yes I2C2_SCL 0x10144004 2
Yes I2C3_DATA 0x10148000 1
Yes I2C3_CNT 0x10148001 1
Yes I2C3_CNTEX 0x10148002 2
Yes I2C3_SCL 0x10148004 2

I2C_CNT

BIT DESCRIPTION
0 Stop (0=No, 1=Stop/last byte)
1 Start (0=No, 1=Start/first byte)
2 Pause (0=Transfer Data, 1=Pause after Error, used with/after Stop)
4 Ack Flag (0=Error, 1=Okay) (For DataRead: W, for DataWrite: R)
5 Data Direction (0=Write, 1=Read)
6 Interrupt Enable (0=Disable, 1=Enable)
7 Start/busy (0=Ready, 1=Start/busy)

I2C Devices

Device id Device bus id Device address Accessible via I2C service Device description
0 1 0x4a "i2c::MCU" Power management?(same device addr as the DSi power-management)
1 1 0x7a "i2c::CAM" Camera0?(same dev-addr as DSi cam0)
2 1 0x78 "i2c::CAM" Camera1?(same dev-addr as DSi cam1)
3 2 0x4a "i2c::MCU" MCU
4 2 0x78 "i2c::CAM" ?
5 2 0x2c "i2c::LCD" ?
6 2 0x2e "i2c::LCD" ?
7 2 0x40 "i2c::DEB" ?
8 2 0x44 "i2c::DEB" ?
9 3 0xa6 "i2c::HID" Unknown. The device table in I2C-module had the device address changed from 0xA6 to 0xD6 with 8.0.0-18.
10 3 0xd0 "i2c::HID" Gyroscope
11 3 0xd2 "i2c::HID" ?
12 3 0xa4 "i2c::HID" DebugPad
13 3 0x9a "i2c::IR" IR
14 3 0xa0 "i2c::EEP" eeprom?
15 2 0xee "i2c::NFC" New3DS-only NFC
16 1 0x40 "i2c::QTM" New3DS-only QTM
17 3 0x54 "i2c::IR" Used by IR-module starting with 8.0.0-18, for New3DS-only HID via "ir:rst". This deviceid doesn't seem to be supported by i2c module on 8.0.0-18(actual support was later added in New3DS i2c module).

Device 3

REGISTER WIDTH DESCRIPTION
0x03 8 ?
0x04 8 ?
0x09 1 Sound volume: 0x0..0x3F.
0xB 1 Battery level: 0x0..0x40.
0xF 1 Flags: bit7-5 are read via mcu::GPU. The rest of these are read via mcu::RTC: bit4 = BatteryChargeState. bit3 = AdapterState. bit1 = ShellState.
0x18 8 ?
0x20 8 Writing u8 value 4 here triggers a hardware system reboot. Writing u8 value 1 (repeatedly) triggers a shutdown via power-off?
0x22 8 ?
0x23 8 ?
0x24 8 ?
0x28 8 ?
0x29 8 ?
0x2A 8 ?
0x2B 8 ?
0x2C 8 ?
0x2D 0x64 This is used for controlling the notification LED(see MCURTC:SetInfoLEDPatternHeader as well), when this register is written.
0x2E 1 This returns the notification LED status when read.
0x30 8 ?
0x31 8 ?
0x32 8 ?
0x33 8 ?
0x34 8 ?
0x35 8 ?
0x36 8 ?
0x37 8 ?
0x38 8 ?
0x39 8 ?
0x3A 8 ?
0x3B 8 ?
0x3C 8 ?
0x41 8 ?
0x43 8 ?
0x4E 8 ?
0x50 8 ?
0x51 8 ?
0x58 8 ?
0x60 8 ?

Device 10

See the datasheet linked to on the Hardware page for reference.

Device 12

REGISTER WIDTH DESCRIPTION
0x0 21 DebugPad state.

This is the DebugPad device, see here.

Device 13

Raw I2C register address Internal register address Width Description
0x0 0x0 0x40 RHR / THR (data receive/send FIFO)
0x8 0x1 0x1 IER
0x10 0x2 0x1 FCR/IIR
0x18 0x3 0x1 LCR
0x20 0x4 0x1 MCR
0x28 0x5 0x1 LSR
0x30 0x6 0x1 MSR/TCR
0x38 0x7 0x1 SPR/TLR
0x40 0x8 0x1 TXLVL
0x48 0x9 0x1 RXLVL
0x50 0xA 0x1 IODir
0x58 0xB 0x1 IOState
0x60 0xC 0x1 IoIntEna
0x68 0xD 0x1 reserved
0x70 0xE 0x1 IOControl
0x78 0xF 0x1 EFCR

See the datasheet linked to on the Hardware page for reference. From that datasheet, for the structure of the I2C register address u8: "Bit 0 is not used, bits 2:1 select the channel, bits 6:3 select one of the UART internal registers. Bit 7 is not used with the I2C-bus interface, but it is used by the SPI interface to indicate a read or a write operation."

Device 15

This the New3DS NFC controller "I2C" interface. This device is accessed via the WriteDeviceRaw/ReadDeviceRaw I2C service commands.

Since the *Raw commands are used with this, this device has no I2C registers. Instead, raw data is transfered after the I2C device is selected. Hence, WriteDeviceRaw is used for sending commands to the controller, while ReadDeviceRaw is for receiving responses from the controller. Certain commands may return multiple command responses.

Command request / response structure:

Offset Size Description
0x0 0x1 Normally 0x10?
0x1 0x1 Command source / destination.
0x2 0x1 CmdID
0x3 0x1 Payload size.

Following the above header is the payload data(when payload size is non-zero), with the size specified in the header. The command response payload is usually at least 1-byte, where that byte appears to be normally 0x0. For command requests the payload data is the command parameters.

For command requests sent to the NFC tag itself, Cmd[1]=0x0 and CmdID=0x0. The command request payload data here is the actual command request data for the NFC tag, starting with the CmdID u8 at payload+0.

During NFC module startup, a certain command is sent to the controller which eventually(after various cmd-reply headers etc) returns the following the payload after the first byte in the payload:

000000: 44 65 63 20 32 32 20 32 30 31 32 31 34 3a 35 33  Dec 22 201214:53 
000010: 3a 35 30 01 05 0d 46 05 1b 79 20 07 32 30 37 39  :50...F..y .2079
000020: 31 42 35                                         1B5

Or that is: "Dec 22 201214:53:50<binary>20791B5". Therefore, this appears to return the part-number of the NFC controller(other command request(s) / response(s) use this part-number value too).

NFC controller commands

CmdRequest[1] CmdID Payload data for parameters Description
0x2E 0x2F 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.