Yahoo Groups archive

Lpc2000

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

Message

Re: Problem with watchdog

2005-12-09 by brendanmurphy37

Ken,

I'm still curous about your statement "the processor expects
a WRITE(0xAA) on the very next cycle". Where is this documented? It 
may be true, but if so, I'd say it contradicts the quote I took from 
the User Manual (for the LPC213x parts). Or am I misreading what it 
says?

It's a fairly important point: if the feed has to be done in two 
adjacent CPU cycles, you're forced to use assembler apart from 
anything else, in order to do the back-to-back write reliably (I've 
checked the assembler o/p from our own code, and it does, but you 
can't rely on this: all you need is to change the revision of the 
compiler or have a new optimsaition setting and thinmgs can fall 
apart).

On the other point: you're quite right - there's plenty of "gotchas" 
with ARM interrupts. It's been a while since I looked at this, but I 
seem to recall spending at least a few days armed with a stack of 
ARM books/manuals etc. (if you'll forgive the pun) to get our 
interrupt handling code to a state we were happy with it. Funny how 
you forget such things... I think what prompted my question was the 
implication that you somehow couldn't set both bits at the same 
time. As the other response on this points out, you can of course, 
and it works, but maybe not in quite the way you'd expect.....

I'd apreciate an answer on the watchdog issue though, as it's very 
much a live issue with us at the moment.

Regards
Brendan


--- In lpc2000@yahoogroups.com, "Ken Wada" <kwada@a...> wrote:
>
> --- In lpc2000@yahoogroups.com, "brendanmurphy37" 
<brendan.murphy@i...
> > wrote:
> >
> > 
> > Ken,
> > 
> > Can you explain why you think there's a problem with an 
interrupt 
> > between the two writes?
> > 
> > According to the User Manual: "Once 0xAA is written to
> > the WDFEED register the next operation in the Watchdog register 
> space 
> > should be a WRITE (0x55) to the WDFFED register otherwise the 
> > watchdog is triggered."
> > 
> > I take this to mean that the next write to the WDFEED register 
has 
> to 
> > be 0x55 following the 0xaa: why should it matter if this is one 
> cycle 
> > on, or 1000 cycles on (e.g. to take account of any interrupt)? 
I'm 
> > assuming here that the interrupt itself doesn't go near the 
> watchdog.
> It makes a bit difference! If you WRITE (0x55), the processor 
expects 
> a WRITE(0xAA) on  the very next cycle. If this is done outside an 
> interrupt context, the interrupt service routine will pretty much 
> guarantee that this condition is violated!
> 
> > 
> > Also, for disabling interrupts, why not just disable IRQ and FIQ 
in 
> > the same write to the CPSR? Is there some problem with this?
> Yep...huge problem. Actually, you will see this type of problem 
with 
> many processors/especially DSP's with fully pipelined 
architecture. 
> The Philips User manual calls this the spurious interrupt problem. 
> Actually, Philips basically took their cautionary note directly 
from 
> the ARM users guide.
> 
> Gone are the good-old days of doing something like EA=0, as per 
8051..
> .these pipelined architectures are a bit different when it comes 
to 
> instruction processing.
> 
> Fortunately, all of these modern architectures give you a way to 
do 
> these types of operations, (albeit with a bit more effort), via 
some 
> software interrupt (SWI) instruction.
> 
> My 1st encounter with this was with the Intel 80386 chip. This 
chip 
> had an instruction pipeline, and I had to use the int86() SWI 
command 
> in order to properly code up the atomic sections.
> 
> Ken Wada
> > 
> > regards
> > Brendan
> >  
> > 
> > --- In lpc2000@yahoogroups.com, "Ken Wada" <kwada@a...> wrote:
> > >
> > > Basically, your method works fine...
> > > UNTIL: you start adding interrupt service routines!
> > > 
> > > This is why:
> > > void WDOG_pet()
> > > {
> > > WDFEED = 0xAA;
> > > /*             Interrupt occurs here...> dog will NOT pet 
> > properly!!! 
> > > ***/
> > > WDFEED = 0x55;
> > > }
> > > 
> > > /**** example uses Keil compiler directives ***/
> > > /********** The following is what I wound up doing, (gotta 
avoid 
> > that 
> > > spurious interrupt issue with the ARM also!!! ***/
> > > 
> > > /**** The actual interface that everybody uses ***/
> > > void WDOG_pet (void)
> > > {
> > >     SYSSWI_service (12,0,0,0);
> > > }
> > > 
> > > /***** How the SYSSWI_service works, (based on SWI) ***/
> > > unsigned SYSSWI_service (SYSSWI opcode, int id, void *pObj, 
> > unsigned 
> > > _user1) __swi(12)
> > > {
> > >     switch (opcode)
> > >     {
> > >       case SYSSWI_WDOGPET:
> > >         SYSSWI_watchDogPet ();
> > >         break;
> > >       ...
> > >     }
> > >     return (0);
> > > }
> > > 
> > > /***** How the SYSSWI_watchDogPet () works ***/
> > > static void SYSSWI_watchDogPet (void)
> > > {
> > >     ARM_disableFIQ ();                /* make sure FIQ is 
> > disabled     
> > >      */
> > >     WDFEED  = 0xAA;
> > >     WDFEED  = 0x55;
> > >     ARM_enableFIQ ();                 /* re-enable the 
> > FIQ             
> > >      */
> > > }
> > > 
> > > /***** The IRQ is automatically disabled by vectoring to the 
SWI..
> .
> > > however, you need to make the operation atomic with respect to 
> FIQ, 
> > > which is NOT disabled ***/
> > > 
> > > PUBLIC  ARM_disableFIQ?A ; interface is ARM mode
> > > 
> > > ARM_disableFIQ?A  PROC  CODE32
> > >       MRS   R0,CPSR
> > >       ORR   R0,R0,#0x0040                   ; Mask just the FIQ
> > >       MSR   CPSR_c,R0
> > >       BX    R14
> > > 
> > >       ENDP
> > > 
> > > PUBLIC  ARM_enableFIQ?A ; interface is ARM mode
> > > 
> > > ARM_enableFIQ?A  PROC  CODE32
> > >       MRS   R0,CPSR
> > >       BIC   R0,R0,#0x0040                   ; Enable just the 
FIQ
> > >       MSR   CPSR_c,R0
> > >       BX    R14
> > > 
> > >       ENDP
> > > END
> > > 
> > > 
> > > --- In lpc2000@yahoogroups.com, "Ake Hedman, eurosource" 
> > <akhe@b...> 
> > > wrote:
> > > >
> > > > Hi all.
> > > > 
> > > > I am trying to enable the watchdog but the result is a total 
> hang 
> > of 
> > > the 
> > > > board. Not even the bootloader is possible to reach after 
the 
> > crash 
> > > and 
> > > > I have to reapply power with P0.14 low to get access to the 
> > > botloader 
> > > > again. Reset is not enough.
> > > > 
> > > > The code to initialize the watchdog is
> > > > 
> > > >     // initialize the watchdog timer
> > > >     WDTC = 0xffffffff; // 
15000000;                        // 
> One 
> > > second 
> > > > = 15000000
> > > >     WDMOD = WDEN | WDRESET;                    // Activate 
> > watchdog
> > > >     WDFEED = 0xAA; WDFEED = 0x55;
> > > > 
> > > > I must have misunderstood the WD functionality. What am I 
doing 
> > > wrong? 
> > > > In the above code the watchdog should not trigger until 5 
> minutes 
> > > > elapsed so even if a vector should be wrong the code that 
follow 
> > > should 
> > > > run for a while but as soon as I write to the WDMOD register 
I 
> > get a 
> > > hang.
> > > > 
> > > > /Ake
> > > > 
> > > > -- 
> > > >  ---
> > > > Ake Hedman (YAP - Yet Another Programmer)
> > > > eurosource, Brattbergavägen 17, 820 50 LOS, Sweden
> > > > Phone: (46) 657 413430 Cellular: (46) 73 84 84 102
> > > > Company home: http://www.eurosource.se      
> > > > Kryddor/Te/Kaffe: http://www.brattberg.com
> > > > Personal homepage: http://www.eurosource.se/akhe
> > > > Automated home: http://www.vscp.org
> > > >
> > >
> >
>

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.