Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: [lpc2000] Re: RTC problem

2005-12-01 by Tom Walsh

r_bottleneck wrote:

>Hello,
>
>I still have the problem that the RTC is not working on my new board.
>However, I found,  the RTC is working with internal clock, in opposite 
>I mentioned in my start message. So there must be a problem with the
>32Khz oscillator internally or externally.
>
>I can not swap the LPC2138, because I have just a single board and
>I dont want to kill it while un-soldering the CPU.
>
>Is it possible to do a basic test to check if the oscillator is ok ? 
>I mean it must be something like an inverter and there is an input and
>output pin.
>
>Does anbody know how the oscillator of the LPC2138 internally looks 
>like? 
>
>What can prevent the 32kHz oscillator from working internally?
>
>  
>
If you have a scope, you would see about 1v p-p signal there, at least 
on my board.  Two can stop the RTC from running, the PCON settings and 
the CCR.  My setup looks like this:

============= begin ==============
static inline void sleepClock(void)
{// place RTC on 32kHz xtal and disconnect power.
   RTCCCR = (CCR_CLKEN | CCR_CLKSRC);
      // power off the clock registers.
   PCONP &= ~PCRTC;
}

static inline void awakenClock(void)
{// prepare clock for interactive use.
   RTCCCR = (CCR_CLKEN | CCR_CLKSRC);
      // power up the clock registers.
   PCONP |= PCRTC;
}

void initRTC(void)
{
#ifdef HAS_CLOCK
bool nonsense = False;
rtcCTIME0_t ctime0;
rtcCTIME1_t ctime1;
rtcCTIME2_t ctime2;
struct tm newTime;
time_t resetTime;
   awakenClock();
      // see if clock contains nonsense values.
      // grab time as consolidated to avoid misses.
   ctime0 = RTCCTIME0; ctime1 = RTCCTIME1; ctime2 = RTCCTIME2;
      // leisurely tear the packed time apart into individual time.
   if ((ctime0.seconds < 0) || (ctime0.seconds > 59)) nonsense = True;
   if ((ctime0.minutes < 0) || (ctime0.minutes > 59)) nonsense = True;
   if ((ctime0.hours < 0) || (ctime0.hours > 23)) nonsense = True;
   if ((ctime1.dayOfMonth < 1) || (ctime1.dayOfMonth > 31)) nonsense = True;
   if ((ctime1.month < 1) || (ctime1.month > 12)) nonsense = True;
   if ((ctime1.year < 1980) || (ctime1.year > 2050)) nonsense = True;
   if ((ctime0.dayOfWeek < 0) || (ctime0.dayOfWeek > 6)) nonsense = True;
   if ((ctime2.dayOfYear < 0) || (ctime2.dayOfYear > 366)) nonsense = True;
   sleepClock ();
   if (nonsense) {
      // set the clock to Jan 1, 2006 00:00:00
      resetTime = 1136073600l;
      localtime_r (&resetTime, &newTime);
      newTime.tm_year += 1900;
      newTime.tm_mon += 1;
      newTime.tm_yday += 1;
      writeRTC (&newTime);
   }
#endif
      // start realtime heartbeat (1ms period).
   startMsTimer();
}

void readRTC (struct tm *theTime)
{// read clock registers and return tm structure.
#ifdef HAS_CLOCK
rtcCTIME0_t ctime0;
rtcCTIME1_t ctime1;
rtcCTIME2_t ctime2;
   awakenClock();
      // grab time as consolidated to avoid misses.
   ctime0 = RTCCTIME0; ctime1 = RTCCTIME1; ctime2 = RTCCTIME2;
      // leisurely tear the packed time apart into individual time.
   theTime->tm_sec = ctime0.seconds;
   theTime->tm_min = ctime0.minutes;
   theTime->tm_hour = ctime0.hours;
   theTime->tm_mday = ctime1.dayOfMonth;
   theTime->tm_mon = ctime1.month;
   theTime->tm_year = ctime1.year;
   theTime->tm_wday = ctime0.dayOfWeek;
   theTime->tm_yday = ctime2.dayOfYear;
   theTime->tm_isdst = False;
   sleepClock ();
#endif
}

void writeRTC (struct tm *newTime)
{// set clock to new values.
#ifdef HAS_CLOCK
   awakenClock();
      // grab time as consolidated to avoid misses.
   RTCTCR->seconds = newTime->tm_sec;
   RTCTCR->minutes = newTime->tm_min;
   RTCTCR->hours = newTime->tm_hour;
   RTCTCR->dayOfMonth = newTime->tm_mday;
   RTCTCR->month = newTime->tm_mon;
   RTCTCR->year = newTime->tm_year;
   RTCTCR->dayOfWeek = newTime->tm_wday;
   RTCTCR->dayOfYear = newTime->tm_yday;
   sleepClock ();
#endif
}

============= snip ===============


I know that was a lot of code, but I figured that you might get what you 
need from it?  Those routines are written to interface with newlib stubs.

Note that in the readRTC() & writeRTC() functions that I "power up" the 
clock interface, do the work, then put it to sleep?  Well, I've found 
that if you leave the clock powered all the time, you run the risk of 
jumbling the time contents when the board is power-cycled.  Since I've 
done the sleep / awake routines, the clock has kept it's time and is 
always accessible.

Regards,

TomW

-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.