/*
 *----------------------------------------------------------------------
 *    micro T-Kernel
 *
 *    Copyright (C) 2006-2011 by Ken Sakamura. All rights reserved.
 *    micro T-Kernel is distributed under the micro T-License.
 *----------------------------------------------------------------------
 *
 *    Version:   1.01.01
 *    Released by T-Engine Forum(http://www.t-engine.org) at 2011/07/29.
 *
 *----------------------------------------------------------------------
 */

/*
 *	tkdev_timer.h (TWRK60N512)
 *	Hardware-Dependent Timer Processing
 */

/*
 *  for MB9BF618T on FRK-FM3
 * 
 *   Copyright (C) by Y.Ishioka.
 */

#ifndef _TKDEV_TIMER_
#define _TKDEV_TIMER_

#include <tk/syslib.h>
#include <sys/sysinfo.h>
#include <systick.h>
#include "tkdev_conf.h"

#if USE_TRAP
#define ENAINT		enaint(1);
#define DISINT		disint();
#else
#define ENAINT		enaint(1);
#define DISINT		disint();
#endif

/*
 * Settable interval range (millisecond)
 */
#define MIN_TIMER_PERIOD	1
#define MAX_TIMER_PERIOD	50

IMPORT UW	knl_TimerClkDiv;	/* Dividing rate of timer clock */

/*
 * Set timer
 */
Inline void knl_init_hw_timer( void )
	{
	InitSysTickTimer();
	return;
	}

/*
 * Timer start processing
 *	Initialize the timer and start the periodical timer interrupt.
 */
Inline void knl_start_hw_timer( void )
{
IMPORT	void	knl_timer_handler_startup( void );

	/* Set timer */
	knl_init_hw_timer();
}

/*
 * Clear timer interrupt
 *	Clear the timer interrupt request. Depending on the type of
 *	hardware, there are two timings for clearing: at the beginning
 *	and the end of the interrupt handler.
 *	'clear_hw_timer_interrupt()' is called at the beginning of the
 *	timer interrupt handler.
 *	'end_of_hw_timer_interrupt()' is called at the end of the timer
 *	interrupt handler.
 *	Use either or both according to hardware.
 */
Inline void knl_clear_hw_timer_interrupt( void )
{
}

Inline void knl_end_of_hw_timer_interrupt( void )
{
}

/*
 * Timer stop processing
 *	Stop the timer operation.
 *	Called when system stops.
 */
Inline void knl_terminate_hw_timer( void )
{
}

/*
 * Get processing time from the previous timer interrupt to the
 * current (nanosecond)
 *	Consider the possibility that the timer interrupt occurred
 *	during the interrupt disable and calculate the processing time
 *	within the following
 *	range: 0 <= Processing time < CFN_TIMER_PERIOD * 2
 */
Inline UW knl_get_hw_timer_nsec( void )
{
	volatile SysTickRegister_t* sysTickReg = (SysTickRegister_t*)0xE000E010;
	UW cur;
	UW rel;

	disint();

	cur = sysTickReg->STCVR;
	rel = sysTickReg->STCVR;

	cur = rel - cur;

	enaint(0);

#if 0  /* Y.Ishioka */
	return (1000000 * (cur / rel));
#else
	return (1440000 * (cur / rel));
#endif
}

#endif /* _TKDEV_TIMER_ */
