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 >
C/C++ Source or Header  |  1996-11-18  |  4KB  |  119 lines

  1. #include "sizint.h"
  2. LONG gettck()
  3. {
  4. /*
  5.     this subroutine looks at the clear to send
  6.     line on the device specified by dv in the .h
  7.     file, and reads the time when the line becomes true.  
  8.     The value returned is the usec portion of the local 
  9.     time.  The subroutine interpolats between ticks if 
  10.     tickus is not zero and if the constant INTERP is
  11.     defined as not 0.  The return value is in usec and
  12.     is always between 0 and 999999.  Under normal
  13.     circumstances, the caller assumes that values
  14.     between 1 and 499999 imply that the integer number
  15.     of ticks is correct so that the local clock
  16.     is fast whereas values between 500000 and 999999
  17.     imply that the local clock is slow.  This routine
  18.     must therefore be called often enough so that the
  19.     local time will not have drifted off by 0.5 seconds.
  20.     If this is not done, the caller will likely drive
  21.     the local time to be a full integer second wrong.
  22.  
  23.     the return time will be negative on an error.
  24.     values are:
  25.     -1 cannot open serial port.
  26.     -2 ioctl error
  27.     -3 no tick received after max number of loops.  
  28.        This may happen sometimes if the system is
  29.        heavily loaded.
  30.  
  31.  
  32.     This software was developed with US Government support
  33.     and it may not be sold, restricted or licensed.  You 
  34.     may duplicate this program provided that this notice
  35.     remains in all of the copies, and you may give it to
  36.     others provided they understand and agree to this
  37.     condition.
  38.  
  39.     This program and the time protocol it uses are under 
  40.     development and the implementation may change without 
  41.     notice.
  42.  
  43.     For questions or additional information, contact:
  44.  
  45.     Judah Levine
  46.     Time and Frequency Division
  47.     NIST/847
  48.     325 Broadway
  49.     Boulder, Colorado 80303
  50.     (303) 492 7785
  51.     judah@india.colorado.edu
  52. */
  53. #include "gettck.h"
  54. #include <sys/termios.h>
  55. #include <sys/ioctl.h>
  56. #include <sys/time.h>
  57. #include <fcntl.h>
  58. #include <stdio.h>
  59. LONG j;
  60. int fd;            /*file handle for open*/
  61. int istat;        /*modem status line*/
  62. LONG  t1,t2,t3;        /*microsecond values of the time*/
  63. struct timeval tvv;    /* holds system time when tick arrives */
  64. LONG k1,k2;        /* counters for interpolation*/
  65.     fd=open(dv, O_RDWR | O_NDELAY);  /*open port defined in .h */
  66.     if(fd < 0) return(-1l);        /* open error*/
  67.     t1= -3l;        /* return value if time-out */
  68. /*
  69.     now loop until CTS becomes true.  If the for loop ends
  70.     on its count limit then we have a time-out, which may
  71.     not be an error if the system is heavily loaded.
  72.  
  73.     Get the time when CTS becomes true and then estimate
  74.     the fraction of the tick remaining by looping until
  75.     the tick changes.  Then loop until the tick changes
  76.     again, which will be a full tick interval.  The
  77.     ratio between these two loop counters is used as
  78.     the interpolation estimate below.  Note that the
  79.     interpolation is effectively disabled if tickus = 0
  80. */
  81.     for(j=0; j<100000l; j++)  /*limit is about 4s on 5000/240 */
  82.        {
  83. /*
  84.        following ioctl gets modem status into istat and
  85.        returns < 0 if ioctl had error.
  86. */
  87.        if(ioctl(fd,TIOCMGET,&istat) < 0)
  88.           {
  89.           t1= -2l;
  90.           break;
  91.        }
  92.        if( (istat & 0x20) != 0)   /*if CTS line is true */
  93.           {
  94.           gettimeofday(&tvv,0);
  95.           t2= t1= tvv.tv_usec;        /*save current value*/
  96. #if INTERP
  97.           for(k1=1; t2 == t1; k1++)        /*loop until tick changes*/
  98.         {
  99.         gettimeofday(&tvv,0);
  100.         t2=tvv.tv_usec;
  101.           }
  102.           t3=t2;        /*now save this value*/
  103.           for(k2=1; t3 == t2; k2++)        /*loop again*/
  104.         {
  105.         gettimeofday(&tvv,0);
  106.         t3=tvv.tv_usec;
  107.          }
  108.          if(k2 < k1) k2=k1;     /*should never happen, ... */
  109.          t1 += tickus*(1 - (float)(k1)/(float)(k2) );
  110.          if(t1 > 1000000l) t1 -= 1000000l; /*interpolation to next sec*/
  111.          if(t1 < 0) t1 += 1000000l; /*interpolation to previous sec*/
  112. #endif
  113.          break;
  114.        }        /*end of if CTS is true ... */
  115.     }        /* end of loop over j */
  116.     close(fd);
  117.     return(t1);
  118. }
  119.