hw_watchdog.c 3.54 KB
#include "c_def.h"
#include "debug.h"
#include "oem.h"

#include "regmap.h"

#include "mem_reloc.h"

#include "hw_watchdog.h"
#include "flash_boot.h"


//void watchdog_init(U8 pre_scale, U8 clk_div) __attribute__ ((section (".flash_boot_text")));
//void wtachdog_enable(void) __attribute__ ((section (".flash_boot_text")));
//void wtachdog_disable(void) __attribute__ ((section (".flash_boot_text")));
void watchdog_time_reset(void) __INTERNAL_RAM_TEXT;


#define UNLOCK_DWORD                   0x6F70746B

#define WDT_RESET_DWORD0               0x55AA9BDF
#define WDT_RESET_DWORD1               0x1357AA55

#define WATCHDOG_ENABLE                (1 << 0)
#define WATCHDOG_DISABLE              ~(1 << 0)

//1K prescale bit
#define WATCHDOG_CLK_PRESCALE_ENABLE    (1 << 1)
#define WATCHDOG_CLK_PRESCALE_DISABLE  ~(1 << 1)


/*
	regCtl_clkDividor: bit5->bit2

   0 to 15
	wdt delay time:		2^(10 + regCtl_clkDividor)
	min:	2^10
	max:	2^25
*/


//System Clock:96Mhz, Bus Clock:48Mhz
//2^10 = 1024
//2^25 = 33554432
//Min:(48 * 10^6)/(1024*1024) = 45.7764 Hz. (21.8453 ms/times, reset:21.8453 ms)
//Max:(48 * 10^6)/(1024*33554432) = 0.001397 Hz. (715.8196 s/times, reset:715.8196 s)

//System Clock:48Mhz, Bus Clock:24Mhz
//Min:(24 * 10^6)/(1024*1024) = 45.7764/2 Hz. (21.84533 * 2 ms/times, reset:21.84533 * 2 ms)
//Max:(24 * 10^6)/(1024*33554432) = 0.001397/2 Hz. (715.8196 * 2 s/times, reset:8196 * 2 ms)

//System Clock:24Mhz, Bus Clock:12Mhz
//Min:(12 * 10^6)/(1024*1024) = 45.7764/4 Hz. (21.84533 * 4 ms/times, reset:21.84533 * 4 ms)
//Max:(12 * 10^6)/(1024*33554432) = 0.001397/4 Hz. (715.8196 * 4 s/times, reset:8196 * 4 ms)

//clk_div: 2^(10 + clk_div)

void watchdog_init(U8 pre_scale, U8 clk_div)
{
#if 1
	U32 tmp = 0;

	REG_WATDOG_UNLOCK = UNLOCK_DWORD;
	
	clk_div &= 0x0F;

	if (pre_scale)
	{
		tmp = (WATCHDOG_ENABLE | WATCHDOG_CLK_PRESCALE_ENABLE | (clk_div << 2));
		REG_WATDOG_CTRL = tmp;
	}
	else
	{
		tmp = (WATCHDOG_ENABLE | (clk_div << 2));
		REG_WATDOG_CTRL = tmp;
	}

#else
	U32 tmp = 0;

	REG_WATDOG_UNLOCK = UNLOCK_DWORD;
	
	clk_div &= 0x0F;

	tmp &= ~WATCHDOG_ENABLE;

	if (pre_scale)
	{
		tmp |= (WATCHDOG_CLK_PRESCALE_ENABLE | (clk_div << 2));
		REG_WATDOG_CTRL = tmp;
	}
	else
	{
		tmp |= (clk_div << 2);
		REG_WATDOG_CTRL = tmp;
	}
#endif
}

void wtachdog_enable(void)
{
	U32 tmp = 0;

	REG_WATDOG_UNLOCK = UNLOCK_DWORD;

	tmp = REG_WATDOG_CTRL;

	tmp |= WATCHDOG_ENABLE;

	REG_WATDOG_CTRL = tmp;
}

void wtachdog_disable(void)
{
	U32 tmp = 0;

	REG_WATDOG_UNLOCK = UNLOCK_DWORD;

	tmp = REG_WATDOG_CTRL;

	tmp &= ~WATCHDOG_ENABLE;

	REG_WATDOG_CTRL = tmp;
}

void watchdog_time_set(U32 ms)
{
}

void watchdog_time_reset(void)
{
#ifdef WATCH_DOG
	REG_WATDOG_UNLOCK = UNLOCK_DWORD;
	REG_WATDOG_RESET = WDT_RESET_DWORD0;
	REG_WATDOG_UNLOCK = UNLOCK_DWORD;
	REG_WATDOG_RESET = WDT_RESET_DWORD1;
#endif
}

#if 0
void watchdog_time_reset_error(void)
{
	REG_WATDOG_UNLOCK = UNLOCK_DWORD;
	REG_WATDOG_RESET = WDT_RESET_DWORD0;

	REG_WATDOG_UNLOCK = UNLOCK_DWORD;
	REG_WATDOG_RESET = 0xff;	

	REG_WATDOG_UNLOCK = UNLOCK_DWORD;
	REG_WATDOG_RESET = WDT_RESET_DWORD1;	
}
#endif

void watchdog_unlock(void)
{
	REG_WATDOG_UNLOCK = UNLOCK_DWORD;
}


//#define WTACHDOG_TEST

#ifdef WTACHDOG_TEST

void wtachdog_test(void)
{
#if 0
	//1K prescale enable
	watchdog_init(TRUE, 0);
	while (1)
	{
#if 0
		delayms(21); //sys no reset
#else
		delayms(22); //sys reset
#endif

		watchdog_time_reset();
	}

#else
	//1K prescale disable
	watchdog_init(FALSE, 0x0A);
	while (1)
	{
#if 1
		delayms(21*2); //sys no reset
#else
		delayms(22*2); //sys reset
#endif

		watchdog_time_reset();
	}
#endif
}

#endif //WTACHDOG_TEST