3DS reverse engineering

Discussion of development of software for any "obsolete" computer or video game system. See the WSdev wiki and ObscureDev wiki for more information on certain platforms.
profi200
Posts: 66
Joined: Fri May 10, 2019 4:48 am

Re: 3DS reverse engineering

Post by profi200 »

Regarding SHA:
I have tested DMA a good while ago and came to the conclusion it's double(!) as slow as copying the data with the CPU and that even doing only in FIFO DMA. I don't know why. I left the test code in: https://github.com/derrekr/fastboot3DS/ ... pto.c#L553
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Oh, I had misremembered that (I was thinking that it happened only on SHA_OUT readback, instead of SHA_IN).
Hmmm, there are various ways to DMA (via NDMA, XDMA, CDMA) and various ways to do CPU transfers...
I have tested ARM9 CPU and ARM9 NDMA, both just writing 64Kbytes of "filldata" to the SHA unit, without reading any source data from RAM:

Code: Select all

  SHA2xx  SHA1
  10000h  10000h  bytes transfer length...
  2213Ah  220E1h  clks when writing SHA blocks via ARM9 2x STMIA r0-r7
  112BFh  15781h  clks when writing SHA blocks via ARM9 NDMA fill mode
With that tests, NDMA is faster than CPU. Timings are measured in 67MHz units.
NDMA timings are about 1 cycle per byte for SHA256/SHA224, and about 1.25 cycles for SHA1.
Or more accurate: 1.07 clks and 1.34 clks, that would be 62Mbyte/s or 50Mbyte/s.

I don't know why CPU was faster for you. But here are some ideas...
- CPU could use data cache (if data is cached, or if PLD opcode was used, or if some kind of cache-read-ahead had occurred).
- CPU could read-ahead source data (before waiting for the FIFO full flag, at least if the code is programmed that way)
- NDMA might bug when reading from memory (unlike the NDMA-fill-mode that I had used)
- Without cache, main RAM may work faster if the source blocks are aligned to main RAM line size (I think it can then do burst reads)
- With cache it might be vice-versa (if the mis-alignment is causing cache-read-ahead)

For the NDMA, I have used 40h bytes as logical & physical block size. The FIFO full flag in SHA_CNT gets set after 40h bytes, too.
The SHA vs Source Data timings would have probably worked more smoothly if they had used a 80h-byte FIFO, with data request when FIFO is at least half-empty.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
profi200
Posts: 66
Joined: Fri May 10, 2019 4:48 am

Re: 3DS reverse engineering

Post by profi200 »

I did the test again and this time i used a 32 bit timer (prescaler 1, cascade), a big buffer (256 KiB) and made sure the ARM9 is waiting for IRQs instead of polling. ARM9 memory --> SHA. This time the result is different:

CPU: 459633 timer cycles
NDMA: 344354 timer cycles

The code on the CPU side is generated by gcc:

Code: Select all

