Reply by sodele288 February 8, 20052005-02-08


Some days it just doesn't pay to get out of bed ...
but I think I had some luck today and killed the beast.

Puuhh ... after some deep investigation:

Loosing miiliseconds was a hardware problem here with the external
crystal oscillator of the EPM900 evaluation board (the behaviour
with other boards may vary).

With both, the 4.194304 MHz and the 3.2768 MHz crystal the XTAL1
amplitude at (Pin3.1) was about the same. I measured 1.2 Volt p-p
with a high-impedance probe (2 pF input capacitance).
While performing the program - depending on the tasks - the whole
oscillator signal was shifted in the baseline by about 60 mV, but
was of the same amplitude.
The shift unfortunately prevented the signal to cross the input
comparator threshold and so I lost input clock cycles.
As reported to the forum, some waiting times here and there had
some smoothing influence on the baseline shift and helped until
the next program changes. But I did not knew what I was doing
about. And I was very close to freak out.

I checked the P89LPC933-935 datasheet for the required signal
amplitude but could not find some values for guidance purposes.

Can someone shed some light on this, please?

The AN10289 LPC900 external crystal start-up application note
did not work for me. There must be a difference in this point
between the LPC935 bond-out and the real chip. But an external
22 kOhms pullup-resistor to VCC at the crystal driver output
(of the bond-out) brought the solution and everything works
fine now.

Where to find specs for the LPC935FA bond-out, please? Hello PM:

as you said : ... (looks like you are doing this OK) ...
I thought there MUST be a hardware problem and I did the above
extensive inquiry. I took all Monday and more ...

I also checked the reload value out with a 3.2768 MHz crystal.
With a given crystal, the reload value of (25.600-1) delivered
a 1.0000020 seconds tick and 25.600 delivered a 1.0000412
seconds tick. So I would stay with (25.600-1) for the 3.2768 MHz
crystal and (32768-1) when using the 4.194304 MHz crystal.

Regards,
J.

--- In lpc900_users@lpc9..., "sodele288" <sohls@t...> wrote:
>
> Hello PM,
>
> Thanks a lot for your advise. Yes, I will have a hardware watchdog
> externally (comes up after 2 seconds).
>
> The RTC initialization routine is as follows:
>
> void v_InitRTC(void)
> {
> WDCON = 0x00; // WDT OFF !!
> WFEED1= 0xA5;
> WFEED2= 0x5A;
> RTCL = (unsigned char) (RTC_RELOAD); // calculation of RTC
> clock
> RTCH = (unsigned char) ((RTC_RELOAD) >> 8);
> RTCCON = 0x22; // RTCS0 = 1 (Med. Freq.
Quartz)
> + Interrupt enable
> RTCCON = RTCCON | 1; // RTC start
> EWDRT = 1; // interrupt RTC & watchdog
> enabled
> }
>
> And still no luck. I cannot find a fault in the methodology.
>
> void v_RTC_ISR(void) interrupt 10 using 1
> {
> EA = 0; // disable all interrups
> EWDRT = 0; // Interrupt RTC & Watchdog disabled
> ....
>
> I cannot explain this: Why do 4 or 5 _nop_(); help here (for a
> while), but *not* 6 ?
> ....
>
> EWDRT = 1; // Interrupt RTC & Watchdog enabled
> EA = 1; // enable all interrups
> }
>
> Thanks for the 32768 reload value. I will check that out.
>
> Regards,
> J. > --- In lpc900_users@lpc9..., "phb_miller"
<PhoebeMiller@h...>
> wrote:
> >
> > Hello J,
> > In addition to my other comments check these points (these are
> > general comments for all users of the RTC):
> > - Clear the watchdog oscillator enable to stop unexpected
> interrupts.
> >
> > - The RTC should never stop counting, just clear the underflow
> flag,
> > do you processing, and then enable the interrupt again (looks
like
> > you are doing this OK).
> >
> > - The RTC is a DOWN counter, so I believe that your reload value
> > should be 32768 and not the 32768-1 that you indicate you are
using.
> >
> > PM



Reply by sodele288 February 6, 20052005-02-06

Hello PM,

Thanks a lot for your advise. Yes, I will have a hardware watchdog
externally (comes up after 2 seconds).

The RTC initialization routine is as follows:

void v_InitRTC(void)
{
WDCON = 0x00; // WDT OFF !!
WFEED1= 0xA5;
WFEED2= 0x5A;
RTCL = (unsigned char) (RTC_RELOAD); // calculation of RTC
clock
RTCH = (unsigned char) ((RTC_RELOAD) >> 8);
RTCCON = 0x22; // RTCS0 = 1 (Med. Freq. Quartz)
+ Interrupt enable
RTCCON = RTCCON | 1; // RTC start
EWDRT = 1; // interrupt RTC & watchdog
enabled
}

And still no luck. I cannot find a fault in the methodology.

void v_RTC_ISR(void) interrupt 10 using 1
{
EA = 0; // disable all interrups
EWDRT = 0; // Interrupt RTC & Watchdog disabled
....

I cannot explain this: Why do 4 or 5 _nop_(); help here (for a
while), but *not* 6 ?
....

EWDRT = 1; // Interrupt RTC & Watchdog enabled
EA = 1; // enable all interrups
}

Thanks for the 32768 reload value. I will check that out.

Regards,
J. --- In lpc900_users@lpc9..., "phb_miller" <PhoebeMiller@h...>
wrote:
>
> Hello J,
> In addition to my other comments check these points (these are
> general comments for all users of the RTC):
> - Clear the watchdog oscillator enable to stop unexpected
interrupts.
>
> - The RTC should never stop counting, just clear the underflow
flag,
> do you processing, and then enable the interrupt again (looks like
> you are doing this OK).
>
> - The RTC is a DOWN counter, so I believe that your reload value
> should be 32768 and not the 32768-1 that you indicate you are using.
>
> PM



