/* This program reads the cts-10 WWV clock and corrects the system clock based on the WWV clock. It will wake up once every CHECKTIME seconds to check the clock. to check the clock. If the clock has lost sync, it aborts. This program is usually called by clock and put in background, once the cts-10 has been configured and checked. */ #define CHECKTIME 5 #include #include #include #include #include #include #include double juliandate(); /********************************************************************/ /* getcode reads in two bytes in BCD using the designated call code */ /* It interprets the resulting code as bcd and puts it in an int. */ /********************************************************************/ int bcdgetcode( code ) int code; { char c; int i,answer; for (i=1; i<100; i++) cts10_flush(); cts10_write( (int) 0x1B); /* The lead in */ cts10_write( code ); /* The actual command */ answer= 10 * (int) cts10_read(); /* Read in the appropriate code */ answer += (int) cts10_read(); return answer; } /******************************************************************/ /* This samples the system clock, the WWV clock, and updates. */ /******************************************************************/ int set_time(arg) int arg; { struct tm tmWWV; struct timeval timeSys,timeClock; struct timezone zoneSys; int hundreths, errorcount=2; double secClock, secSys, secError; pid_t pidOld; pidOld = getprio(getpid()); setprio( getpid(), 29); /* Lock out other processes for a sec */ cts10_write( (int) 0x1B); /* capture time in buffer on CTS10 */ cts10_write( (int) 0x01); cts10_read(); /* Read the system clock */ gettimeofday(&timeSys, &zoneSys); /* Get system time */ secSys = timeSys.tv_sec + timeSys.tv_usec / 1000000.0; setprio( getpid(), pidOld); /* Ok, back down in priority */ hundreths = bcdgetcode( (int) 0x1F ); tmWWV.tm_sec = bcdgetcode( (int) 0x1E ); /* Set the second */ tmWWV.tm_min = bcdgetcode( (int) 0x1D ); tmWWV.tm_hour = bcdgetcode( (int) 0x1C ); tmWWV.tm_mday = bcdgetcode( (int) 0x1A ); tmWWV.tm_mon = bcdgetcode( (int) 0x19 ); tmWWV.tm_year = bcdgetcode( (int) 0x18 ); if (hundreths > 97) return(1); /* To close to a second - the clock board is apt to give us an incorrect time */ secClock = 3600.0 * (double) tmWWV.tm_hour + 60.0 * (double) tmWWV.tm_min + (double) tmWWV.tm_sec + 0.01 * (double) hundreths + 24 * 3600 * (juliandate(tmWWV.tm_year, tmWWV.tm_mon, tmWWV.tm_mday) - juliandate( 70, 1, 1)); secError = secSys - secClock; if ( (( secError > 6.0) || (secError < -6.0 )) && (arg==1) ) { errorcount--; return(1); } else { errorcount = 2; } if ( errorcount == 0 ) { printf("The clock has run amok! \n"); printf("By This I Mean:\n"); printf(" The CTS-10 clock is more then 6 seconds out of\n"); printf(" sync with the LynxOS clock. This should not \n"); printf(" occur; so the ctssync program is being dumped\n"); printf(" and the 486 clock will begin free-running. \n"); printf(" You may want to re-sync the clock, or take other\n"); printf(" measures.\n"); errorcount = 2; exit(1); } if ( ( secError > 0.005 ) || ( secError < -0.005) ) { setprio( getpid(), 29); /* Lock out other processes for a sec */ gettimeofday(&timeSys, &zoneSys); /* Get system time */ secSys = (double) timeSys.tv_sec + (double ) timeSys.tv_usec / 1000000.0; timeSys.tv_usec -= 1000000.0 * ((double) secError - floor( (double) secError )); while ( timeSys.tv_usec < 0 ) { timeSys.tv_usec += 1000000.0; timeSys.tv_sec -= 1.0; } while ( timeSys.tv_usec > 1000000.0 ) { timeSys.tv_usec -= 1000000.0; timeSys.tv_sec += 1.0; } timeSys.tv_sec -= floor( secError ); settimeofday(&timeSys, &zoneSys); setprio( getpid(), pidOld); /* Let 'em back. */ } return(0); } main() { int i,j; char c; set_time(0); while(1) { sleep(CHECKTIME); set_time(1); fflush(stdout); } exit(1); }