1
\$\begingroup\$

I am using TWR-S08DC-PT60 board which has a MC9S08PT60 microcontroller.

I am trying to disable the watchdog timer in my application, just for ease of development. After configuring it in the software, it is disabled in the first run after programming, as wanted. However, after a reset occurs, either by reset button or power down, it is automatically enabled by itself. This happens when I debug, run or flash using CodeWarrior 10.4.

Here is how I disable it:

  _WDOG_CS1.Bits.UPDATE = 1; // Enable changes to WDOG.
  WDOG_CNT = 0xC520; // write the 1st unlock word
  WDOG_CNT = 0xD928; // write the 2nd unlock word

  _WDOG_CS1.Bits.EN = 0; // Kill the dog.
  _WDOG_CS1.Bits.INT = 1; // Enable WDOG interrupt.

From the reference manual:

23.3.2.1 Reconfiguring the Watchdog

In some cases (such as when supporting a bootloader function), users may want to reconfigure or disable the watchdog without forcing a reset first. By setting the WDOG_CS1[UPDATE] bit to a 1 on the initial configuration of the watchdog after a reset, users can reconfigure the watchdog at any time by executing an unlock sequence. (Conversely, if the WDOG_CS1[UPDATE] remains 0, the only way to reconfigure the watchdog is by initiating a reset.) The unlock sequence is similar to the refresh sequence but uses different values.

When I debug the application, I can see that UPDATE bit is set and the watchdog timer is disabled, also, it behaves as desired when I reset using the debugger. However, in case of a reset by the reset button or power down, watchdog timer is enabled again and reset the MCU, since I do not feed it in the main loop.

Also, it doesn't create an interrupt before resetting the MCU, although its interrupt is enabled. I can see, by the help of SYS_SRS (system reset source) register that the MCU is last reset by watchdog timer.

Commenting out 2nd and 3rd line (WDOG_CNT=...) does not help.

Here is my full code:

\$\endgroup\$
4
  • \$\begingroup\$ The reference manual (PDF) states in section 23.2 (p606) that the reset value of the watchdog control & status register (WDOG_CS1) is 80h, ie the enable bit is set on reset. \$\endgroup\$
    – MikeJ-UK
    Jun 21, 2013 at 14:08
  • \$\begingroup\$ @MikeJ-UK I have checked that; before the microcontroller resets, the code above is executed. Please check main.c. After initialize_CPU() function, which includes above code, executed, an LED is lit, then it is turned OFF. Then, SYS_SRS register is shown by the LEDs on the board. \$\endgroup\$ Jun 21, 2013 at 14:18
  • \$\begingroup\$ I'm not familiar with the architecture, but it's behaving as if WDOG_CS1 is in it's reset condition (EN=1, INT=0). The unlock sequence shouldn't be required, but I see you've tried removing that. Either initialize_CPU is not being called or it's not changing the CSR bits. What happens if you put a breakpoint after initialize_CPU, press reset, and check WDOG_CS1? \$\endgroup\$
    – MikeJ-UK
    Jun 21, 2013 at 14:52
  • \$\begingroup\$ @MikeJ-UK As I said so, with the debugger in control, code always runs. I have done what you suggested and EN bit of WDOG_CS1 seems to be cleared. \$\endgroup\$ Jun 21, 2013 at 15:15

2 Answers 2

1
\$\begingroup\$

Following is stated in page 615 of the reference manual, under section 23.3.2:

The new configuration takes effect only after all registers except WDOG_CNTH:L are written once after reset. Otherwise, the WDOG uses the reset values by default. If window mode is not used (WDOG_CS2[WIN] is 0), writing to WDOG_WINH:L is not required to make the new configuration take effect.

Adding these lines in initialize_CPU() function under file init.c, I can configure the watchdog timer, and disable it:

WDOG_CS1 = 0x60;
WDOG_CS2 = 1;
WDOG_TOVAL = 0x04;

Also, it is good to note that watchdog timer registers are write-once only. So, individual bit changes are not going to have an effect after first write to the same watchdog timer register.

If user wants to configure any of the watchdog timer registers later on, updates should be enabled in the first configuration. After that following is used to configure watchdog timer the second time. For more information, please have a look at the reference manual.

/* Initialize watchdog with ~1-kHz clock source, ~1s time-out */
DisableInterrupts; // disable global interrupt
WDOG_CNT = 0xC520; // write the 1st unlock word
WDOG_CNT = 0xD928; // write the 2nd unlock word
WDOG_TOVAL = 1000; // setting timeout value
WDOG_CS2 = WDOG_CS2_CLK_MASK; // setting 1-kHz clock source
WDOG_CS1 = WDOG_CS1_EN_MASK; // enable counter running
EnableInterrupts; // enable global interrupt
\$\endgroup\$
0
\$\begingroup\$

Virtually all MCUs that I have worked with enable the WDT on the reset. If you want it disabled the thing to do is put the code to disable it as the first code executed out of reset. That may even mean having to modify the C-startup module to make this happen right out of the starting gate. Some tool sets deliver the startup code with conditionals already in place to enable this behavior.

\$\endgroup\$
8
  • \$\begingroup\$ My toolset, CodeWarrior 10.4, shows the startup code, and possibly allows modification. But I don't get why I should do this in the startup code? \$\endgroup\$ Jun 21, 2013 at 15:16
  • \$\begingroup\$ @abdullahkahraman: If the watchdog could be disabled at any time, then errant code might disable the watchdog as it's wandering through the weeds. If I were designing a 32-bit processor chip, I would have a 32-bit register which would default to a "watchdog enabled" value; the CPU would reset any time the register contained a value other than a "watchdog enabled" value or one exact "watchdog disabled" value. Note that I'd implement the register as 32 latches, so that a glitch which disrupted any latch would be unlike to disrupt a valid combination. \$\endgroup\$
    – supercat
    Jun 21, 2013 at 15:55
  • \$\begingroup\$ @abdullahkahraman: If the value that would be necessary to disable the watchdog, did not appear anywhere in the code, it would be unlike that such a value could ever get written to the register. Further, if it was necessary for the application to disable and later re-enable the watchdog, the code which disabled it could be immediately followed by code which ensured that was the right thing to do (so if execution erroneously jumped there, code could detect that condition and force a resetart). \$\endgroup\$
    – supercat
    Jun 21, 2013 at 15:56
  • \$\begingroup\$ The reason for doing it in the C-Startup code is to satisfy the needs of some MCUs that I've worked with that require any possible WDT disable to be done within a specific number of clock cycles after the reset release. For those MCUs if you wait till main() to do it you may very well burn through the finite number of clock cycles before ever getting to main(). This can easily happen in cases where there are initialized global variables in RAM and part of the startup code runs loops to copy the RAM values from the ROM/FLASH code space. Note also that startup code has the job of (continued) \$\endgroup\$ Jun 21, 2013 at 17:51
  • 2
    \$\begingroup\$ @abdullahkahraman: If something causes a processor to start running errant code (e.g. stack-pointer corruption), just about anything can happen; one should basically figure the processor might start running "random code". Part of the purpose of a watchdog is to reset the processor in such situations. If there were any significant likelihood that random program execution could by chance perform the operations necessary to disable the watchdog, that would be very bad. \$\endgroup\$
    – supercat
    Jun 24, 2013 at 18:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.