lpcware

WWDT with WDRESET set to 0 (interrupt only)

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by miccio on Thu Feb 04 09:46:24 MST 2016
Hello everyone,

I am experiencing two very different behaviors from the watchdog when testing my application.

I wrapped the watchdog handling in a class and wrote the following IRQ:

IRQ handler

#ifdef __cplusplus
extern "C" {
#endif

void WDT_IRQHandler(void) {
WatchDog::instance().handleIRQ();
}

#ifdef __cplusplus
}
#endif

void WatchDog::handleIRQ() {
uint32_t wdt_status = Chip_WWDT_GetStatus(_reg);

// warning interrupt
if (wdt_status & WWDT_WDMOD_WDINT) {
if(_warning_fnc != NULL) {
_warning_fnc();
}
Chip_WWDT_ClearStatusFlag(_reg, WWDT_WDMOD_WDINT);
}

// timeout interrupt
if (wdt_status & WWDT_WDMOD_WDTOF) {
if(_timeout_fnc != NULL) {
_timeout_fnc();
}
Chip_WWDT_ClearStatusFlag(_reg, WWDT_WDMOD_WDTOF);
}
}


callback function

void wdt_wrn_irq() {
Debug::instance() << "WDT warning " << gbl_sw.elapsedMS() << endl;
}
void wdt_rst_irq() {
Debug::instance() << "WDT timeout " << gbl_sw.elapsedMS() << endl;
}


usage in main code

WatchDog& wdt = WatchDog::instance();
wdt.init();

wdt.setTimeOutFunction(wdt_rst_irq);
wdt.setTimeOutMode(WDT_TO_Interrupt);
wdt.setTimeOutMS(5000);

// wdt.setWarningUS(50000);
// wdt.setWarningFunction(wdt_wrn_irq);

if(wdt.start()) {
Debug::instance() << "WDT started" << endl;
}


In this way, I can set a callback function that handles a timeout and/or warning event.
When I just let the code run with no breakpoint, the function seems to never get hit and nothing gets printed on the screen; when i set a breakpoint at handleIRQ(), it would however stop there and succesfully print the message when resumed.
It's also worth mentioning that the warning interrupt callback (represented by pointer void (*_warning_fnc)() ) gets executed regardless of whether I set breakpoints.

And it gets even weirder: I will use a different setup in my main code in order to enable the warning interrupt, like this:

WatchDog& wdt = WatchDog::instance();
wdt.init();

wdt.setTimeOutMode(WDT_TO_Interrupt);
wdt.setTimeOutMS(5000);
wdt.setTimeOutFunction(wdt_rst_irq);

wdt.setWarningUS(50000);
wdt.setWarningFunction(wdt_wrn_irq);

if(wdt.start()) {
Debug::instance() << "WDT started" << endl;
}


Now if I run with the usual breakpoint, the following will appear on screen:

WDT started
WDT warning 4711
WDT timeout 4713

Please note that the breakpoint is only hit once, and both callbacks are called withing the same execution of the handler. In facts, reading LPC_WWDT->MOD gives 1100 in binary.
This happens in spite of the value inside  LPC_WWDT->WARNINT which is at its maximum of 1023 (so the warning should occur 8.1ms before the interrupt. Instead, they are triggered at the very same time.

If I run it with no breakpoint, the following happens:

WDT started
WDT warning 4710

As you can see in this case, the timeout doesn't even seem to occur!!



Any idea, anyone?

Outcomes