gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Powering up on RTC irq?

#157134 - Maxxie - Mon May 19, 2008 6:41 pm

Heya,

We know there is that rtc installed in the DS, it is active even when the DS is turned off, and can trigger an IRQ at a specific time.

My question: can the IRQ wake up (as in enabling power again) the DS?

I know how to put the DS in power saving mode (arm7 halt swi, cp15 halt on arm9 and perpherival unpowering) so that any enabled IRQ can awake it from there, but i'd really like to completely shut it off (via spi controlled power register) and have it go live with the health warning & such when the alarm time approaches.

#157142 - simonjhall - Mon May 19, 2008 7:40 pm

I doubt it. Otherwise wouldn't Nintendo have done this for the alarm clock program that comes on the DS?
(I was never too sure with that alarm clock as to whether you could turn it off or not...I wonder how many people turned it off and didn't wake when they should have!)
_________________
Big thanks to everyone who donated for Quake2

#157149 - Maxxie - Mon May 19, 2008 8:03 pm

Yes, that is what i tested today and was disappointed by it. It is such a waste.

I think i have seen a picture of the mainboard with the int line of the rtc marked. It would have been down to a single transistor to short the power button on the interrupt.

Too bad.

#157198 - HyperHacker - Tue May 20, 2008 8:40 am

Well, anyone feel like doing such a mod and seeing how well it works?
_________________
I'm a PSP hacker now, but I still <3 DS.

#157227 - Cydrak - Tue May 20, 2008 7:10 pm

This is a nice idea, though I see a couple issues, if you mean to blindly fake the button press.

First, it'd break existing alarms. The firmware leaves the power on, so poking the switch then turns the DS off, exactly the opposite of what was intended.

But worse, there are periodic settings. Imagine if, by malice or mistake, the chip was left cycling 2Hz... (the NES crowd should be groaning any second now :-)

I think you'd just need a bit to allow the power toggle, which is cleared afterward (and by a real power cycle, as well). That way it isn't triggered unaware, and avoids the undesirable 80's flashbacks.

#157268 - sverx - Wed May 21, 2008 2:54 pm

Maxxie wrote:
I know how to put the DS in power saving mode (arm7 halt swi, cp15 halt on arm9 and perpherival unpowering)


going on with that topic... I'm trying to understand how to halt arm9... I've read about cp15 on GBATek but I don't know how I could code that request. Any example?

Thanks :)

#157270 - Maxxie - Wed May 21, 2008 3:24 pm

The easy way is to call swiWaitForIRQ - (SWI 0x06)

It will call the cp15 to enter power saving mode for the arm9.

You have to make sure that IME is enabled, and the IRQ you wish to break the sleep is set up.

#157271 - sverx - Wed May 21, 2008 3:28 pm

Maxxie wrote:
The easy way is to call swiWaitForIRQ - (SWI 0x06)

It will call the cp15 to enter power saving mode for the arm9.

You have to make sure that IME is enabled, and the IRQ you wish to break the sleep is set up.


You were so fast that I didn't had time to come back here and say "Wait, maybe I've found... there's that swiWaitForIRQ()..."

Thanks! :)

Ciao :)

#157272 - sverx - Wed May 21, 2008 3:38 pm

one last thing... besides ARM7, ARM9, sound amplifier, LCDs (wifi already off)... what else can I turn off to save as much battery as possible?

Thanks :)

#157273 - eKid - Wed May 21, 2008 3:42 pm

There's also another SWI to wait for certain interrupts, swiIntrWait (0x04). It lets you specify a bitmask for certain interrupts to wait for.... and one other parameter that means 'wait for a new interrupt', or 'dont wait if one already happened'
And the one that is used most often is swiWaitForVBlank (0x05) which waits for the vblank irq.

#157275 - eKid - Wed May 21, 2008 3:46 pm

sverx wrote:
one last thing... besides ARM7, ARM9, sound amplifier, LCDs (wifi already off)... what else can I turn off to save as much battery as possible?

Thanks :)

Did you catch REG_POWCNT1? (controlled by libnds powerON, powerOFF) It can toggle power to the 2d and 3d graphic engines

#157276 - Maxxie - Wed May 21, 2008 3:48 pm

Everything else in the power control registers:
The graphic cores A, B 3d renderer and geometry and the speakers.