Reply by phb_miller February 6, 20052005-02-06

Hello J,
In addition to my other comments check these points (these are
general comments for all users of the RTC):
- Clear the watchdog oscillator enable to stop unexpected interrupts.

- The RTC should never stop counting, just clear the underflow flag,
do you processing, and then enable the interrupt again (looks like
you are doing this OK).

- The RTC is a DOWN counter, so I believe that your reload value
should be 32768 and not the 32768-1 that you indicate you are using.

PM



Reply by phb_miller February 6, 20052005-02-06

Hello J.

What have you done with the watchdog?

For your reference the watchdog is enabled at reset (even if the WD
reset is disabled in UCFG1) and will generate an interrupt when it
barks. The watchdog shares the RTC interrupt and could the the cause
of your time creep.

Additionally the watchdog will draw current while it runs and
therefore turning it off would save power. The following code
sequence will achieve that:

WD_default equ 11100000b ; longest timeout, disable oscillator
WD_feed1 equ 0A5h
WD_feed2 equ 05Ah

mov wdcon, #WD_default
mov wfeed1, #WD_feed1
mov wfeed2, #WD_feed2

With my PDS900 emulator I can stop in the interrupt routine and
verify if the interrupt was caused by the RTC or the watchdog. The
need to turn the watchdog off (especially when aiming for minimum
current) does not seem to be widely known.

Good luck,
PM

--- In lpc900_users@lpc9..., "sodele288" <sohls@t...> wrote:
>
> Hi everybody!
>
> I'm working on a time sheduler that counts the seconds based on
> January 1, 2000 in order to represent the actual time and date
using
> the Keil LPC900 Development Tools MCB900/LPC935, EPM900 Emulator,
and
> uVision3.
>
> An external 4.194304 MHz crystal with the divide-by-128 prescaler
and
> a 32768-1 reload value delivers the 1-second tick for the ISR of
the
> RTC in order to increase the binary seconds. For binary-to-date
> calculation and driving the LCD on P2 the micro works with the
> internal RC-oscillator clock. No other external interrups applied.
>
> But up to now I have no luck to get the right time right:
> In average I am loosing 8 milliseconds every second or - in other
> words - about 12 minutes per day depending on other parts in
software
> due to clock slips.
>
> The basics are:
>
> At the very beginning of the RTC_ISR I am disabling the interrups.
> Then I count and process the next second.
> Then I enable the interrups again.
> BTW: IP0H = 0x40; // RTC interrupt priority 3
>
> void v_RTC_ISR(void) interrupt 10 using 1
> }
> EWDRT = 0; // disable RTC & watchdog interrupt
> RTCCON = 0x23; // clear med.frequ.crystal & ISR-flag
> ulRTCBinarySeconds++;
> btRTCNewSecond = 1; // there is a new time
> v_BinaryToDate(ulRTCBinarySeconds); // you got a new date
> EWDRT = 1; // enable interrupt RTC & Watchdog
> } > What I have done so far:
>
> a) I copied the ulRTCBinarySeconds variable to a second global
> variable and further processed it with the v_BinaryToDate function
> outside the RTC_ISR after the main program was aware of the
> btRTCNewSecond flag. But no luck!
> b) I included wait-functions in one to ten millisecods magnitudes
and
> _nop_()'s here and there in the main programm - and with an immense
> effort - I can stop the bit slips (which are multiples of 250
> nanoseconds) for a certain software representation. However if I
> include, move or delete one single program step of any kind the
> problem occurs again.
>
> Any hints or suggestions to make it right will be very much
> appreciated.
>
> Regards,
> J.



Reply by sodele288 February 5, 20052005-02-05

Hi everybody!

I'm working on a time sheduler that counts the seconds based on
January 1, 2000 in order to represent the actual time and date using
the Keil LPC900 Development Tools MCB900/LPC935, EPM900 Emulator, and
uVision3.

An external 4.194304 MHz crystal with the divide-by-128 prescaler and
a 32768-1 reload value delivers the 1-second tick for the ISR of the
RTC in order to increase the binary seconds. For binary-to-date
calculation and driving the LCD on P2 the micro works with the
internal RC-oscillator clock. No other external interrups applied.

But up to now I have no luck to get the right time right:
In average I am loosing 8 milliseconds every second or - in other
words - about 12 minutes per day depending on other parts in software
due to clock slips.

The basics are:

At the very beginning of the RTC_ISR I am disabling the interrups.
Then I count and process the next second.
Then I enable the interrups again.
BTW: IP0H = 0x40; // RTC interrupt priority 3

void v_RTC_ISR(void) interrupt 10 using 1
}
EWDRT = 0; // disable RTC & watchdog interrupt
RTCCON = 0x23; // clear med.frequ.crystal & ISR-flag
ulRTCBinarySeconds++;
btRTCNewSecond = 1; // there is a new time
v_BinaryToDate(ulRTCBinarySeconds); // you got a new date
EWDRT = 1; // enable interrupt RTC & Watchdog
} What I have done so far:

a) I copied the ulRTCBinarySeconds variable to a second global
variable and further processed it with the v_BinaryToDate function
outside the RTC_ISR after the main program was aware of the
btRTCNewSecond flag. But no luck!
b) I included wait-functions in one to ten millisecods magnitudes and
_nop_()'s here and there in the main programm - and with an immense
effort - I can stop the bit slips (which are multiples of 250
nanoseconds) for a certain software representation. However if I
include, move or delete one single program step of any kind the
problem occurs again.

Any hints or suggestions to make it right will be very much
appreciated.

Regards,
J.