/**
 * Watchdog Timer example.
 *
 * The watchdog timer MUST be enabled in the config bits for this 
 * example to work.
 *
 * PORTA is configured as all inputs.  PORTB is configured as all outputs.
 *
 * Every reset, it produces a 100 millisecond pulse on B0, then
 * falls into a loop where it watches A0.  Whenever it finds A0 high,
 * it clears the watchdog timer.
 *
 * As a result, when A0 is high, the watchdog will never time out and
 * B0 will not flash.  But when A0 is low, the watchdog will time out
 * and give the chip a stern boot to the head several times a second,
 * rebooting the program which flashes B0.
 */
#define __16f628a
#include "pic/pic16f628a.h"
#include "tsmtypes.h"

/* tsmdelay.h needs KHZ to be defined to something. */
#ifndef KHZ
#define KHZ 4000
#endif

/**
 * If you're linking several .c files together, INSTANTIATE_DELAY
 * should only be defined in one of them or you'll get multiple definitions
 * of loop variables and cycle_eater.
 */
#define INSTANTIATE_DELAY
#include "tsmdelay.h"
 
// Set the __CONFIG word:
// I usually set it to _EXTCLK_OSC&_WDT_OFF&_LVP_OFF&_DATA_CP_OFF&_PWRTE_ON
Uint16 at 0x2007  __CONFIG = _INTOSC_OSC_CLKOUT &	// Internal oscillator
				_WDT_ON		&	// Watchdog ON!
				_LVP_OFF	&	// No Low-Volt Program.
				_DATA_CP_OFF	&	// No Code Protect
				_PWRTE_ON;

void setup_wdt(void)
{
	/**
	 * This could done in one line with OPTION_REG=0x0d, but
	 * this is an example, so we show you exactly what bits we're 
	 * setting to what why.
	 */
	
	PSA=1;	// WDT uses the prescaler, not the timer

	/**
	 *	PS2 PS1 PS0
	 *	0   0   0	=	1:1
	 *	0   0   1	=	1:2
	 *	0   1   0	=	1:4
	 *	0   1   1	=	1:8
	 *	1   0   0	=	1:16
	 *	1   0   1	=	1:32
	 *	1   1   0	=	1:64
	 *	1   1   1	=	1:128
	 */

	PS2=1;	// A 1:32 ratio at 4MHz gives us about 3 reboots a second.
	PS1=0;
	PS0=1;
}

void main(void)
{
#ifdef __16f628a
	CMCON = 0x07;	/** Disable comparators.  NEEDED FOR NORMAL PORTA
			 *  BEHAVIOR ON 16f628a!
			 */
#endif

	TRISB=0x00;	// PortB all outputs
	TRISA=0xff;	// PortA all inputs
	setup_wdt();	// Set up watchdog timer prescaler

	PORTB=0x01;	// Set 1 to B0
		DELAY_BIG_US(100000UL);	// Wait 100ms
	PORTB=0x00;	// Set 0 to B0

END:
	if(PORTA&0x01)	// Keep refreshing the WDT when A0=1
	{
		__asm clrwdt __endasm;	// It has its own special instruction
		setup_wdt();	// clrwdt resets WDT parameters to default
	}
	goto END;	// Loop forever, waiting for WDT reset
}  