.text:08004DBC ; void __fastcall SHA_update(const u32 *data, u32 size)
.text:08004DBC SHA_update                              ; CODE XREF: loadVerifyFirm+398↓p
.text:08004DBC                                         ; sdmmc_dnand_init_0+1B8↓p ...
.text:08004DBC data = R0                               ; const u32 *
.text:08004DBC size = R1                               ; u32
.text:08004DBC                 CMP     size, #0x3F
.text:08004DC0                 STMFD   SP!, {R4-R7,LR}
.text:08004DC4                 MOV     R7, size
.text:08004DC8                 MOV     R5, data
.text:08004DCC                 BLS     loc_8004E44
.text:08004DD0                 SUB     R6, size, #0x40
.text:08004DD4                 BIC     R6, R6, #0x3F
.text:08004DD8                 ADD     R6, R6, #0x40
.text:08004DDC                 LDR     R4, =0x1000A000
.text:08004DE0                 ADD     R6, data, R6
.text:08004DE4
.text:08004DE4 loc_8004DE4                             ; CODE XREF: SHA_update+64↓j
.text:08004DE4 data = R5                               ; const u32 *
.text:08004DE4                 MOV     LR, data
.text:08004DE8                 LDR     R12, =0x1000A080
.text:08004DEC                 LDMIA   LR!, {R0-R3}
.text:08004DF0                 STMIA   R12!, {R0-R3}
.text:08004DF4                 LDMIA   LR!, {R0-R3}
.text:08004DF8                 STMIA   R12!, {R0-R3}
.text:08004DFC                 LDMIA   LR!, {R0-R3}
.text:08004E00                 STMIA   R12!, {R0-R3}
.text:08004E04                 LDMIA   LR, {R0-R3}
.text:08004E08                 STMIA   R12, {R0-R3}
.text:08004E0C                 ADD     data, data, #0x40
.text:08004E10
.text:08004E10 loc_8004E10                             ; CODE XREF: SHA_update+5C↓j
.text:08004E10                 LDR     R3, [R4]
.text:08004E14                 TST     R3, #1
.text:08004E18                 BNE     loc_8004E10
.text:08004E1C                 CMP     data, R6
.text:08004E20                 BNE     loc_8004DE4
.text:08004E24                 AND     R7, R7, #0x3F
.text:08004E28                 CMP     R7, #0
.text:08004E2C                 LDMEQFD SP!, {R4-R7,PC}
.text:08004E30
.text:08004E30 loc_8004E30                             ; CODE XREF: SHA_update+94↓j
.text:08004E30                 MOV     R2, R7
.text:08004E34                 MOV     R1, R6
.text:08004E38                 LDMFD   SP!, {R4-R7,LR}
.text:08004E3C                 LDR     R0, =0x1000A080
.text:08004E40                 B       iomemcpy
.text:08004E44 ; ---------------------------------------------------------------------------
.text:08004E44
.text:08004E44 loc_8004E44                             ; CODE XREF: SHA_update+10↑j
.text:08004E44 data = R0                               ; const u32 *
.text:08004E44 size = R1                               ; u32
.text:08004E44                 CMP     R7, #0
.text:08004E48                 MOV     R6, data
.text:08004E4C                 LDMEQFD SP!, {R4-R7,PC}
.text:08004E50                 B       loc_8004E30
.text:08004E50 ; End of function SHA_update
.text:08004E50
.text:08004E50 ; ---------------------------------------------------------------------------
.text:08004E54 off_8004E54     DCD 0x1000A000          ; DATA XREF: SHA_update+20↑r
.text:08004E58 dword_8004E58   DCD 0x1000A080          ; DATA XREF: SHA_update+2C↑r
.text:08004E58                                         ; SHA_update+80↑r
The code is not the best it could be but i think that is plenty fast.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Time for Battery/Power related stuff...

First of, while messing with the battery pins, I've blown the fuse near the external supply connector, and melted the 4pin coils next to it. After removing/briding that components... the damn thing does still work... destroying the power supply would have been a good excuse to get rid of the half-broken console : /

---

Anyways, some other/older battery related problems are:

1) Some months ago I noticed that the battery does fully discharge after about 10 hours - even when the console is switched off (unless the charger is connected). In the discharged state, it won't even power-on for a brief moment (until/unless connecting the charger). Is that a known problem? I don't know if it might be a bug in my power-off function, somehow leaving the console in half powered state.

2) Some months later the console stopped working completely without charger connected, it powers down instantly when removing the charger, and won't power-on without charger. With charger, the orange charger LED never goes off, and the power LED is always red (when switched on). It behaves as if the battery is completely "empty". But despite of that, the battery does have 3.7 volts, so it seems to be quite well charged.

---

Measuring Amperes on the charger input, I see...
About 50mA when switched on.
About 17mA anytime else (when switched off, even when switched-off with battery removed).
I guess the 17mA might be because it is trying to charge the battery (or maybe Nintendo does always draw 17mA even if the battery is full?)
The 17mA don't seem to be related to my power-off function (they are drawn even after a "hard power-down" ie. after temporarily removing both charger+battery).

---

For the fuel gauge, I've searched for device 6Ch and fuel gauge... that looks like being a MAX17xxx chip... the Old3DS does have an 8pin chip marked "17040", so it's apparently a MAX17040.
The MCU in New3DS does also contain code for device 6Ch... but I haven't spotted a "17040" chip or anything similar on the New3DS mainboard, so I don't know if or where that chip does exist in New3DS (or maybe it is the 6pin chip... with marking "9D" or "06" or so).
The MCU code reads from MAX17040 registers 02h:03h (VCELL voltage as 12bit value) , 04h:05h (SOC StateOfCharge as 16bit value in percent/256), and 08h:09h (VERSION with undocumented value; returned in byte [03h,04h] of MCU command 7Fh).

