/******************************************************************************

  Copyright (C), 2010-2013, Texas Instrument.

 ******************************************************************************
  File Name     : Robust_watch_dog.c
  Version       : Initial Draft
  Author        : Brighton Feng
  Created       : 2012/10/13
  Last Modified :
  Description   : This example shows watch-dog Timer on KeyStone device
  Function List :
              watch_dog_test
  History       :
  1.Date        : 2012/10/13
    Author      : Brighton Feng
    Modification: Created file

******************************************************************************/
#include <stdio.h>
#include <csl_bootcfgAux.h>
#include "K2_common.h"

/*period (in millisecond) of the watch-dog timer*/
/*since the timer runs at (Main core clock)/6
the conversion between millisecond and timer PRD value is:
PRD = (xxx_MS/1000)*Main_CLK_HZ/6
    = xxx_MS*(Main_CLK_HZ/1000)/6
    = xxx_MS*Main_CLK_HZ/6*/
#define WATCH_DOG_PERIOD_MS 	3000
    
/*****************************************************************************
 Prototype    : watch_dog_test
 Description  : set local timer (==(16+CP15_get_CPU_ID())) as watch dog timer,
                service the watch-dog for sometime, 
                after stop servicing watch-dog, let it trigger NMI
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/13
    Author       : Brighton Feng
    Modification : Created function

*****************************************************************************/
void watch_dog_test()
{
	int i;
	Uint32 timerCnt, timerNum;
	Timer64_Config tmrCfg;
	volatile Uint32 * RSTMUX;

	puts("===================-watch dog timer test-========================");
	timerNum= 16+CP15_get_CPU_ID();
	//select output on TIMO0 from local timer.
#ifdef DEVICE_K2L 	//for K2L
	gpBootCfgRegs->TOUTPSEL0 = (timerNum*2)<<CSL_BOOTCFG_TOUTPSEL0_TOUTPSEL0_SHIFT;
#else
	gpBootCfgRegs->TOUTSEL = (timerNum*2)<<CSL_BOOTCFG_TOUTSEL_TOUTSEL0_SHIFT;
#endif

#ifdef DEVICE_K2E
	RSTMUX = &gpBootCfgRegs->RSTMUX8; 
	RSTMUX += CP15_get_CPU_ID();
#else
	RSTMUX = &gpBootCfgRegs->RSTMUX[(8+CP15_get_CPU_ID())]; 
#endif
	*RSTMUX= (7<<CSL_BOOTCFG_RSTMUX0_RSTMUX_DELAY0_SHIFT)
		/*WD timer event trigger GIC interrupt*/
		|(WD_TRIGGER_GIC<<CSL_BOOTCFG_RSTMUX0_RSTMUX_OMODE0_SHIFT);
		
	puts("start watch-dog timer...");

	//configure the timer for watch-dog
	tmrCfg.timer_num= timerNum;
	tmrCfg.timerMode= TIMER_WATCH_DOG;
	tmrCfg.period= (unsigned long long)WATCH_DOG_PERIOD_MS*gMain_Core_Speed_Hz/6000;
	tmrCfg.reload_period= 0; //not used for this case
	tmrCfg.pulseWidth= 3;
	Timer64_Init(&tmrCfg);

	//service the watch-dog for sometime, 
	for(i=1; i<=10; i++)
	{
		timerCnt= gpTimerRegs[timerNum]->CNTLO;
		Service_Watchdog(timerNum);
		printf("service watch-dog %d times, at time counter = %u\n", 
			i, timerCnt);
	}

	printf("!!!stop servicing watch-dog, it will timeout and trigger exception after %d ms...\n",
		WATCH_DOG_PERIOD_MS);

	/*wait for watch dog timer expires*/
	while(gpTimerRegs[timerNum]->CNTLO);
	/*add dummy nop here to wait for the exception happens*/
	dummy_wait(10000);	
}

