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.

Watchdog Timer Resetting



I can't seem to get WDT to work.  It trips as soon as I clear the counter.

I'm using CCS 5.3.0.00090, and the MSP FET430UIF. 

Code:

main{

WDTCTL = WDTPW + WDTHOLD;           // Stop WDT
msp430_init();                                              // Set up DCO and configure ports
__bis_SR_register(GIE);                            // Interrupts enabled
IFG1 &= ~WDTIFG;                                      // Clear WDT Interrupt flag
IE1 |= WDTIE;                                                // Enable WDT Interrupt
WDTCTL |= WDTPW + WDTCNTCL + WDTHOLD;         // Clear WDT Counter- Don't start WDT.

while(1)
     {

     WDTCTL = WDTPW + WDTCNTCL;                    //Start  watchdog

     }

}

SMCLK is running at 4 Mhz.. 

I put a break point in the while loop, and execution never makes it that far.  As soon as I clear the WDT (even while keeping the hold bit set "WDTCTL = WDTPW + WDTHOLD;" ), the controller resets and the PC is pointing back to the first line of code. 

Is the FET causing my problems, or am I doing something really stupid?

  • Rkensparc said:
    am I doing something really stupid?

    To be honest - yes.

    You are not getting WDT __reset__ because you disable its' functionality by reconfiguring WDT to period timer:

    Rkensparc said:
    IE1 |= WDTIE;                                                // Enable WDT Interrupt

    Don't test WDT using debugger but blinking LED code instead.

    This is how you shall arm WDT:

    WDTCTL = WDT_ARST_1000; // Set Watchdog Timer timeout 1s

    Download source code examples and study WDT examples..

  • I think you need to read the Chapter about WDT in the User's Guide of the family of MSP430 you are using.

    Are you trying to use it as a watchdog or an interval timer? You did not even attempt to make it operates as an interval timer.

    As a watchdog, you do not need to set GIE, you do not need to clear WDTIFG, and you do not need set WDTIE. It will generate a reset when WDTCNT expires.

    As an interval timer with both GIE and WDTIE set, you need to have an ISR for that. But you did not have that and you code will crash.

    As for you immediate problem with the statement:

    WDTCTL |= WDTPW + WDTCNTCL + WDTHOLD;

    Why do you use |= instead of = ? The difference is the cause of your misfortune.

  • Ilmars said:
    ... You are not getting WDT __reset__ because you disable its' functionality by reconfiguring WDT to period timer: ...

    I did not see that. No mansion of WDTTMSEL or anything like that.

  • old_cow_yellow - Thanks - I knew I was doing something stupid.  The |= was indeed the source for my misfortune.

  • old_cow_yellow said:
    WDTCTL |= WDTPW + WDTCNTCL + WDTHOLD;
    Why do you use |= instead of = ? The difference is the cause of your misfortune.

    You should not just give the solution but also an explanation (or else the next one is posting the same question again, even if he did read your post)

    |= reads WDTCTL, ORs the right-hand expression into this value and writes the result back. But WDTCTL always reads a wrong password. OR'ing the right password into it will still give a wrong password. This is intentional. And will cause a PUC in this case.

    As a side note: this mistake, if done right at the start of main in a project without (or with only a few) global variables, did often lead to an inaccessible MSP in the past. The reset caused by the wrong password was resetting the MSP before the debugger could attach. In this case, clearing the memory through BSL was the only way to revive the MSP.

**Attention** This is a public forum