---

And a general thing about DSi/New3DS batteries... I would love to know how to use the consoles without battery - but they refuse to work when attaching only the external supply without battery.
Both DSi and New3DS have 3pin batteries, BT+, BT-, and some unknown "middle pin", which migt be a resistor, thermistor, or 1-wire bus?

- On DSi, the middle pin is called "DET", and it seems to have no connection to BT- (and connects to PowerMan chip).
- On New3DS, there's no name/text layer, and it seems to have 0 ohm resistance to BT- (and connects wherever).

Hmmm, that looks as if the middle pins have different functions in DSi and New3DS.

For the thermistor theory:
The DSi seems to have a thermistor on the PCB (close to the battery, but NOT INSIDE of the battery... unless there are two different thermistors).
The datasheet for the New3DS charger chip BQ24072 suggests a thermistor on the TS pin (which, too, might be on the PCB... or in the battery).

That BQ24072 datasheet does also say that one could disable battery detection via TD pin (or SYSOFF pin in other BQ2407x chips). I haven't yet checked how far that pin could be rewired on the PCB, but it might require to change tiny wires underneath of the chip.
Other than that, one could probably fool it by replacing the battery with a large capacitor on BT+ and BT- (and whatever on the middle pin... if it's a digital 1-wire signal (?) then it might require something alike a CIC-clone).

Did anybody ever manage to power those consoles without battery?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: 3DS reverse engineering

Post by lidnariq »

nocash wrote: Thu Jan 09, 2020 11:46 pm 1) Some months ago I noticed that the battery does fully discharge after about 10 hours - even when the console is switched off (unless the charger is connected).
In isolation, it's hard to say whether this a mistake on your part or just a end-of-life battery ... but your other comments strongly imply this is an almost-dead battery. Not only does LiIon/LiPoly capacity decrease drastically at end of life, but its self-discharge rate also seems to increase.
In the discharged state, it won't even power-on for a brief moment (until/unless connecting the charger). Is that a known problem?
I've seen this behavior in a lot of other devices that use LiPoly cells.
But despite of that, the battery does have 3.7 volts, so it seems to be quite well charged.
A LiIon/LiPoly cell that's reading 3.7V doesn't have much power left in it.

The voltage read off a LiIon/LiPoly cell starts showing hysteresis as it wears down, where some increasing amount of voltage swing is unrelated to actual remaining capacity. (For example, removing it from the charger and it will immediately drop from 4.2V to 3.9V, then if it discharges to 3.7V and it's plugged back in it immediately starts reading 4.0V)
some unknown "middle pin", which migt be a resistor, thermistor, or 1-wire bus?
Thermistor is extremely likely. Most have a "room temperature" resistance somewhere around 10-50kΩ, and most often between battery- and the extra pin.
Did anybody ever manage to power those consoles without battery?
I only have a GBASP and a old DS, but they don't work without the battery. Not even putting in a capacitor in lieu works.

I have managed to power the GBASP using a bench power supply providing 4V via the battery terminals ... but it does only has two pins on its battery.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Just checked again... the New3DS Xl battery is Li-Ion 1750mAh 3.7V (not 4.2V)... and I am measuring 3.6V on the battery contacts (on the raw/removed battery, and same voltage also when charging, with console being either powered on or off)).
Does that sound charged, or did you mean that it should exceed 3.7V, despite of the battery sticker saying 3.7V?

In the DSi, I have a "normal" worn out battery, causing the console to switch off after 5 minutes. I think that is a normal wear-out effect.

