/************************************************************************/
/* Copyright 1993 - 1997 MBARI						*/
/************************************************************************/
/* $Header: microtime.c,v 1.2 91/09/23 09:38:59 hebo Exp $		*/
/* Summary  : Clock adjustment functions for MVME-162 CPU under vxWorks	*/
/* Filename : sysMicroClock.c						*/
/* Author   : Bob Herlien (rah)						*/
/* Project  : Tiburon ROV						*/
/* $Revision: 1.2 $							*/
/* Created  : 02/28/91							*/
/************************************************************************/
/* Modification History:						*/
/* $Log$
*/
/* 23nov93 rah, created	for MVME-162					*/
/************************************************************************/

#include <mbari_types.h>		/* MBARI standard types		    */
#include <vxWorks.h>			/* VxWorks includes		    */
#include <mv162.h>			/* Hardware defns for MVME-162	    */
#include <drv/multi/mcchip.h>		/* MCC chip definitions		    */
#include <intLib.h>			/* for intLock/intUnlock	    */

#define DELTA	1000


/********************************/
/*	Module Local Data	*/
/********************************/

MLocal Nat32	currentTick;		/* Current clock tick interval    */


/************************************************************************/
/* Function    : sysMicroClockInit					*/
/* Purpose     : Init function for sysMicroClock			*/
/* Input       : Period of clock tick in microseconds			*/
/* Outputs     : None							*/
/************************************************************************/
	Void
sysMicroClockInit( Nat32 tickTime )
{
    currentTick = tickTime;

} /* sysMicroClockInit() */


/************************************************************************/
/* Function    : sysMicroClockAdj					*/
/* Purpose     : Adjust the clock frequency of system ticker		*/
/* Input       : Period of clock in microseconds			*/
/* Outputs     : None							*/
/* Comments    : Needed in support of adjtime(), which is in support	*/
/*		 of NTP.  For NTP, clock adjustments are small differences*/
/*		 from the normal system clock rate.  In our case (MV-162),*/
/*		 normal rate is 16.67 ms, and the adjustments are	*/
/*		 +/- 8 microseconds from that.				*/
/************************************************************************/
	Void
sysMicroClockAdj( Nat32 tickTime )
{
    Reg int	key;

    key = intLock();

    *MCC_TIMER1_CMP = tickTime;		/*Set up new compare value	*/

/* Note that this routine gets called from the clock tick interrupt.	*/
/* Therefore the current timer count should be low.  The following is	*/
/* a sanity check, to ensure we're not going to set a compare value	*/
/* below the current count, which would result in no tick for 71 	*/
/* minutes.  It should never happen, barring extreme interrupt latency	*/
/* (> 15.6 ms).  But if it does, the result of the following is to	*/
/* lose a small amount of clock time, rather than 71 minutes.		*/
/* This check is the reason for the intLock/intUnlock.			*/

    if ( *MCC_TIMER1_CNT > (tickTime - DELTA) )
	*MCC_TIMER1_CNT = tickTime - DELTA;

    intUnlock(key);

    currentTick = tickTime;

} /* sysMicroClockAdj() */


/************************************************************************/
/* Function    : sysMicroClockGet					*/
/* Purpose     : Return microseconds since last clock tick		*/
/* Input       : None							*/
/* Outputs     : Microseconds since last clock tick			*/
/************************************************************************/
	Nat32
sysMicroClockGet( Void )
{
    Reg Nat32	cnt;

/* No intLock() needed, because the following is a single transfer	*/

    cnt = *MCC_TIMER1_CNT;

    if ( cnt > currentTick )
	return( 0 );

    return( cnt );

} /* sysMicroClockGet() */


/************************************************************************/
/* Function    : sysMicroClockSet					*/
/* Purpose     : Set the microtime counter				*/
/* Input       : Microseconds since last tick to set			*/
/* Outputs     : None							*/
/************************************************************************/
	Void
sysMicroClockSet( Nat32 microTime )
{
    Reg int	key;

    key = intLock();

    if ( microTime < (currentTick - DELTA) )
	*MCC_TIMER1_CNT = microTime;

    intUnlock(key);

} /* sysMicroClockSet() */