If you can backup the mainram on disk or can rebuild the data (i.e. by having a save/load routine in shared ram or vram), you can even shut down main ram ( http://nocash.emubase.de/gbatek.htm#dsmainmemorycontrol )

#157277 - Maxxie - Wed May 21, 2008 4:40 pm

For the ST Type of memory deep power down would be

LDRH R0,[27FFFFEh]
STRH R0,[27FFFFEh]
STRH R0,[27FFFFEh]
STRH 0000h,[27FFFFEh]
STRH 0003h,[27FFFFEh]
LDRH R0,[27FFFFEh]

( http://www.st.com/stonline/products/literature/od/9866/m69aw048b.pdf )

#157390 - sverx - Fri May 23, 2008 11:44 am

Thanks everybody :) I think I won't turn off the memory but everything else of course I will...

Ciao! :D

#157642 - sverx - Tue May 27, 2008 4:52 pm

I'm having problems :| ...

I have IRQ_VBLANK,IRQ_IPC_SYNC and IRQ_LID active on ARM9, and I want to put the processor to sleep. It seems to me it goes to sleep, but in both cases: if I do like this
Code:
irqDisable(IRQ_VBLANK);
swiWaitForIRQ();
irqEnable(IRQ_VBLANK);

_or_ if I do like this
Code:
swiIntrWait (1,IRQ_IPC_SYNC|IRQ_LID)

then the ARM9 doesn't wake up when opening the lid :|

Any ideas?

#157647 - Maxxie - Tue May 27, 2008 5:24 pm

The LID-irq is arm7 only
http://nocash.emubase.de/gbatek.htm#dsinterrupts

#157649 - sverx - Tue May 27, 2008 5:38 pm

Maxxie wrote:
The LID-irq is arm7 only
http://nocash.emubase.de/gbatek.htm#dsinterrupts


yes, you're right, sorry. I've been mixing up...

anyway on ARM7 I get the LID IRQ and I signal the ARM9 thru IPC that the DS has been unfolded. So I could use

Code:
swiIntrWait (1,IRQ_IPC_SYNC)


but it doesn't wake up :|

#157655 - Maxxie - Tue May 27, 2008 5:57 pm

Are you sure, that the ipc sync irq us enabled on the arm9 and in the arm9 ipc sync control register?

The following (irq's are set up beforehand) works for me like a charm

arm9:
Code:

if (keysDown() & KEY_LID)
{
   u32 oldIE = REG_IE ;
   REG_IE = IRQ_IPC_SYNC ;
   engine->Powersave(true) ;
   powerOFF(0x2E) ;
   swiWaitForIRQ() ;
   powerON(0x22) ;
   REG_IE = oldIE ;
}


with Powersave:
Code:

void ENGINE::Powersave(bool en)
{
   if (en)
   {
      if (keysHeld() & KEY_LID)
      {
         ipCom->SendCommand(CMD_PowersaveLid) ;
      } else
      {
         ipCom->SendCommand(CMD_Powersave) ;
      }
   } else
   {
      // signal the arm7 to awake again
      REG_IPC_SYNC |= IPC_SYNC_IRQ_REQUEST ;
   }
}


arm7:
Code:

void IPC_CMD_Powersave(u32 data, IPCOM *com)
{
   powerOFF(POWER_SOUND | POWER_WIFI) ;
   writePowerManagement(0,0x10) ;       // slow blinking power led
   writePowerManagement(1,0) ;       // green power led
   
   irqSet(IRQ_LID,&LidIRQ) ;
   
   u32 oldIE = REG_IE ;
   REG_IE = IRQ_IPC_SYNC | ((data & 1)?IRQ_LID:0) ;
   
   /* we will wait for either the lid beeing open again or signal from arm9 */
   swiSleep() ;
   
   REG_IE = oldIE ;
   
   writePowerManagement(0,0x0F) ;      // enable backlight, fulltime led and sound amp
   powerON(POWER_SOUND | POWER_WIFI) ;
   
   /* enable arm9 again if it was asleep itself */
   REG_IPC_SYNC |= IPC_SYNC_IRQ_REQUEST ;
}

#157658 - sverx - Tue May 27, 2008 6:10 pm

Maxxie wrote:
Are you sure, that the ipc sync irq us enabled on the arm9 and in the arm9 ipc sync control register?


I did that:
Code:
FIFOInit();
irqEnable(IRQ_IPC_SYNC);


the FIFOInit() is that:
Code:
//  turn on/clear send FIFO
void FIFOInit(void) {
  REG_IPC_FIFO_CR = (IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR);
}


any ideas? Anyway in the while I'll check your code... thanks! :)

#157660 - Maxxie - Tue May 27, 2008 6:14 pm

I think you forgot REG_IPC_SYNC |= IPC_SYNC_IRQ_ENABLE ;

#157662 - sverx - Tue May 27, 2008 6:29 pm

Maxxie wrote:
I think you forgot REG_IPC_SYNC |= IPC_SYNC_IRQ_ENABLE ;


wrong, wrong, wrong... it's not that I forgot, it's that I never knew about that REG_IPC_SYNC before!!!

Thanks a lot... it doesn't work anyway but I'll be checking my code better once more now...

See you :)

Ciao :)

