/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1991 by John E. Lloyd.				    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*---------------------------------------------------------------------------
 *		
 * NAME:	sysclock
 *
 * USAGE:	sysclock [-set <interval>] [-get] [-on] [-off] [-D <value>]
 *
 * DESCRIPTION: This program is used to control the RCI system clock.
 *		
 *		The RCI system clock provides the time base with which
 *		RCI tasks are controlled. It was implemented for two
 *		reasons: (1) the default UNIX clock on many CPUs has a
 *		time base of only 50 or 100 Hz., which is too course
 *		for many applications, and (2) RCI tasks running on the 
 *		ARBITER CPU must run at maximum IPL, therefore masking out
 *		the UNIX clock and causing it to lose time, since the hardware
 *		with which the UNIX clock is implemented typically does not
 *		provide a counter with which to detect lost interrupts.
 *
 *		The RCI system clock is implemented with a useful resolution
 *		and a counter to allow recovery from the loss of clock ticks.
 *
 *		All present implementations of the RCI system clock restrict
 *		its usage to programs running control tasks on the ARBITER CPU
 *		only. As soon as a task is started on a slave CPU, the
 *		program's timebase is transferred to the clock on the slave.
 * 
 *		The system clock is controlled by the device /dev/rciclk,
 *		whose driver maps onto whatever hardware happens to be
 *		controlling the clock. Two implementations currently exist:
 *
 *			uVAX II system: A DRV11 connected to some 555 
 *					circuitry.
 *
 *			SUN4 SPARC system: A XYCOM XVME-203 counter
 *					module.
 *
 *		The /dev/rciclk driver provides I/O controls which query
 *		or set the clock rate, turn the device on or off, etc. The
 *		clock is normally off unless this device is open (and the
 *		clock is enabled; see '-on' option below). This
 *		program is a front end to that driver.
 *
 * ARGUMENTS:	-set <interval>		Set the clock interrupt rate to 
 *					<interval> milliseconds.
 *
 *		-get			Get the clock interrupt rate
 *					in milliseconds.
 *
 *		-on			Enable the clock. 
 *
 *		-off			Disable the clock.
 *
 *		-D <value>		Set debugging flag to <value>.
 *					Used by people hacking the device
 *					driver.
 *
 * AUTHOR/DATE: John Lloyd, Summer 1989
 *
 * MODIFICATION HISTORY:
 *
 *--------------------------------------------------------------------------*/

#include <stdio.h>
#include <errno.h>

#include "../h/cdefs.h"

extern int errno;

main(argc, argv)
int argc;
char **argv;
{
	char **argvec = argv;

	int enable = 0;
	int disable = 0;
	int getRate = 0;
	int setRate = 0;
	int setDebug = 0;
	int getStatus = 0;

	int interval;
	int debugValue;

	if (argc == 1)
	 { getStatus = 1;
	 }
	argc--; argv++;
	while (argc > 0)
	 { if (ARGUMENT ("-on"))
	    { enable = 1;
	    }
	   else if (ARGUMENT ("-off"))
	    { disable = 1;
	    }
	   else if (ARGUMENT ("-get"))
	    { getRate = 1;
	    }
	   else if (ARGUMENT ("-set"))
	    { argc--; argv++;
	      if (argc == 0)
	       { argc = -1;
		 break;
	       }
	      interval = atoi(*argv);
	      setRate = 1;
	    }
	   else if (ARGUMENT ("-D"))
	    { int value;

	      argc--; argv++;
	      if (argc == 0)
	       { argc = -1;
		 break;
	       }
	      debugValue = atoi(*argv);
	      setDebug = 1;
	    }
	   else
	    { argc = -1;
	      break;
	    }
	   argc--; argv++;
	 }
	if (argc < 0)
	 { fprintf (stderr, 
"%s [-set <interval>] [-get] [-on] [-off] [-D <value>]\n", argvec[0]);
	   exit (-1);
	 }

	if (getStatus)
	 { int enabled;
	   if (rciArbClkStatus(&enabled) < 0)
	    { printErrors();
	      exit(-1);
	    }
	   printf ("clock is %s\n", enabled ? "enabled" : "disabled");
	 }
	if (enable)
	 { if (rciArbClkEnable() < 0)
	    { printErrors();
	      exit (-1);
	    }
	   printf ("clock is now enabled\n");
	 }
	if (disable)
	 { if (rciArbClkDisable() < 0)
	    { printErrors();
	      exit (-1);
	    }
	   printf ("clock is now disabled\n");
	 }
	if (getRate)
	 { if (rciArbClkGetPeriod (&interval) < 0)
	    { printErrors();
	      exit (-1);
	    }
	   printf ("clock interval is %d msec.\n", interval);
	 }
	if (setRate)
	 { if (rciArbClkSetPeriod (interval) < 0)
	    { printErrors();
	      if (errno == EINVAL)
	       { fprintf (stderr,
			  "interval value %d msec. is illegal\n", interval);
	       }
	      exit (-1);
	    }
	   printf ("clock interval now set to %d msec.\n", interval);
	 }
	if (setDebug)
	 { if (rciArbClkSetDebug (debugValue) < 0)
	    { printErrors();
	      exit (-1);
	    }
	 }
}

