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.

MSP430F5438A & Watchdog use/configuration

Other Parts Discussed in Thread: CC1101, SIMPLICITI, MSP430F5529

Hi, I am here again.

I need to use the watchdog in my project.

Reading documentation, I have understand that once I have started the WDT, I need to "feed" or "kick" the dog in the code to avoid a PUC. So, to start using WDT,  my first idea is: start the WDT and a generic timer. In the generic timer interupt I "feed" the dog, so if I have configured a timer overflow value lower than WDT interval, I will "feed" the dog, but if this time is greater than WDT, PUC. My code is here (my first tests without the lines have been commented):

#include  "msp430x54x.h"

unsigned char selection=0;

void main(void)
{
    WDTCTL = WDTPW + WDTIS_4   + WDTCNTCL + WDTSSEL_1;     // watchdog pass, watchdog time interval: 1 sec (page 386 User's guide), clear register,
                                                                                                                              // select ACLK as clock source                      
 /*
  TA1CCTL0 = CCIE;                            
  TA1CCR0 =15000;                                                                              // With prescale selected, 15000 => ~3.6 second (near to limit between WDT feeding or PUC)           
  TA1CCTL0 &= 0xFFFE;    
  TA1CTL = TASSEL_1 + MC_1 +  TACLR + ID__8;                         // ACLK as clock source, Timer UP mode, clear register prescale /8
 */
  __bis_SR_register(GIE);
      
  for(;;)
  {/*
      switch (selection)
      {
          case 0:{break;}
          
          case 1:
          {
              WDTCTL = WDTPW + WDTCNTCL;
            WDTCTL = WDTPW + WDTIS__32K  + WDTSSEL_1;  
            selection=0;
              break;
          }
      }*/
  }                 
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
    selection=1;
}

Well, my problems start with WDT interval, if I understand correctly the User's Giude, with my configuration, I have to achieve a 1 second interval, but I obtain about 3.5 seconds. This time is calculated with a breakpoint in the first line of main and the first line of case 1. I suppose that with way, there will be some delays, but not as long as 1 second or more.

To test another way (maybe two timers sourced to a same clock source could create problems, it is a supposition by my side), I did the commentaries that you see in this code (I only start the WDT and a infinite loop). So  I do not "feed" the WDT in any moment, it will produce a PUC. But the time between the unique breakpoint in the first line of the main holds constant (about 3.5 sec).

The formula showed in the user's guide, for WDTIS = 4, is  "Watchdog clock source /32k ". If I use the 3.5s in this formula: f(watchdog clock source)/ 32000=1/3.5

f(watchdog clock source)= 32000/3.5 = ~10KHz instead of 32KHz. The VLO frequency is about those 10KHz, but I do not have modified any UCSCTLX register for changing the clock source for ACLK.

I do not know if I am doing something wrong or I do not understand well the WDT functionality. ¿Any idea, correction, etc.?

