Yahoo Groups archive

Lpc2000

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

Thread

Need help setting up the watchdog timer to generate an interrupt

Need help setting up the watchdog timer to generate an interrupt

2005-03-14 by david_z_lawson

I'm trying to get the watchdog timer on the 2138 to timeout and
generate an interrupt. If I have the reset bit set in WDMOD it does
reset after 5 seconds, but I can't get the chip to execute the
interrupt (can't break in the interrupt routine). How should you
handle a watchdog interrupt? I'm not sure how you clear it.

Can someone look at the setup of the watchdog timer and tell me if I'm
doing it correctly?


#define WD_TIMEOUT 5.0		// 5 second watchdog timeout
void __attribute__((interrupt("IRQ"))) wdi(void);

//-------------------------------------------------------
//-------------------------------------------------------

init_watchdog(void)  {

   VICIntSelect &= ~0x00000001;	// watchdog selected as IRQ, not FIQ
   VICVectAddr4 = (unsigned long)wdi;	// set interrupt in slot 4
   VICVectCntl4 = 0x20;		// use it for watchdog interrupt
   VICIntEnable = 0x00000001;	// enable watchdog interrupt

   WDTC = (unsigned long) (.5 + WD_TIMEOUT / (4.0*PPERIOD) );
   WDMOD = 0x01;	// 8 bits, wden, interrupt but no reset

   WDFEED = 0xaa;	// 8 bits
   WDFEED = 0x55;	// 8 bits

   return;
}

//-------------------------------------------------------
//-------------------------------------------------------

void __attribute__((interrupt("IRQ"))) wdi(void)  {

   VICVectAddr = 0;		// acknowledge interrupt

}

Re: Need help setting up the watchdog timer to generate an interrupt

2005-12-24 by sonoramark@yahoo.com

>  Watchdog testing is tricky.  I've found that if I erase the 2138 and set 
a break in the MM_WATCHDOG_ISR() it works ONCE. Then, I must erase or re-flash the part with watchdog dis. before trying again, otherwise it will
always hit the watchdog ISR as soon as the watchdog is enabled.  Also, test in flash only, not in ram.  Do NOT load test code with watchdog time-out too quick or it becomes hard to talk to the part again.  Example, write test code to watchdog_hit() for about 5-10 sec. before trying to test a wathdog time-out.  This gives you the 5-10 sec. after each crash to try to re-flash the part with code that doesn't enable the watchdog. WATCHDOG_DEBUG does hit break point but only ONCE, THEN step 2,
STEP 1) test your code
STEP 2) load code with-out watchdog en.
STEP 3) goto step 1
Don't ship with WATCHDOG_DEBUG defined ,MM_WATCHDOG_ISR() OR after watchdog time-out it locks instead of resets (while(1);)
IAR lpc2138 code (12Mhz xtal):
//watchdog.h
#define WATCHDOG
//#define WATCHDOG_DEBUG

void watchdog_init(void);
void watchdog_hit(void);
//watchdog.c

#include "EWARM_version_420_430.h"
#include <iolpc2138.h>
#include <stdio.h>
#include <inarm.h>

#include "watchdog.h"

void watchdog_init(void)
{
  //WDTC = 0x004fffff; //4 sec //no pll
  //WDTC = 0x27FFFF; //2 sec //without pll
  WDTC = 0x9FFFFC; //2 sec //with pll 60Mhz

  WDFEED = 0xAA;
  WDFEED = 0x55;
  WDMOD_bit.WDEN = 1;
#if !defined(WATCHDOG_DEBUG)
  WDMOD_bit.WDRESET = 1;
#endif
  WDFEED = 0xAA;
  WDFEED = 0x55;
}

void watchdog_hit(void)
{
  WDFEED = 0xAA;
  WDFEED = 0x55;
}
//main.c
#include "Timer0_IntOnMR0.h"
#include "rtc.h"
#include "watchdog.h"
unsigned int us_Ticks;
#define InitPORT()	IO1DIR  = 0xFF0000; \
			IO1CLR  = 0xFF0000
#define TogglePORTbit0()  IO1PIN ^= 0x00800000
#define TogglePORTbit1()  IO1PIN ^= 0x00100000
void main(void)
{
  int i;
...
//12-22-05 add watchdog
#ifdef WATCHDOG
  watchdog_init();
#ifdef WATCHDOG_DEBUG
  VICIntSelect &= ~(1<<VIC_WDT); // watchdog intrpt is an IRQ (VIC_WDT = 0)
  VICVectAddr8 = (unsigned int)&MM_WATCHDOG_ISR; // Install ISR in VIC addr 
  VICVectCntl8 = 0x20 | VIC_WDT;    // IRQ type, watchdog int enabled
  VICIntEnable |= (1<<VIC_WDT);    // Turn on watchdog Interrupt
#endif
#endif
...
  __enable_interrupt();                        // Global interrupt enable
  InitPORT();
...
  i = 1;
  while(TRUE)                                  // Foreground "task"
  {
    if(bl_TimerFlag)
    {
      TogglePORTbit1();
      if(i < 20){
      //if(i){
        i++;
        watchdog_hit(); //10 sec. of this, then 2 sec. then TIME-OUT
        TogglePORTbit0();
      }
      bl_TimerFlag = FALSE; // Clear flag set by isr
      if( IOPIN0 & (1<<PIN0_4) )               // Is P0.4 High?
        IOCLR0 |= (1<<PIN0_4);                 // Yes, make it low
      else
        IOSET0 |= (1<<PIN0_4);                 // No, set pin high
    }
    read_rtc();

  } // end foreground loop
}   // end main()
#pragma vector=0x18
__irq __arm void IRQ_ISR_Handler (void)
{
  void (*interrupt_function)(void);
  unsigned int vector;
  static unsigned int us_count;
  us_count++;
  vector = VICVectAddr;                   // Get interrupt vector.
  interrupt_function = (void(*)())vector; // Call MM_.._ISR thru pointer
  (*interrupt_function)();            // Call vectored interrupt function
  VICVectAddr = 0;                      // Clear interrupt in VIC
}
void MM_WATCHDOG_ISR()
{
  IO1PIN = 0;
  while(1)
    ;
}

