Forums

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

Started by sono...@... December 23, 2005
> 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)
;
}



An Engineer's Guide to the LPC2100 Series

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@lpc2..., 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
> VICVectAddr = 0; // Clear interrupt in VIC
> }
> void MM_WATCHDOG_ISR()
> {
> IO1PIN = 0;
> while(1)
> ;
> }
>