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 > Problems with RealTimeClock (IPC->...)

#117802 - king corn - Wed Feb 07, 2007 4:59 pm

hi!
first off, yes i did a search ;).

yesterday i switched from devkitARM_r19a to devkitARM_r20 and from libnds-20060719 to libnds-20070127, made some changes to my sourcecode and compiled.
well the problem now is, that IPC->time.rtc.xyz returns zero.
i've tried on both hardware and no$gba, but no luck with the clock.
it did work fine with the old version, but with the new improved stylushandling i really don't want to switch back again.

any hint or help would be very much appreciated.

#123110 - ikaris - Sun Mar 25, 2007 4:39 am

I have the same issue.

Not sure what can be done to fix it.

#123116 - ttabbal - Sun Mar 25, 2007 6:52 am

I added this to the VBlank handler for the arm7...

rtcGetTime(IPC->time.curtime);

The RTC data is now not zero. It doesn't fix my problem with libfat not setting a file date though. Odd. I can print out the time, but libfat still doesn't want to set the file timestamps.

I'm not sure this is the best way to handle the time data, but it has to be read from the arm7, and the VBlank seemed like a good way to keep it reasonably updated.

#123124 - melw - Sun Mar 25, 2007 10:42 am

According to Wintermute, there's going to be a changes in a way how IPC struct is handled, as well as realtime clock. However, this is how the realtime clock works with the current libnds CVS version. Just call initClock() in the beginning of arm7 main and use syncRTC() in vblank interrupt.

Code:
void initClock()
{
   REG_RCNT = 0x8100;

   irqSet(IRQ_NETWORK, testSync);

   // Reset the clock if needed
   rtcReset();

   rtcGetTimeAndDate((uint8 *)&(IPC->time.rtc.year));

   uint8 command[4];
   
   command[0] = READ_STATUS_REG2;
   rtcTransaction(command, 1, &command[1], 1);

   command[0] = WRITE_STATUS_REG2;
   command[1] = 0x41;

   rtcTransaction(command, 2, 0, 0);   

   command[0] = WRITE_INT_REG1;
   command[1] = 0x01;
   rtcTransaction(command, 2, 0, 0);
   
   command[0] = WRITE_INT_REG2;
   command[1] = 0x00;
   command[2] = 0x21;
   command[3] = 0x35;
   
   rtcTransaction(command, 4, 0, 0);
}

void syncRTC()
{
   int oldhours = IPC->time.rtc.hours;
   
   uint8 command[2];
   
   command[0] = READ_STATUS_REG1;
   rtcTransaction(command, 1, &command[1], 1);

   IPC->mailSize = REG_RCNT;

   if ( command[1] & 0x30 ) {
      IPC->mailRead = command[1];
      REG_IF = IRQ_NETWORK;
   } else {
      IPC->mailAddr = command[1];
   }

   rtcGetTime((uint8 *)&(IPC->time.rtc.hours));

   if(oldhours>IPC->time.rtc.hours) // going from 23 to 0 hours, update whole time struct
      rtcGetTimeAndDate((uint8 *)&(IPC->time.rtc.year));
}

// in vblank:

   if ( ++frame == 60 ) { // update time struct once per second
      frame = 0;
      syncRTC();
   }