Re: Need help setting up the watchdog timer to generate an interrupt

2005-12-24 by Joe

See page 216 LPC2138 User guide
"If P0.14 is sampled low and the watchdog overflow flag is set, the
external hardware request to start the ISP command handler is ignored."

Could this be part of you problem?
 
I just ran in to this the other day, was using watchdog to reset after
 IAP, and then could not get to bootloader by pulling P0.14 low.

Joe

--- In lpc2000@yahoogroups.com, sonoramark@y... wrote:
>
> >  Watchdog testing is tricky.  I've found that if I erase the 2138
and set 
> a break in the MM_WATCHDOG_ISR() it works ONCE. Then, I must erase
or re-flash the part with watchdog dis. before trying again, otherwise
it will
> always hit the watchdog ISR as soon as the watchdog is enabled. 
Also, test in flash only, not in ram.  Do NOT load test code with
watchdog time-out too quick or it becomes hard to talk to the part
again.  Example, write test code to watchdog_hit() for about 5-10 sec.
before trying to test a wathdog time-out.  This gives you the 5-10
sec. after each crash to try to re-flash the part with code that
doesn't enable the watchdog. WATCHDOG_DEBUG does hit break point but
only ONCE, THEN step 2,
> STEP 1) test your code
> STEP 2) load code with-out watchdog en.
> STEP 3) goto step 1
> Don't ship with WATCHDOG_DEBUG defined ,MM_WATCHDOG_ISR() OR after
watchdog time-out it locks instead of resets (while(1);)
> IAR lpc2138 code (12Mhz xtal):
> //watchdog.h
> #define WATCHDOG
> //#define WATCHDOG_DEBUG
> 
> void watchdog_init(void);
> void watchdog_hit(void);
> //watchdog.c
> 
> #include "EWARM_version_420_430.h"
> #include <iolpc2138.h>
> #include <stdio.h>
> #include <inarm.h>
> 
> #include "watchdog.h"
> 
> void watchdog_init(void)
> {
>   //WDTC = 0x004fffff; //4 sec //no pll
>   //WDTC = 0x27FFFF; //2 sec //without pll
>   WDTC = 0x9FFFFC; //2 sec //with pll 60Mhz
> 
>   WDFEED = 0xAA;
>   WDFEED = 0x55;
>   WDMOD_bit.WDEN = 1;
> #if !defined(WATCHDOG_DEBUG)
>   WDMOD_bit.WDRESET = 1;
> #endif
>   WDFEED = 0xAA;
>   WDFEED = 0x55;
> }
> 
> void watchdog_hit(void)
> {
>   WDFEED = 0xAA;
>   WDFEED = 0x55;
> }
> //main.c
> #include "Timer0_IntOnMR0.h"
> #include "rtc.h"
> #include "watchdog.h"
> unsigned int us_Ticks;
> #define InitPORT()	IO1DIR  = 0xFF0000; \
> 			IO1CLR  = 0xFF0000
> #define TogglePORTbit0()  IO1PIN ^= 0x00800000
> #define TogglePORTbit1()  IO1PIN ^= 0x00100000
> void main(void)
> {
>   int i;
> ...
> //12-22-05 add watchdog
> #ifdef WATCHDOG
>   watchdog_init();
> #ifdef WATCHDOG_DEBUG
>   VICIntSelect &= ~(1<<VIC_WDT); // watchdog intrpt is an IRQ
(VIC_WDT = 0)
>   VICVectAddr8 = (unsigned int)&MM_WATCHDOG_ISR; // Install ISR in
VIC addr 
>   VICVectCntl8 = 0x20 | VIC_WDT;    // IRQ type, watchdog int enabled
>   VICIntEnable |= (1<<VIC_WDT);    // Turn on watchdog Interrupt
> #endif
> #endif
> ...
>   __enable_interrupt();                        // Global interrupt
enable
>   InitPORT();
> ...
>   i = 1;
>   while(TRUE)                                  // Foreground "task"
>   {
>     if(bl_TimerFlag)
>     {
>       TogglePORTbit1();
>       if(i < 20){
>       //if(i){
>         i++;
>         watchdog_hit(); //10 sec. of this, then 2 sec. then TIME-OUT
>         TogglePORTbit0();
>       }
>       bl_TimerFlag = FALSE; // Clear flag set by isr
>       if( IOPIN0 & (1<<PIN0_4) )               // Is P0.4 High?
>         IOCLR0 |= (1<<PIN0_4);                 // Yes, make it low
>       else
>         IOSET0 |= (1<<PIN0_4);                 // No, set pin high
>     }
>     read_rtc();
> 
>   } // end foreground loop
> }   // end main()
> #pragma vector=0x18
> __irq __arm void IRQ_ISR_Handler (void)
> {
>   void (*interrupt_function)(void);
>   unsigned int vector;
>   static unsigned int us_count;
>   us_count++;
>   vector = VICVectAddr;                   // Get interrupt vector.
>   interrupt_function = (void(*)())vector; // Call MM_.._ISR thru pointer
>   (*interrupt_function)();            // Call vectored interrupt
function
Show quoted textHide quoted text
>   VICVectAddr = 0;                      // Clear interrupt in VIC
> }
> void MM_WATCHDOG_ISR()
> {
>   IO1PIN = 0;
>   while(1)
>     ;
> }
>

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.