Difference between revisions of "I2C Bus"
(25 intermediate revisions by 2 users not shown) | |||
Line 23: | Line 23: | ||
|- | |- | ||
| 1 | | 1 | ||
− | | Start/device select bit? | + | | Start/device select bit? [guess from old [[I2C]] page: More data coming?] |
|- | |- | ||
| 2 | | 2 | ||
Line 38: | Line 38: | ||
|- | |- | ||
| 6 | | 6 | ||
− | | Unknown, always set when writing to CNT? | + | | Unknown, always set when writing to CNT? [guess from old [[I2C]] page: Interrupt Enable?] |
|- | |- | ||
| 7 | | 7 | ||
Line 47: | Line 47: | ||
When selecting a register, the register byte address is written here. When reading or writing data to the I2C device, it's read/written from here. | When selecting a register, the register byte address is written here. When reading or writing data to the I2C device, it's read/written from here. | ||
− | When selecting a device, the device byte address is written here. Bit0 is unknown, when reading from certain devices | + | When selecting a device, the device byte address is written here. Bit0 is unknown, when reading from certain devices, the device is first selected and then the register, following that the device is reselected with device byte address bit0 set. |
== Protocol == | == Protocol == | ||
Line 59: | Line 59: | ||
! Device address | ! Device address | ||
! Device swiWaitByLoop delay | ! Device swiWaitByLoop delay | ||
+ | ! I2CDATA bit0 set with dev addr required for reading | ||
! Device description | ! Device description | ||
|- | |- | ||
+ | | 0x7A | ||
| 0x00 | | 0x00 | ||
− | | | + | | No |
− | | Camera0? | + | | Camera0(internal?) |
|- | |- | ||
− | | | + | | 0x78 |
| 0x00 | | 0x00 | ||
− | | Camera1? | + | | No |
+ | | Camera1(external?) | ||
|- | |- | ||
+ | | 0xA0 | ||
| 0x00 | | 0x00 | ||
− | | | + | | No |
− | | | + | | Camera0 config |
|- | |- | ||
+ | | 0xE0 | ||
| 0x00 | | 0x00 | ||
− | | | + | | No |
− | | | + | | Camera1 config |
|- | |- | ||
− | | | + | | 0x4A |
| 0x180 | | 0x180 | ||
+ | | Yes | ||
| Power management | | Power management | ||
|- | |- | ||
− | | | + | | 0x40 |
| 0x00 | | 0x00 | ||
+ | | Yes | ||
| ? | | ? | ||
|- | |- | ||
− | | | + | | 0x90 |
| 0x00 | | 0x00 | ||
+ | | Yes | ||
| ? | | ? | ||
+ | |} | ||
+ | |||
+ | === Cameras === | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | ! REGISTER | ||
+ | ! WIDTH | ||
+ | ! DESCRIPTION | ||
+ | |- | ||
+ | | 0x18 | ||
+ | | 2 | ||
+ | | Unknown | ||
+ | |- | ||
+ | | 0x98c | ||
+ | | 2 | ||
+ | | Unknown | ||
|- | |- | ||
− | | | + | | 0x990 |
− | | | + | | 2 |
− | | | + | | Unknown |
|} | |} | ||
− | === | + | === Cameras Config === |
− | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 102: | Line 125: | ||
! DESCRIPTION | ! DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0xc1 |
+ | | 8 | ||
+ | | Data from the below camconf_c1 structure is written here. | ||
+ | |} | ||
+ | |||
+ | ==== camconf_c1 ==== | ||
+ | Data is retrieved from this struct via this byte-offset: (conf_type*0x30) + (conf_index*8). Max number of conf types and conf indexes are 2 and 6. | ||
+ | {| class="wikitable" border="1" | ||
+ | ! CONF TYPE | ||
+ | ! CONF INDEX | ||
+ | ! DATA | ||
+ | ! DESCRIPTION | ||
+ | |- | ||
+ | | 0 | ||
+ | | 0 | ||
+ | | 38 30 1F 1F 2C 30 1F 1F | ||
+ | | ? | ||
+ | |- | ||
+ | | 0 | ||
+ | | 1 | ||
+ | | 38 30 1F 1F 38 30 1F 1F | ||
+ | | ? | ||
+ | |- | ||
+ | | 0 | ||
+ | | 2 | ||
+ | | 2C 30 1F 1F 2C 30 1F 1F | ||
+ | | ? | ||
+ | |- | ||
+ | | 0 | ||
+ | | 3 | ||
+ | | 2C 30 1F 1F 2C 30 1F 1F | ||
+ | | ? | ||
+ | |- | ||
+ | | 0 | ||
+ | | 4 | ||
+ | | 2C 30 1F 1F 2C 30 1F 1F | ||
+ | | ? | ||
+ | |- | ||
+ | | 0 | ||
+ | | 5 | ||
+ | | 2C 30 1F 1F 2C 30 1F 1F | ||
+ | | ? | ||
+ | |- | ||
+ | | 1 | ||
+ | | 0 | ||
+ | | 30 28 18 18 34 28 08 18 | ||
+ | | ? | ||
+ | |- | ||
+ | | 1 | ||
+ | | 1 | ||
+ | | 30 28 18 18 30 28 08 18 | ||
+ | | ? | ||
+ | |- | ||
| 1 | | 1 | ||
− | | | + | | 2 |
+ | | 28 28 18 18 28 28 08 18 | ||
+ | | ? | ||
|- | |- | ||
− | |||
| 1 | | 1 | ||
− | | | + | | 3 |
+ | | 28 28 18 18 28 28 08 18 | ||
+ | | ? | ||
|- | |- | ||
− | |||
| 1 | | 1 | ||
− | | | + | | 4 |
+ | | 28 28 18 18 28 28 08 18 | ||
+ | | ? | ||
|- | |- | ||
− | |||
| 1 | | 1 | ||
− | | | + | | 5 |
+ | | 28 28 18 18 28 28 08 18 | ||
+ | | ? | ||
|} | |} | ||
− | === | + | === Power management === |
− | + | When register 0x11 has value one written to, a power cycle is done. When reg 0x70 val 1 is written before reg 0x11, sysmenu/launcher doesn't display the heath screen, otherwise when not written with the register value left at zero the health screen is displayed. Reg 0x70 would be zero on hard boot, when any twlsdk app does a system reset it writes value 1 to reg 0x70. | |
− | When | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 130: | Line 209: | ||
| 0x0 | | 0x0 | ||
| 1 | | 1 | ||
− | | | + | | Unknown, battery related? Usually this reg val is 0x33? |
|- | |- | ||
| 0x10 | | 0x10 | ||
| 1 | | 1 | ||
− | | Power | + | | Power flags. When bit0 is set, arm7 does a system reset. When bit1 or bit3 are set, arm7 does a shutdown. Bits 0-2 are used for DSi [[Interrupts|IRQ6]] IF flags. |
+ | |- | ||
+ | | 0x11 | ||
+ | | 1 | ||
+ | | Power reg? Writing value 1 here does a system reset. Writing value 2 powers off all DSi-only hw. | ||
|- | |- | ||
− | | | + | | 0x12 |
+ | | 1 | ||
+ | | Might be MMC bus power related, unknown. | ||
+ | |- | ||
+ | | 0x20 | ||
+ | | 1 | ||
+ | | Battery flags. When zero the battery is at critical level, arm7 does a shutdown. Bit7 is set when the battery is charging. Battery levels in the low 4-bits: battery icon bars full 0xF, 3 bars 0xB, 2 bars 0x7, one solid red bar 0x3, and one blinking red bar 0x1. When plugging in or removing recharge cord, this value increases/decreases between the real battery level and 0xF, thus the battery level while bit7 is set is useless. | ||
+ | |- | ||
+ | | 0x21 | ||
| 1 | | 1 | ||
− | | | + | | ? |
+ | |- | ||
+ | | 0x31 | ||
+ | | 1 | ||
+ | | External camera LED control, valid values are 0-2. Value 0 disables the LED, value 1 activates the LED, value 2 activates the LED with the LED blinking. | ||
+ | |- | ||
+ | | 0x40 | ||
+ | | 1 | ||
+ | | Volume level: 0x00 - 0x1F. | ||
|- | |- | ||
− | | | + | | 0x70 |
+ | | 1 | ||
+ | | BOOTFLG | ||
+ | |} | ||
+ | |||
+ | === Device 0x90 === | ||
+ | {| class="wikitable" border="1" | ||
+ | ! REGISTER | ||
+ | ! WIDTH | ||
+ | ! DESCRIPTION | ||
+ | |- | ||
+ | | 0x2 | ||
+ | | 1 | ||
+ | | Used for DSi [[Interrupts|IRQ6]] IF flags. | ||
+ | |- | ||
+ | | 0x4 | ||
| 1 | | 1 | ||
− | | | + | | Unknown (bit0 toggled) |
|} | |} |
Latest revision as of 16:06, 16 July 2013
Registers
NAME | ADDRESS | WIDTH |
---|---|---|
REG_I2CDATA | 0x04004500 | 1 |
REG_I2CCNT | 0x04004501 | 1 |
REG_I2CCNT
BIT | DESCRIPTION |
---|---|
0 | R/W, clear for write, set for read |
1 | Start/device select bit? [guess from old I2C page: More data coming?] |
2 | Restart/device reselect bit? |
3 | ? |
4 | SCL hold. When clear SCL is being held low, set when SCL is high. This bit must always be set(by reading CNT again) after writing REG_I2CCNT. This bit must be set when writing blocks of data(more than 1 byte) with bit0 clear. |
5 | SCL, toggle this for each loop iteration(in the loop execute the I2C WR code) with max 8 iterations where the loop exits successfully when bit 4 is set. This bit must be set when writing blocks of data(more than 1 byte) with bit0 clear. |
6 | Unknown, always set when writing to CNT? [guess from old I2C page: Interrupt Enable?] |
7 | Enable/busy, wait for this bit to clear after writing to I2CCNT. |
REG_I2CDATA
When selecting a register, the register byte address is written here. When reading or writing data to the I2C device, it's read/written from here. When selecting a device, the device byte address is written here. Bit0 is unknown, when reading from certain devices, the device is first selected and then the register, following that the device is reselected with device byte address bit0 set.
Protocol
Wait for the busy bit to clear. Write the device address to REG_I2CDATA, then write 0xc2(busy/enable, bit 6, and start bit 1 set) to REG_I2CCNT. Execute swiWaitByLoop for a device-specific duration, then write the register address to REG_I2CDATA, and write 0xc0 to REG_I2CCNT.(busy/enable and bit 6 set) Wait with swiWaitByLoop device duration, then write the data to REG_I2CDATA when writing. When reading, write the device address to REG_I2CDATA and write 0xc2 to REG_I2CCNT. When the delay value is zero, write 0xc1 | i<<5 to REG_I2CCNT, otherwise write 0xc0 | i<<5 to REG_I2CCNT, wait for busy to clear, delay, then write 0xc5 to REG_I2CCNT. For writing i is the loop i for iteration, for reading replace that with 1. When reading, read the data from REG_I2CCNT. Return a error if REG_I2CCNT bit 4 SCL hold is set, otherwise return normal.
I2C devices
I2C device table:
Device address | Device swiWaitByLoop delay | I2CDATA bit0 set with dev addr required for reading | Device description |
---|---|---|---|
0x7A | 0x00 | No | Camera0(internal?) |
0x78 | 0x00 | No | Camera1(external?) |
0xA0 | 0x00 | No | Camera0 config |
0xE0 | 0x00 | No | Camera1 config |
0x4A | 0x180 | Yes | Power management |
0x40 | 0x00 | Yes | ? |
0x90 | 0x00 | Yes | ? |
Cameras
REGISTER | WIDTH | DESCRIPTION |
---|---|---|
0x18 | 2 | Unknown |
0x98c | 2 | Unknown |
0x990 | 2 | Unknown |
Cameras Config
REGISTER | WIDTH | DESCRIPTION |
---|---|---|
0xc1 | 8 | Data from the below camconf_c1 structure is written here. |
camconf_c1
Data is retrieved from this struct via this byte-offset: (conf_type*0x30) + (conf_index*8). Max number of conf types and conf indexes are 2 and 6.
CONF TYPE | CONF INDEX | DATA | DESCRIPTION |
---|---|---|---|
0 | 0 | 38 30 1F 1F 2C 30 1F 1F | ? |
0 | 1 | 38 30 1F 1F 38 30 1F 1F | ? |
0 | 2 | 2C 30 1F 1F 2C 30 1F 1F | ? |
0 | 3 | 2C 30 1F 1F 2C 30 1F 1F | ? |
0 | 4 | 2C 30 1F 1F 2C 30 1F 1F | ? |
0 | 5 | 2C 30 1F 1F 2C 30 1F 1F | ? |
1 | 0 | 30 28 18 18 34 28 08 18 | ? |
1 | 1 | 30 28 18 18 30 28 08 18 | ? |
1 | 2 | 28 28 18 18 28 28 08 18 | ? |
1 | 3 | 28 28 18 18 28 28 08 18 | ? |
1 | 4 | 28 28 18 18 28 28 08 18 | ? |
1 | 5 | 28 28 18 18 28 28 08 18 | ? |
Power management
When register 0x11 has value one written to, a power cycle is done. When reg 0x70 val 1 is written before reg 0x11, sysmenu/launcher doesn't display the heath screen, otherwise when not written with the register value left at zero the health screen is displayed. Reg 0x70 would be zero on hard boot, when any twlsdk app does a system reset it writes value 1 to reg 0x70.
REGISTER | WIDTH | DESCRIPTION |
---|---|---|
0x0 | 1 | Unknown, battery related? Usually this reg val is 0x33? |
0x10 | 1 | Power flags. When bit0 is set, arm7 does a system reset. When bit1 or bit3 are set, arm7 does a shutdown. Bits 0-2 are used for DSi IRQ6 IF flags. |
0x11 | 1 | Power reg? Writing value 1 here does a system reset. Writing value 2 powers off all DSi-only hw. |
0x12 | 1 | Might be MMC bus power related, unknown. |
0x20 | 1 | Battery flags. When zero the battery is at critical level, arm7 does a shutdown. Bit7 is set when the battery is charging. Battery levels in the low 4-bits: battery icon bars full 0xF, 3 bars 0xB, 2 bars 0x7, one solid red bar 0x3, and one blinking red bar 0x1. When plugging in or removing recharge cord, this value increases/decreases between the real battery level and 0xF, thus the battery level while bit7 is set is useless. |
0x21 | 1 | ? |
0x31 | 1 | External camera LED control, valid values are 0-2. Value 0 disables the LED, value 1 activates the LED, value 2 activates the LED with the LED blinking. |
0x40 | 1 | Volume level: 0x00 - 0x1F. |
0x70 | 1 | BOOTFLG |
Device 0x90
REGISTER | WIDTH | DESCRIPTION |
---|---|---|
0x2 | 1 | Used for DSi IRQ6 IF flags. |
0x4 | 1 | Unknown (bit0 toggled) |