This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MCU wont wakeup from standby when using watchdog as wakeup source

I have a situation where i need to go to standby mode when mains power is lost.

To wakeup when mains is returned the watchdog wakes up the MCU every 400ms to check if mains has come back. If not the MCU goes to sleep again.

I have a problem with successive going to standby mode. After several successful watchdog wakeups the MCU suddenly wont wakeup on any of the defined wakeup sources (2 GPIOS and the watchdog) and is somehow frozen in standby mode.

All interrupts are disabled except the watchdog.

The actual sleep/wakeup loop looks like this:

void sleep(void)
{
// periodic sleep until power comes back or someone presses a button on control panel or emergency button
//do
{
// wait until WDINTS flag

if((SysCtrlRegs.SCSR & 0x04) != 0)
{
GpioDataRegs.GPBTOGGLE.bit.GPIO37 = 1; 

WDT_reset();

asm(" RPT #7 || NOP");
asm(" IDLE"); /* Force device into standby */
}

}
while ((AdcResult.ADCRESULT1 < 1792) && GpioDataRegs.GPADAT.bit.GPIO14 && GpioDataRegs.GPADAT.bit.GPIO10);

}

The function that inits the standby and calls the sleep loop looks like this:

void LPM_gotoSleep(void)
{

// disable all interrupts except watchdog
IER_backup = IER;
TMR_disableIsr();
IER = M_INT1;

EALLOW;

// The wakeup signal should be (2+QUALSTDBY) OSCCLKs wide.
SysCtrlRegs.LPMCR0.bit.QUALSTDBY = 0;

// enable watchdog in standby
SysCtrlRegs.LPMCR0.bit.WDINTE = 1;

// Wake up on control panel press
GpioIntRegs.GPIOLPMSEL.all = 0;
GpioIntRegs.GPIOLPMSEL.bit.GPIO14 = 1;
GpioIntRegs.GPIOLPMSEL.bit.GPIO10 = 1;

if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 1) // Only enter Standby mode when PLL is not in limp mode.
{
// Write the LPM code value
SysCtrlRegs.LPMCR0.bit.LPM = 0x0001; // LPM mode = Standby

EDIS;

// use watchdog to periodic wake from sleep
WDT_setMode(WDT_MODE_INTERRUPT);
WDT_reset();

EALLOW;
// prevent osc1 from halting. We want watchdog to wake us up
SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 1; // Switch Watchdog Clk Src to external
EDIS;

sleep();

EALLOW;
SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0; // Switch Watchdog Clk Src to internal
EDIS;

// enable watchdog
WDT_reset();
WDT_setMode(WDT_MODE_RESET);


}

EDIS;

// restore isr
IER = IER_backup;
TMR_enableIsr();

}

The watchdog interrupt and other watchdog functions:

__interrupt void WDT_wakeint_isr(void)
{
// Acknowledge this interrupt to get more from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

void WDT_reset(void)
{
EALLOW;
SysCtrlRegs.WDKEY = 0x0055;
SysCtrlRegs.WDKEY = 0x00AA;
EDIS;
}


void WDT_setMode(WDT_mode_t mode)
{
EALLOW;
if (mode == WDT_MODE_INTERRUPT) SysCtrlRegs.SCSR = BIT1;
else SysCtrlRegs.SCSR = 0;
EDIS;

}

Can anyone give me a hint to what i am doing wrong?