The MC9S08QG8 & MC9S08QG4 watchdog timer.

 

The watchdog timer (Freescale named it COP computer operate properly) in these devices can only cause the System Reset of the device and it has not the interrupt generation capability.

The watchdog timer could be clocked by an on chip oscillator running at 1 KHz or by the bus clock. The selection of the clock source is done using the COPCLKS bit of the SOPT2 (System Options Register 2) register. With each clock sources, there is an associated short and long time-out controlled by COPT in SOPT1.

The timeout value is set by the combination of the COPT and COPCLKS bits of the SOPT1 and SOPT2 register. Note that these registers are write-once to ensure the safety of the system. The possible timeout values are illustrated in the following table:

COPCLKS

COPT

Clock Source

Cop Overflow (in cycle)

0

0

1 Khz

2^5 cycles (32 ms)

0

1

1 Khz

2^8 cycles (256 ms)

1

0

Bus

2^13 cycles

1

1

Bus

2^18 cycle

 

To enable the watchdog timer, the COPE bit of the SOPT1 (System Options Register 1) register needs to be set to a logical 1. During the reset initialization the user needs to write to the write-once SOPT1 and SOPT2 registers to lock the setting even if the default watchdog values are used. These initial writes will reset the watchdog timer and will lock it (it's not possible to disable the watchdog timer if it is enabled after a SOPT1 write).

The refresh operation is done writing any value to the SRS (System Reset Status Register). Any write operation in the SRS register doesn't alter the SRS content, but only refresh the watchdog counter.

When the 1-kHz clock source is selected, the watchdog counter is re-initialized to zero upon entry to stop mode. The watchdog counter begins from zero after the MCU exits stop mode. In background mode the watchdog counter will not increment.

The operations used to enable/disable the watchdog timer and used to set up one of the timeout values is the following one:

1- Set, in the same instruction, the COPE bit (a logical 1 to enable, a logical 0 to disable) and COPT bit (according to the timeout) of the SOPT1 register, to the proper value.

2- Set the COPCLKS of the SOPT2.

It is not important the order of the previous sequence.

3- Write any value in the SRS register to refresh the watchdog.

To identify if the last reset was due to the watchdog timer, at the startup check if the COP bit of the SRS register is set.

 

MC9S08QG4/MC9S08QG8 example

 

The following example shows how to use the watchdog timer of the QG4/QG8 devices. use the CodeWarrior 6.1 C compiler to build the application. To build the application, you need to create a C project (with the project wizard) for the QG4/QG8 micro controller and your project name.

 

The QG4/QG8 is set to run from internal 8 Mhz clock and the PORTA pin 0 is connected to a led. At the startup the application checks if last system reset is due to watchdog. If the System reset is due to watchdog, the application turns on the led and wait forever otherwise the application toggles on/off for 10 times the led, resetting the watchdog timer, then it stops to refresh the watchdog. After 10 refreshes the micro controller executes a system reset and the next startup application turn on indefinitely the led.

To change the watchdog timer clock source and long/short timeout setting change the SOPT1 register value in the PeriphInit function.

// Watchdog C souce code for HCS08:

// written by : Stefano D’Andrea

#include <hidef.h> // for EnableInterrupts macro

#include "derivative.h" // include peripheral declarations

// ICSTRM location in Flash

unsigned char ICSTRM_FLASH @0xFFAF;

// Init the G4 modules

void PeriphInit(void)

{

// Watchdog setting ( 256 ms) :

// 1- clk 1Khz COPCLK = 0 (SOPT2)

// 2- long timeout COPT=1 (SOPT1)

// 3- enable the watchdog COPE = 1 (SOPT1)

SOPT1 = SOPT1_BKGDPE_MASK | SOPT1_COPT_MASK | SOPT1_COPE_MASK;

// it isn't necessary to setup the SOPT2 but ….. it's better (write once register)

SOPT2 = 0 ; // RESET value

// Configures PTA0 as output LED

PTAD = 0x00;

PTADD = 0x01;

// Configures ICS clock. Selects FLL Engaged Internal Mode (Divides ICSOUT by 1)

// fBUS about 8 MHz

ICSTRM = ICSTRM_FLASH;

ICSC2 = 0x00;

ICSC1 = 0x04;

// Waits until output FLL is selected (CLKST=00)

while (ICSSC & 0x0C)

;

}

void main(void)

{

int i,j, iWatch = 0;

// disable interrupts

DisableInterrupts;

/* Is last reset due to watchdog ?

*/

if (SRS & SRS_COP_MASK)

{

//Init the G4/G8 modules if last reset is due to watchdog

// disable the watchdog

SOPT1 &= 0x7F;

// Configures ICS clock. Selects FLL Engaged Internal Mode (Divides ICSOUT // by 1)

// fBUS about 8 MHz

ICSTRM = ICSTRM_FLASH;

ICSC2 = 0x00;

ICSC1 = 0x04;

// Waits until output FLL is selected (CLKST=00)

while (ICSSC & 0x0C);

// Configures PTA0 as output LED

PTAD = 0x00;

PTADD = 0x01;

// Toggles the LED (On)

PTAD |= 0x01;

for(;;)

{

// wait forever

};

}

// Init the G4/G8 modules if last reset is not due to watchdog

PeriphInit();

// enable the interrupts

EnableInterrupts;

for(;;) // Forever

{

iWatch++;

// refresh the watchdog timer until the iWatch counter is less than 10

if (iWatch < 10)

__RESET_WATCHDOG();

// Toggles the LED (On)

PTAD |= 0x01;

// Waits some times

for (i=0; i<20000; i++)

j = -1+i+1;

// Toggles the LED (Off)

PTAD &= 0xFE;

//Waits some times

for (i=0; i<20000; i++)

j = -1+i+1;

}

/* please make sure that you never leave main */

}