Thanks in advance.

  • Hi,

    the easiest way i find to use the WDT is basically using the predefined macros in the device header file.

    For example in your case if you want to use WDT in Watchdog mode, you need only to feed the WDTCTL with one of the following values:

    /* Watchdog mode -> reset after expired time */
    /* WDT is clocked by fSMCLK (assumed 1MHz) */
    #define WDT_MRST_32 (WDTPW+WDTCNTCL) /* 32ms interval (default) */
    #define WDT_MRST_8 (WDTPW+WDTCNTCL+WDTIS0) /* 8ms " */
    #define WDT_MRST_0_5 (WDTPW+WDTCNTCL+WDTIS1) /* 0.5ms " */
    #define WDT_MRST_0_064 (WDTPW+WDTCNTCL+WDTIS1+WDTIS0) /* 0.064ms " */
    /* WDT is clocked by fACLK (assumed 32KHz) */
    #define WDT_ARST_1000 (WDTPW+WDTCNTCL+WDTSSEL) /* 1000ms " */
    #define WDT_ARST_250 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS0) /* 250ms " */
    #define WDT_ARST_16 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1) /* 16ms " */
    #define WDT_ARST_1_9 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0) /* 1.9ms " */

    If you are using VLO with 10 kHz as ACLK instead of 32 kHz, you can just  roughly multiply the time given in the comment with around factor 3 e.g. if you use WDT_ARST_1000, you shall expect the time reset after ~3s

  • Thanks for your answer (by the way, I have to answer you in other post too, about CC1101).

    Well, I had not mentioned, but I have used this values too (WDT_ARST_1000) and I have just tried again, with the same result, I obtain about 3 s interval, when I do not modified the clock source for the ACLK.

    After some projects using timers, I have seen that the default source for ACLK is XT1. When I wanted to reduce the power consumption, I use ACLK sourced to VLO, to get this, I had to rewrite the UCSCTL4 register (UCSCTL4 |= SELA_1;). If I did not this, my ACLK source still was XT1.

    So my doubt is about the reason why, without have not done any modifications in the register to change the ALCK source, I obtain a 10kHz frequency for the watchdog clock source according to the User's guide formula and the time measured while the timer A which I used gives a correct values for my selected times, is to say:

    (-) without touching ACLK sourced,using ACLK as clock source, timer  prescale /8 and 15000, I do obtain ~3 secs. [(32768/8)^-1]*15000=3.66 s.

    (-) without touching ACLK sourced, using ACLK as clock source, WDTIS =4, I obatin ~3sec, when it would have to be : 32768Hz/32000=1,024Hz=> (1,024)^-1=0.976 s.

    Thanks again.

  • Is T da S said:
    I have understand that once I have started the WDT, I need to "feed" or "kick" the dog in the code to avoid a PUC.

    The WDT is active on power-on. So not 'once I have started', but rather 'unless I have stopped' :)

    Is T da S said:
    my first idea is: start the WDT and a generic timer. In the generic timer interupt I "feed" the dog,

    That's how I use it. My timer ISR that runs my millisecond timer will trigger the WDT every ms. However, this ISR counts up several global variables and if one of them exceeds a certain threshold, th eISR won't kick the WDT anymore and eventually teh WDT will cause a reboot.

    The software has to clear these variables before they reach the threshold.

    This way, I have any number of WDTs for different threads or jobs, with different timeouts.

    On 54xx, ACLK should run on 32kHz, either through external crystal or (if there is no crystal on XT1) though internal REFO. Which too should be 32kHz.

    So I agree, with your settings, I'd expect the watchdog to time out in 1s.

    However, some general advice: when assigning multiuple options to a hardware register, you shoud not add them you shoudl OR them:
    WDTCTL = WDTPW | WDTIS_4   | WDTCNTCL | WDTSSEL_1;
    It avoids almos tuntraceable confusion if some options set the same bits, like the WDT_ADLY_1000 setting that already contains the password. ORing the password manually will not do any harm, adding it will result in a completely different value to be written.

    BTW: you can turn the WDT into interval mode. In this mode, expiration will not trigger a PUC but rather trigger an interrupt. This is done by setting the WDTTMSEL bit and enabling the watchdog interrupt in SFRIE. And of course the proper ISR needs to be coded. IOn Interval mode, teh WDT will trigger an interrupt periodically. You can still reset it, stretching the current 'interval'. Btu it can serve as a cheap 1s timer tick or such. If you don't need the WDT acting as real watchdog.

    p.s.: the purpose of a watchdog is mainly to revive/reset the MSP if it crashes due to external events like ESD or supply voltage anomalies. It is not meant to serve as a 'restart a buggy application if it crashes' tool. Even if it is abused for this often by less skilled coders.

  • Did you ever resolve this? I have the exact same problem: the watchdog PUC takes about 3.5 times as long as it should.

    I even wrote some test code to put the watchdog into timer mode and trigger an interrupt, which toggles an LED. Then I remove the timer bit to put it into watchdog mode, and also add an LED toggle to main that will trigger after every PUC. With only those changes, the LED period is 3.5 times longer.

    This is on the experimenter board. I wonder if that has something to do with it. I confirmed that ACLK is 32.768 kHz from the test point.

  • Test code. I highlighted the only differences.

    #if 1 // This is timer mode. The LED toggles every 16 seconds.
    void main(void)
    {
      WDTCTL = WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL_1+WDTIS_3;// WDT 16s, ACLK, interval timer
      SFRIE1 |= WDTIE;                          // Enable WDT interrupt
      P1DIR |= 0x01;                            // Set P1.0 to output direction

      __bis_SR_register(LPM3_bits + GIE);       // Enter LPM3, enable interrupts
      __no_operation();                         // For debugger
    }

    // Watchdog Timer interrupt service routine
    #pragma vector = WDT_VECTOR
    __interrupt void WDT_ISR(void)
    {
      P1OUT ^= 0x01;                            // Toggle P1.0 using exclusive-OR
    }
    #else // This is watchdog mode. The LED toggles every 56 seconds.
    void main(void)
    {
      WDTCTL = WDTPW+WDTCNTCL+WDTSSEL_1+WDTIS_3;// WDT 16s, ACLK, watchdog mode
      P1DIR |= 0x01;                            // Set P1.0 to output direction
      P1OUT ^= 0x01;                            // Toggle P1.0 using exclusive-OR

      __bis_SR_register(LPM3_bits + GIE);       // Enter LPM3, enable interrupts
      __no_operation();                         // For debugger
    }
    #endif

  • Hi,

    when I had this problem I was working with SimpliciTI stack too. In the SimpliciTI Board Support Package for our uC is placed a loop that waits for the Xtal stabilization (it is that the comments says). Using this loop, I got a correct timing for the WDT and RTC (without this loop, the RTC had a big delay after a some time of working).

    /* Setup XT1 crystal */
      P7DIR = 0xFE;                             // Enable xtal pins
      P7SEL |= 0x03;
     
      while ( (SFRIFG1 & OFIFG) )
      {
        UCSCTL7 &= ~(XT1LFOFFG + DCOFFG);
        SFRIFG1 &= ~OFIFG;
      }
      UCSCTL6 &= ~(XT1DRIVE_3);                 // Xtal is now stable, reduce drive strength


    The steps that I followed: Stop the WDT, do this loop and then, trigger the WDT again and with this, it would have to work better.

    Right now, I have copied part of the SimpliciTI BSP to a custom *.h and *.c to get a quick way to initialize the uC correctly and more automatic, so I could be saying  some wrong or could be forgetting something in this post. Take this in account (it could not work at first time or give some problems). If you want some extra information, ask here again.

    I hope it help you.

  • That loop worked, thanks. I saw a similar loop in the TI example code for the UCS. It didn't help when I first tried it, but now I think I might have been messing with some other settings at the time. I had switched over to use VLOCLK instead.

    For anyone else reading this in the future, don't forget to stop the watchdog timer before doing this loop and enabling the WDT again. Otherwise it might trigger the watchdog before the clock has finished stabilizing. That threw me off at first.

  • Timothy James said:
    don't forget to stop the watchdog timer before doing this loop and enabling the WDT again

    Or feed the dog so it doesn't bark :)

    If you can afford switching the watchdog off for even a split second, then you can leave it off all the time. Unless you want to abuse it as timer, or as a cheap fix for buggy code.

  • Jens-Michael Gross said:
    Or feed the dog so it doesn't bark :)

    Quick follow-up for future web searchers: this does work. You can pet the system default watchdog in the clock stabilization loop, and then quickly use the stabilized clock to create the watchdog timeout you want to do. When I first tried this, I must have been getting a watchdog timeout or some other odd behavior. I thought I needed to turn it off before stabilizing the clocks.

    All set now. I'm glad we resolved this mystery.

  • Timothy James said:

    Did you ever resolve this? I have the exact same problem: the watchdog PUC takes about 3.5 times as long as it should.

    I even wrote some test code to put the watchdog into timer mode and trigger an interrupt, which toggles an LED. Then I remove the timer bit to put it into watchdog mode, and also add an LED toggle to main that will trigger after every PUC. With only those changes, the LED period is 3.5 times longer.


    I can across this thread today after encountering the same issue (all WDT durations lasting about 3.5 longer than predicted when using ACLK) with the MSP430F5529. The solution ultimately proposed in this thread worked for me (with the minor difference that the XIN and XOUT pins are P5.4 and P5.5 on the F5529), but I thought it might be worth adding a few points (specific to the F5529, but generally applicable).

    With the F5529, ACLK's default is to use XT1CLK as its source. On the F5529 launchpad, XT1 is connected to a 32.768 kHz crystal oscillator. As noted in the MSP430x5xx and MSP430x6xx Family User's Guide, when XT1CLK uses a crystal, fault control logic immediately causes ACLK to switch to using REFOCLK as its source because the crystal isn't initially stable (section 5.2 of the UG). REFOCLK also runs at 32.768 kHz, but is less accurate. To switch back to XT1CLK, it's necessary to loop while OFIFG is set and clear both OFIFG and the oscillator fault flags in UCSCTL7 in the loop body (as discussed earlier in this thread).

    Given this information, it seems that the WDT (when set to use ACLK) should run at 32.768 kHz regardless of whether or not XT1CLK or REFOCLK ends up being ACLK's source, just with a varying degree of accuracy. However, the WDT switches its clock source to VLOCLK (which runs at around 10 kHz) if it is set to use SMCLK or ACLK and either of those fail, but only when operating in watchdog mode (not timer mode). This is referred to as the clock fail-safe and is discussed in section 16.2.5 of the UG. Since VLOCLK is more than three times slower than ACLK, the WDT's duration ends up a bit more than three times greater than intended.

    I found this somewhat counter-intuitive. Since ACLK switches to REFOCLK if XT1CLK has faulted, it surprised me that the WDT considers ACLK to have failed in this case. If ACLK is set to REFOCLK directly (e.g., using UCSCTL4 |= SELA__REFOCLK on the F5529), the WDT will use ACLK. It seems that any sort of problem with ACLK (even one that ACLK itself recovers from) causes the WDT to switch to VLOCLK.

  • Hello,

    I have worked with this uC some years ago, so I do not remember exactly the register to write, reset, set, ... but I can give you the information I got in the past.

    When I wrote this question, it was my first contact to this uC,  I had a bit lack of knowledge, so I continued with my job without regarding this problem. But the months passed, and when the date project is about to end, I found a problem with a simple timing of 10 minutes. I could not get the correct timing, why? In our project we turn on an internal power supply to turn on a communication module, and  for some reason(voltage peak, ....) the oscillator lost its stability, and the counting was wrong (for 10 minutes, we got 9, 8 minutes and decresing every time we turn on that power supply)

    The solution I found comes from SimpliciTI (TI's RF stack). During the initialization function of this stack, I found a line (while loop I think) which wait to stabilize the oscillator and then the flow continues. I simply added this loop to my main loop. Maybe you can add a state machine instead of using a while loop.

    As I have told you before, many years have passed, so Ï do not remember exactly the register to check, but you can find it in the board support initialization supplied by SimpliciTI or you can take a look to the CPU module register (I think this register is related to this section or a section related to uC clocks).

    I hope it helps.

  • "I found this somewhat counter-intuitive. "
    It seems so at first, unless you think about it more closely.
    The WDT is special in that it can use not only ALCK and SMCLK as sources but also VLOCLK (which originally is an oscillator for the clock and not a clock itself) and X_CLK.
    Remember that on older MSPs, ACLK didn't have a fallback, leaving the WDT with no clock at all if it wouldn't switch to something that will always work (DCO or VLO).
    So if the source of its currently selected clock (if ACLK or SMCLK) signals a fault, it switches to its own default (VLOCLK), not caring for what ACLK or SMCLK do when their selected source fails. This ensures that the WDT will eventually time out, even if it takes longer than originally planned.

**Attention** This is a public forum