#157739 - sverx - Wed May 28, 2008 10:23 am

Something's still missing...

Now I changed FIFOInit() so that I set REG_IPC_SYNC (and also activating IPC_FIFO_RECV_IRQ on REG_IPC_FIFO_CR that of course was forgotten...)

Code:
void FIFOInit(void) {
  REG_IPC_SYNC = (IPC_SYNC_IRQ_ENABLE | IPC_SYNC_IRQ_REQUEST);
  REG_IPC_FIFO_CR = (IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR | IPC_FIFO_RECV_IRQ);
}


and then, in the ARM9, when it's time to sleep I do that:

Code:
u32 oldIE = REG_IE;
REG_IE = IRQ_IPC_SYNC;
swiWaitForIRQ();
REG_IE = oldIE;


unfortunaly it never gets waken up. But on the ARM7 I receive the IRQ_LID and I send the ARM9 -thru IPC- the signal... I'm sure that part works because if I remove the line
Code:
swiWaitForIRQ();

it works, it tells me 'I was sleeping...', than means the signal from ARM7 has been received.

Going to study a bit deeper... :| Any help is, obviously, welcome ;)

#157741 - silent_code - Wed May 28, 2008 10:54 am

just a little side note: make sure you don't play any audio for about 15ms after powering up the sound hardware. :^)
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#157744 - Maxxie - Wed May 28, 2008 11:58 am

silent_code wrote:
just a little side note: make sure you don't play any audio for about 15ms after powering up the sound hardware. :^)


Actually i am not having any problems with this at all.
I'm setting power off to amp and sound hardware _while_ it is still playing a ringbuffer (in Repeat mode), and it continues to play it when returning. And the remaining sync between feeder and sound playing states that there is no long (10+ms) delay there.

I can however imagine, that for a proper state / initiation you shouldn't access the sound registers within the timeframe, but playing sound is working fine (as well on NDSL as on "phat" DS)

#157751 - Cydrak - Wed May 28, 2008 8:32 pm

sverx wrote:
Code:
void FIFOInit(void) {
  REG_IPC_SYNC = (IPC_SYNC_IRQ_ENABLE | IPC_SYNC_IRQ_REQUEST);
  REG_IPC_FIFO_CR = (IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR | IPC_FIFO_RECV_IRQ);
}


Do you have IPC_SYNC_IRQ_ENABLE on the ARM9? IPC stuff is two-way, so the receiver needs them enabled. If swiWaitForIRQ() gets stuck there, it sounds like either IME = 0, or, for whatever reason, there's no sync pending...

Poking IPC_SYNC_IRQ_REQUEST "sends" the IRQ; FIFOInit() doesn't need it, unless you meant to. Not sure if this would confuse things.

Maxxie: Yep. Both streams and samples seem to recover okay. When I had *sequenced* music going, sleep would cause the occasional note to get stuck. Which implies the registers were missing i/o. A small delay upon waking, however, works fine.

#157756 - HyperHacker - Wed May 28, 2008 11:48 pm

About the earlier discussion of wiring the interrupt to the power switch, wouldn't that only be able to turn it on, since you have to hold the switch to turn it off? A quick jolt from the interrupt line shouldn't last long enough to shut down.
_________________
I'm a PSP hacker now, but I still <3 DS.

#157760 - Maxxie - Thu May 29, 2008 12:02 am

Well this wouldn't be a real problem.
As Cydrak pointed out we'd need additional logic to remove the shut-down an an already active and running DS. And adding a rc-combination to extend the signal length isn't too complex ;)

Main problem then would still be that existing original games as well as homebrew are probably leaving the IRQ enabled on shutdown of the DS (which can happen at any time by the user) so we'd have a lot of sideeffects.

It should have been considered in the design phase and it probably was but was dismissed as it could be used as another workaround for the write once-registers (POSTFLAG, Encryption)