home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
nisttime.carsoncity.k12.mi.us
/
nisttime.carsoncity.k12.mi.us.tar
/
nisttime.carsoncity.k12.mi.us
/
pub
/
lockclock
/
gettck.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-18
|
4KB
|
119 lines
#include "sizint.h"
LONG gettck()
{
/*
this subroutine looks at the clear to send
line on the device specified by dv in the .h
file, and reads the time when the line becomes true.
The value returned is the usec portion of the local
time. The subroutine interpolats between ticks if
tickus is not zero and if the constant INTERP is
defined as not 0. The return value is in usec and
is always between 0 and 999999. Under normal
circumstances, the caller assumes that values
between 1 and 499999 imply that the integer number
of ticks is correct so that the local clock
is fast whereas values between 500000 and 999999
imply that the local clock is slow. This routine
must therefore be called often enough so that the
local time will not have drifted off by 0.5 seconds.
If this is not done, the caller will likely drive
the local time to be a full integer second wrong.
the return time will be negative on an error.
values are:
-1 cannot open serial port.
-2 ioctl error
-3 no tick received after max number of loops.
This may happen sometimes if the system is
heavily loaded.
This software was developed with US Government support
and it may not be sold, restricted or licensed. You
may duplicate this program provided that this notice
remains in all of the copies, and you may give it to
others provided they understand and agree to this
condition.
This program and the time protocol it uses are under
development and the implementation may change without
notice.
For questions or additional information, contact:
Judah Levine
Time and Frequency Division
NIST/847
325 Broadway
Boulder, Colorado 80303
(303) 492 7785
judah@india.colorado.edu
*/
#include "gettck.h"
#include <sys/termios.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
LONG j;
int fd; /*file handle for open*/
int istat; /*modem status line*/
LONG t1,t2,t3; /*microsecond values of the time*/
struct timeval tvv; /* holds system time when tick arrives */
LONG k1,k2; /* counters for interpolation*/
fd=open(dv, O_RDWR | O_NDELAY); /*open port defined in .h */
if(fd < 0) return(-1l); /* open error*/
t1= -3l; /* return value if time-out */
/*
now loop until CTS becomes true. If the for loop ends
on its count limit then we have a time-out, which may
not be an error if the system is heavily loaded.
Get the time when CTS becomes true and then estimate
the fraction of the tick remaining by looping until
the tick changes. Then loop until the tick changes
again, which will be a full tick interval. The
ratio between these two loop counters is used as
the interpolation estimate below. Note that the
interpolation is effectively disabled if tickus = 0
*/
for(j=0; j<100000l; j++) /*limit is about 4s on 5000/240 */
{
/*
following ioctl gets modem status into istat and
returns < 0 if ioctl had error.
*/
if(ioctl(fd,TIOCMGET,&istat) < 0)
{
t1= -2l;
break;
}
if( (istat & 0x20) != 0) /*if CTS line is true */
{
gettimeofday(&tvv,0);
t2= t1= tvv.tv_usec; /*save current value*/
#if INTERP
for(k1=1; t2 == t1; k1++) /*loop until tick changes*/
{
gettimeofday(&tvv,0);
t2=tvv.tv_usec;
}
t3=t2; /*now save this value*/
for(k2=1; t3 == t2; k2++) /*loop again*/
{
gettimeofday(&tvv,0);
t3=tvv.tv_usec;
}
if(k2 < k1) k2=k1; /*should never happen, ... */
t1 += tickus*(1 - (float)(k1)/(float)(k2) );
if(t1 > 1000000l) t1 -= 1000000l; /*interpolation to next sec*/
if(t1 < 0) t1 += 1000000l; /*interpolation to previous sec*/
#endif
break;
} /*end of if CTS is true ... */
} /* end of loop over j */
close(fd);
return(t1);
}