But the New3DS does switch off after 0.000 seconds. I think that is a bit too rapid, even if the battery would be worn out (which I am not even sure about... not so long ago it did still last several hours (even when switched on)... and then the lifetime suddenly dropped from hours to microseconds. Maybe there's a damaged component on PCB, or the battery is heavily damaged (exceeding normal wear-out effects).

Yes, I have read about Thermistors in 10kOhm range, I am just not measuring anything remotely close to 10kOhm on the Nintendo batteries (and as said before, the DSi does have the thermistor with name "TH" on the button/battery PCB (above the battery)).

Some batteries are reportedly merely having a resistor on the 3rd pin (with different resistor values for different battery capacities). And some do reportedly have a 1-wire bus (though those might also have a built-in fuel gauge... which is apparently not the case here, as the MCU is accessing an I2C bus fuel gauge).
For the New3DS battery, I think the 3rd pin is simply shortcut to BT- inside of the battery (I measure 0 ohm between that battery pins, and the console pin has 0 volt when battery is attached, and 1.3V when removing the battery) (but then, my battery might be damaged).

I've meanwhile found a few more fuel gauge I2C register accesses in the MCU firmware, that makes it look as if the New3DS has something newer than MAX17040... either a newer MAXnnnn chip... or something compatible... like Richtek RT9428 (that has a few more registers, but the MCU uses even more than that).

Code: Select all

  index__________;MAX17040______________;Richtek RT9428___
  02h        R   ;VCELL, voltage        ;VBAT
  04h        R   ;SOC, StateOfCharge    ;SOC
  04h.byte   R   ;SOC.msb               ;SOC.msb
  06h        W   ;MODE                  ;CONTROL
  08h.byte   R   ;VERSION.msb?          ;DEVICE ID.msb
  08h        R   ;VERSION               ;DEVICE ID
  0Ah        -   ;-                     ;Status, dSOC
  0Ch        R/W ;RCOMP                 ;CONFIG
  0Eh        R/W ;???                   ;OCV
  3Eh        W   ;???                   ;???
  40h+N      W   ;???                   ;???
  80h+N      W   ;???                   ;???
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
profi200
Posts: 66
Joined: Fri May 10, 2019 4:48 am

Re: 3DS reverse engineering

Post by profi200 »

nocash wrote: Thu Jan 09, 2020 11:46 pm 1) Some months ago I noticed that the battery does fully discharge after about 10 hours - even when the console is switched off (unless the charger is connected). In the discharged state, it won't even power-on for a brief moment (until/unless connecting the charger). Is that a known problem? I don't know if it might be a bug in my power-off function, somehow leaving the console in half powered state.
Definitely not normal. Fully powered off it can survive months without charge.

That reminds me that wifiboot fucks up the MCU watchdog timer. HOS doesn't reset it to normal. This is bad and here is why:
If you have to force shutdown the system it doesn't have enough time to finish writes/close file handles. This can and will lead to data corruption! There is a full blown OS running and you need to give it time to properly shutdown. You would not turn off your PC by cutting power while it's on either (unless it hung so badly nothing else works).
nocash wrote: Thu Jan 09, 2020 11:46 pm And a general thing about DSi/New3DS batteries... I would love to know how to use the consoles without battery - but they refuse to work when attaching only the external supply without battery.
Both DSi and New3DS have 3pin batteries, BT+, BT-, and some unknown "middle pin", which migt be a resistor, thermistor, or 1-wire bus?

[...]

Did anybody ever manage to power those consoles without battery?
You can test for a thermistor by wiring it up and carefully heating the battery with a hair dryer. Don't heat it up higher than about 50*C or you will get a fire. If they catch on fire they go really nuclear and you can only watch it burn (water will make it even worse).

You can try either powering it from the battery side or try to simulate a charging battery with a resistor. I don't know where i read that but someone had success with a resistor.

nocash wrote: Fri Jan 10, 2020 1:45 am Just checked again... the New3DS Xl battery is Li-Ion 1750mAh 3.7V (not 4.2V)... and I am measuring 3.6V on the battery contacts (on the raw/removed battery, and same voltage also when charging, with console being either powered on or off)).
Does that sound charged, or did you mean that it should exceed 3.7V, despite of the battery sticker saying 3.7V?
This is not the the maximum voltage. Every battery in existence is measured in nominal voltage. LiIon usually is in the range of 2.5-4.2V (LiPo has a higher discharge cutoff voltage if i recall correctly). Going below 3V will hurt cycle life a lot and will give you barely any more juice.
nocash wrote: Thu Jan 09, 2020 11:46 pm In the DSi, I have a "normal" worn out battery, causing the console to switch off after 5 minutes. I think that is a normal wear-out effect.
If they are that worn out you should get rid of them since there is a higher risk of fires with very worn out batteries. If any of them is swollen get rid of them immediately because they don't swell for no reason. Something is wrong with them and continued usage is risky.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: 3DS reverse engineering

Post by lidnariq »

nocash wrote: Fri Jan 10, 2020 1:45 am Just checked again... the New3DS Xl battery is Li-Ion 1750mAh 3.7V (not 4.2V)... and I am measuring 3.6V on the battery contacts (on the raw/removed battery, and same voltage also when charging, with console being either powered on or off)).
Does that sound charged, or did you mean that it should exceed 3.7V, despite of the battery sticker saying 3.7V?
Very empty.

LiIon/LiPoly discharge curves look like this: https://i.stack.imgur.com/LV91V.gif
(where "C" is the proportion of current drawn relative to the battery's capacity, units of (1/Hr))

LiIon can safely go up to not more than 4.25V, and most of the useful battery charge on a new cell is in the range of 4V to about 3.7V.

(Non-rechargable lithium coin cells have an even flatter discharge curve)
But the New3DS does switch off after 0.000 seconds. I think that is a bit too rapid, even if the battery would be worn out (which I am not even sure about... not so long ago it did still last several hours (even when switched on)... and then the lifetime suddenly dropped from hours to microseconds. Maybe there's a damaged component on PCB, or the battery is heavily damaged (exceeding normal wear-out effects).
That sounds like the battery's protection circuitry has disconnected the cell from the contacts, and it's effectively a battery-shaped box now.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

lidnariq wrote: Fri Jan 10, 2020 11:22 am Very empty. LiIon/LiPoly discharge curves look like this: https://i.stack.imgur.com/LV91V.gif
profi200 wrote: Fri Jan 10, 2020 7:24 am Definitely not normal. Fully powered off it can survive months without charge.
Thanks. Okay, if 3.6V is empty, and if it isn't caused by known software issues... I've now checked the fuse on the back side of the battery board... and that was blown... I've fixed that, and it does now power-on without charger... and it's now also actually charging with charger.
I guess I must have short-cut the battery contacts when messing with the PCB with charger still plugged in, and didn't notice the problem until some weeks/months later because it was still partially working (with charger, and maybe also without charger when the battery was still full).
profi200 wrote: Fri Jan 10, 2020 7:24 am That reminds me that wifiboot fucks up the MCU watchdog timer. HOS doesn't reset it to normal. This is bad and here is why:
If you have to force shutdown the system it doesn't have enough time to finish writes/close file handles. This can and will lead to data corruption! There is a full blown OS running and you need to give it time to properly shutdown. You would not turn off your PC by cutting power while it's on either (unless it hung so badly nothing else works).
The forced-power-off-delay in MCU[24h]? I don't know why they have called it watchdog on 3dbrew. But yeah, I have considered OS timings issues:

Code: Select all

  - Normal-power-off timings are TapButton(0.1s) + Wait until power-down has completed.
  - Forced-power-off timings are HoldButton(3s) + Wait(7s). With MCU[24h] allowing to change/remove the 7s delay.
If the user does hold the button for 3 seconds then I would consider that at as a "hung so badly nothing else works" case, and then the extra 7 second delay would be pointless... or could you think of scenarios where it is needed?

I think that it's quite essential to disable that delay (especially if you are developing code that does occassionally hang during testing).
But I could "restore" the setting in wifiboot before starting the uploaded file... the MCU[24h] setting seems to be battery-backed, that's making it difficult to restore the "old" setting (especially if a crash had occurred)... the only other way would be to restore the hardcoded default setting.
profi200 wrote: Fri Jan 10, 2020 7:24 am You can try either powering it from the battery side or try to simulate a charging battery with a resistor. I don't know where i read that but someone had success with a resistor.
But where? I guess a resistor between external supply+ and battery+ might work?
It might even work when shorting that pins with 0 ohms, but then the battery+ would have 4.6V (or even 5V or whatever is connected externally), I don't know if that could damage anything... probably it would work fine, assuming that the voltage regulators would still pass the correct voltages to the mainboard.

---

I think I have located the fuel gauge chip on the New3DS XL battery board (the tiny 8pin bga chip right of the select button; it's very tiny, a good bit smaller than many SMD resistors). There is also some tinier-than-tiny text on it. I've tried to identify some letters using a led-torch, a camera, and a magnifying glass while balancing the pcb on my knees... with that DIY microscope... I can see lots of dust and deep scratches on the gold contacts... and something like "7048" (?) in upper line of chip name.
If that's right then it might stand for MAX17048, but the datasheet doesn't fully match up with the MCU code (on the other hand, the MCU code seems to detect at least two different fuel gauge chip versions).

Anyways, all datasheets are clear about the version/percentage/voltage registers... which are forwarded to the following MCU registers:

Code: Select all

  0Bh     Fuel Gauge Battery Percentage, msb (percent, 0..64h)
  0Ch     Fuel Gauge Battery Percentage, lsb (percent/256, 0..FFh)
  0Dh     Fuel Gauge Battery Voltage (in 20mV units)
  7Fh     ArrayEntry[03h]: Fuel Gauge Version.msb
  7Fh     ArrayEntry[04h]: Fuel Gauge Version.lsb
New details are the battery "percentage/256" fraction, and the "20mV" unit for the battery voltage.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

The battery charging is still bad. It takes endless to reach 100%, still consumes 0.15A when switched off with battery at 100%, and tends to discharge overnight to 0% when switched off, without charger attached (I've tried to power-off from within wifiboot, and fastboot, and it's both 0.15A).
So, well, I guess the battery is dead... or maybe there's another bent pin in one of the ribbon cable connectors causing a shortcut. It's probably unfixable without buying new hardware components.
I could leave it as is, or maybe I'll try to get it powered without battery alltogether.

---

Looking at my MCU disassembly, I am afraid that I have just found a nasty problem with RL78 "short addresses" (eg. opcode 8Dh: MOV A,saddr):

Code: Select all

 currently, I have that disassembled as so:
    00h..FFh --> FE20h..FF1Fh  ;datasheet suggests that it works that way
 but, at closer look, it might rather work as so:
    00h..1Fh --> FF00h..FF1Fh  ;top bytes
    20h..FFh --> FE20h..FEFFh  ;bottom bytes
Or in other words, to disassemble opcode 8D 1F:

Code: Select all

    8D 1F  -->  mov a,[0FFE3Fh]   ;read ADC result from RAM, which seems to be wrong : /
    8D 1F  -->  mov a,[0FFF1Fh]   ;read ADC result from the A/D converter's SFR register
I guess the latter is right?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

The RL78 short address disassembly was in fact wrong, my MCU disassembly is about 10000 lines, and it did have about 500 mistakes with wrong addresses : /

I got it repaired by spending 3-4 days on carefully using search/replace to fix the addresses (the RAM addresses were relative easy (but needed caution for replacing only 8bit addresses, not 16bit addresses), but replacing RAM by SFRs (and vice-versa) needed some more caution).
The funny thing is that I didn't notice the error earlier in past some months, but it didn't really matter for RAM, and for the SFRs it did just make them look like being RAM flags (now I know that those flags are actually direct reads/writes to the GPIO port bits).
Here's a summary of the GPIO Port bits (and ADC inputs, and I2C data registers):

Code: Select all

[MCU_SFR_P0].0    ;related to POW[xxh] ?
[MCU_SFR_P0].1    ;reset (/RES)        ?
[MCU_SFR_P0].2-7  ;unused
;---
[MCU_SFR_P1].0-6  ;unused
[MCU_SFR_P1].6    ;power for ADC(9)?   ;\somewhat power for ADC(8,9) pull-up?
[MCU_SFR_P1].7    ;power for ADC(8)?   ;/
;---
[MCU_SFR_P2].0    ;home.button?
[MCU_SFR_P2].1-2  ;unused
[MCU_SFR_P2].3    ;?  cleared
[MCU_SFR_P2].4    ;?  charge
[MCU_SFR_P2].5    ;?  cleared
[MCU_SFR_P2].6-7  ;unused
;---
[MCU_SFR_P3].0    ;?
[MCU_SFR_P3].1-3  ;fixed (all bits set)
[MCU_SFR_P3].4-7  ;unused
;---
[MCU_SFR_P4].0-1  ;?      extra info alike system model?
[MCU_SFR_P4].2    ;power led color (0=blue, 1=red)
[MCU_SFR_P4].3    ;... maybe charger led? (or ENABLE charging?) (when charger connected, and temperature good)
[MCU_SFR_P4].4-7  ;unused
;---
[MCU_SFR_P5].0    ;?  related to POW[xxh]
[MCU_SFR_P5].1    ;charger busy
[MCU_SFR_P5].2    ;unused
[MCU_SFR_P5].3    ;fixed (set)
[MCU_SFR_P5].4-7  ;unused
;---
[MCU_SFR_P6].0-1  ;cleared on init (maybe i2c_bus0 dta/clk?)
[MCU_SFR_P6].2-7  ;unused
;---
[MCU_SFR_P7].0    ;charger_plugged  (R)
[MCU_SFR_P7].1    ;hinge/magnet     (R)
[MCU_SFR_P7].2    ;request TSC[10h] (R)
[MCU_SFR_P7].3    ...pwr.button?    (R)
[MCU_SFR_P7].4    ;..wifi.button?   (R/W?)
[MCU_SFR_P7].5    ;camera led (0=off, 1=on)
[MCU_SFR_P7].6    ;... irq.signal.out (and irq.ack.in?)
[MCU_SFR_P7].7    ;... irq-like state-change short strobe?
;---
[MCU_SFR_P8].0-7  ;unused
[MCU_SFR_P9].0-7  ;unused
[MCU_SFR_P10].0-7 ;unused
[MCU_SFR_P11].0-7 ;unused
;---
[MCU_SFR_P12].0   ;?      (R)
[MCU_SFR_P12].1-2 ;System Model (0,1,2,3 = Model 0,4,2,3)
[MCU_SFR_P12].3-7 ;unused
;---
[MCU_SFR_P13].0-7 ;unused
;---
[MCU_SFR_P14].0-1 ;?  (both bits set, or both cleared)
[MCU_SFR_P14].2-7 ;unused
;---
[MCU_SFR_P15].0-7 ;unused
;---
;Port X...
[MCU_SFR_?F0510].0-1  ;maybe i2c_bus1 dta/clk?  ;alike "Port data 6" for other I2C bus
[MCU_SFR_?F0510].2    ;video "push" on (except, unused on original old 3ds)
[MCU_SFR_?F0510].3    ;fixed (cleared)
[MCU_SFR_?F0510].4    ;alternate home button ???
[MCU_SFR_?F0510].5    ;pedometer related ?
[MCU_SFR_?F0510].6-7  ;unused
;---
ADC(6)          ;3d_slider     (raw NNh)
ADC(7)          ;volume_slider (raw NNh, or reverse 0FFh-NNh)
ADC(8)          ;battery pcb temperature [mcu_info_06h], and xlated to [mcu_reg_0Ah_battery_temp_celsius]
ADC(9)          ;xlated to 0..7 then stored in [mcu_info_02h]
;---
[MCU_SFR_IICA0]   ;I2C bus data for DSi/BPTWL
[MCU_SFR_IICA1]   ;I2C bus data for 3DS/MCU
[MCU_SFR_SDR02]   ;I2C bus data for slave devices (accel, fuel, tsc, powerman)
I have meanwhile got the New3DS-XL console power without battery (and without charger), by injecting the supply directly to BT+/- pins.
For BT+, I've passed 5VDC through two 1N4004 diodes to lower the voltage a bit... though that is getting a bit too low: The power/notify LEDs are blinking red, and the console occassionally goes off after some seconds; until it has warmed up when touching the backlight cable, and the two diodes are getting quite hot (maybe the console tries to draw more current to compensate too low voltage?). Not tested yet, but it does probably work better with only 1 diode (or perhaps without any diodes).

Battery middle pin... the battery does have it GNDed, but the console does also work fine if it is left floating, I've also tried to wire via 10Kohm and 2Mohm potentiometers to GND with different settings, but that didn't seem to have any effect either.
The middle pin signal is forwarded from battery board to a test point on mainboard (near the battery pcb connector), but I don't know where it goes from there (my best guess would be to MCU chip).
The MCU does read something related to battery/fuel/charger from the ADC(9) input (upon initial power-up and wake-up), that ADC value is translated to a "battery type" number in range 0..6 (or 7=invalid), and can be then read via MCU[7Fh:02h]... which seems to be always 00h (even with floating middle pin or with potentiometers). Hmmmm, I am still thinking that the middle pin "should" go to that ADC(9) input, but maybe it doesn't work because they didn't install a pull-up resistor... or maybe I am just wrong there.
Whatever ADC(9) is good for... the two known things are that it affects MCU[7Fh:02h]=0..7, and the fuel gauge calibration is changed if MCU[7Fh:02h]>=4. The fuel gauge MAX17048 datasheet recommends to change the calibration based on battery chemistry and temperature.

Battery temperature is measured via ADC(8) input, the raw ADC value can be read via MCU[7Fh:06h], and the value converted to degrees Celsius can be read from MCU[0Ah] (the value is about 5-6'C degrees too high, ie. even the "cold" state is higher than room temperature). The MCU firmware uses the temperature to calibrate the fuel gauge's RCOMP value, and apparently to disable battery-charging when the temperature is too cold, or to hot.
The temperature sensor is somewhere in the console (not in the battery; it's working even with battery removed), presumably somewhere above the battery... there are a bunch of "resistors/capacitors" on the battery PCB, one of them is probably actually a thermistor.

Battery discharging while powered off... that does still happen to me. When removing the battery it does drop to 93% after some days (that might be more or less okay?). When keeping the battery inserted it drops to 0% after about 10 hours (although it shouldn't do much more than powering the real-clock when switched off).
I am still unsure if that is a hardware issue, or if I am missing something in my power-down function... that is, I am setting MCU[20h]=01h, followed by entering an endless loop.
Fastboot seems to execute a WFI opcode (wait for interrupt) instead of the endless loop, but I don't know if that is really needed (and with which/any IRQs enabled, on which/all CPU cores)?
Well, and I didn't disable backlights before writing MCU[20h]=01h, but they seem to go off anyways.
Apart from the RTC, some of my test code might have the accelerometer kept powered on, but even if so, that shouldn't drain the battery too much.
And lastly, as I am booting via wifi, maybe the wifi hardware is kept powered-on after MCU[20h]=01h?
Last edited by nocash on Tue Jan 21, 2020 11:03 pm, edited 5 times in total.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: 3DS reverse engineering

Post by lidnariq »

nocash wrote: Tue Jan 21, 2020 12:38 pm For BT+, I've passed 5VDC through two 1N4004 diodes to lower the voltage a bit... though that is getting a bit too low: The power/notify LEDs are blinking red, and the console occassionally goes off after some seconds; until it has warmed up, and the two diodes are getting quite hot (maybe the console tries to draw more current to compensate too low voltage?). Not tested yet, but it does probably work better with only 1 diode (or perhaps without any diodes).
Yeah, almost all even-vaguely modern power supplies emit approximately the same amount of power in as out, instead of the lossy output stage of a linear regulator (where current in ≈ current out).

1N400x family are a good choice here, because they have very high forward voltages. If the 3DS typically consumes somewhere around 300mA-500mA, then Vf of the diode should be around 0.83-0.87V ... so, yes, two in series will yield a voltage that's close to an almost-empty LiIon cell. (And one by itself is close to "almost full LiIon cell").

The only thing to be careful about is what the voltage is when the 3DS is off.

Half a watt through each diode should be somewhere around a 25°C rise above ambient... not clear if that counts as "quite" hot?
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Quite hot like 50'C or a bit more. It doesn't cause burns on my fingers, but it's ways above just 25'C.
Well, yes, that might be room temperature 18'C plus 25'C... but it feels a bit hotter than that.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: 3DS reverse engineering

Post by tepples »

Would it help to put the two diodes in parallel? I imagine that way they'd at least give the same voltage drop, but half the current would be passing through each.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: 3DS reverse engineering

Post by lidnariq »

It'd let them run cooler, yes, as long as they're far enough away from each other. They'll heat each other if they're right on top of each other. (Two adjacent diodes still can handle more heat dissipation than a single diode.)

I'm just spitballing this as 0.85V × 0.5A = 0.42W, times the thermal resistance given in the 1N400x datasheet of somewhere around 50K/W

The "right" solution is a real voltage regulator that would let you take 5V in and emit something in the 4.2V-3.0V range. Higher's better, because the subsequent power conversion in the 3DS will draw less current for a given power demand, and also the voltage dropped and so dissipated as heat will be lower. Unfortunately, that's small enough headroom that you'll need some kind of "low drop-out" regulator.
Post Reply