📄 refclock_true.c
字号:
true_doevent(peer, e_F51); break; default: true_debug(peer, "got F%02d - ignoring\n", i); break; } return; } /* * Timecode: " TRUETIME Mk III" * (from a TM/TMD clock during initialization.) */ if (strcmp(pp->lastcode, " TRUETIME Mk III") == 0) { true_doevent(peer, e_F18); NLOG(NLOG_CLOCKSTATUS) { msyslog(LOG_INFO, "TM/TMD: %s", pp->lastcode); } return; } /* * Timecode: "N03726428W12209421+000033" * 1 2 * 0123456789012345678901234 * (from a TCU during initialization) */ if ((pp->lastcode[0] == 'N' || pp->lastcode[0] == 'S') && (pp->lastcode[9] == 'W' || pp->lastcode[9] == 'E') && pp->lastcode[18] == '+') { true_doevent(peer, e_Location); NLOG(NLOG_CLOCKSTATUS) { msyslog(LOG_INFO, "TCU-800: %s", pp->lastcode); } return; } /* * Timecode: "ddd:hh:mm:ssQ" * (from all clocks supported by this driver.) */ if (pp->lastcode[3] == ':' && pp->lastcode[6] == ':' && pp->lastcode[9] == ':' && sscanf(pp->lastcode, "%3d:%2d:%2d:%2d%c", &pp->day, &pp->hour, &pp->minute, &pp->second, &sync) == 5) { /* * Adjust the synchronize indicator according to timecode */ if (sync != ' ' && sync != '.' && sync != '*') pp->leap = LEAP_NOTINSYNC; else { pp->leap = 0; pp->lasttime = current_time; } true_doevent(peer, e_TS);#ifdef PPS720 /* If it's taken more than 65ms to get here, we'll lose. */ if ((pp->sloppyclockflag & CLK_FLAG4) && up->pcl720init) { l_fp off;#ifdef ATOM /* * find out what time it really is. Include * the count from the PCL720 */ if (!clocktime(pp->day, pp->hour, pp->minute, pp->second, GMT, pp->lastrec.l_ui, &pp->yearstart, &off.l_ui)) { refclock_report(peer, CEVNT_BADTIME); return; }#endif pp->usec = true_sample720();#ifdef ATOM TVUTOTSF(pp->usec, off.l_uf);#endif /* * Stomp all over the timestamp that was pulled out * of the input stream. It's irrelevant since we've * adjusted the input time to reflect now (via pp->usec) * rather than when the data was collected. */ get_systime(&pp->lastrec);#ifdef ATOM /* * Create a true offset for feeding to pps_sample() */ L_SUB(&off, &pp->lastrec); pps_sample(&off);#endif true_debug(peer, "true_sample720: %luus\n", pp->usec); }#endif /* * The clock will blurt a timecode every second but we only * want one when polled. If we havn't been polled, bail out. */ if (!up->polled) return; true_doevent(peer, e_Poll); /* * Process the new sample in the median filter and determine * the reference clock offset and dispersion. We use lastrec * as both the reference time and receive time in order to * avoid being cute, like setting the reference time later * than the receive time, which may cause a paranoid protocol * module to chuck out the data. */ if (!refclock_process(pp, NSAMPLES, NSAMPLES)) { true_debug(peer, "Error processing timecodes. \n"); refclock_report(peer, CEVNT_BADTIME); return; } refclock_receive(peer, &pp->offset, 0, pp->dispersion, &pp->lastrec, &pp->lastrec, pp->leap); /* * We have succedded in answering the poll. * Turn off the flag and return */ up->polled = 0; return; } /* * No match to known timecodes, report failure and return */ refclock_report(peer, CEVNT_BADREPLY); true_debug(peer, "No match to known timecodes. \n"); return;}/* * true_send - time to send the clock a signal to cough up a time sample */static voidtrue_send(peer, cmd) struct peer *peer; char *cmd;{ struct refclockproc *pp; pp = peer->procptr; if (!(pp->sloppyclockflag & CLK_FLAG1)) { register int len = strlen(cmd); true_debug(peer, "Send '%s'\n", cmd); if (write(pp->io.fd, cmd, len) != len) refclock_report(peer, CEVNT_FAULT); else pp->polls++; }}/* * state machine for initializing and controlling a clock */static voidtrue_doevent(peer, event) struct peer *peer; enum true_event event;{ struct true_unit *up; struct refclockproc *pp; pp = peer->procptr; up = (struct true_unit *)pp->unitptr; if (event != e_TS) { NLOG(NLOG_CLOCKSTATUS) { msyslog(LOG_INFO, "TRUE: clock %s, state %s, event %s", typeStr(up->type), stateStr(up->state), eventStr(event)); } } true_debug(peer, "clock %s, state %s, event %s\n", typeStr(up->type), stateStr(up->state), eventStr(event)); switch (up->type) { case t_goes: switch (event) { case e_Init: /* FALLTHROUGH */ case e_Satellite: /* * Switch back to on-second time codes and return. */ true_send(peer, "C"); up->state = s_Start; break; case e_Poll: /* * After each poll, check the station (satellite). */ true_send(peer, "P"); /* No state change needed. */ break; default: break; } /* FALLTHROUGH */ case t_omega: switch (event) { case e_Init: true_send(peer, "C"); up->state = s_Start; break; case e_TS: if (up->state != s_Start && up->state != s_Auto) { true_send(peer, "\03\r"); break; } up->state = s_Auto; break; default: break; } break; case t_tm: switch (event) { case e_Init: true_send(peer, "F18\r"); up->state = s_Init; break; case e_F18: true_send(peer, "F50\r"); up->state = s_F18; break; case e_F50: true_send(peer, "F51\r"); up->state = s_F50; break; case e_F51: true_send(peer, "F08\r"); up->state = s_Start; break; case e_TS: if (up->state != s_Start && up->state != s_Auto) { true_send(peer, "\03\r"); break; } up->state = s_Auto; break; default: break; } break; case t_tcu: switch (event) { case e_Init: true_send(peer, "MD3\r"); /* GPS Synch'd Gen. */ true_send(peer, "TSU\r"); /* UTC, not GPS. */ true_send(peer, "AU\r"); /* Auto Timestamps. */ up->state = s_Start; break; case e_TS: if (up->state != s_Start && up->state != s_Auto) { true_send(peer, "\03\r"); break; } up->state = s_Auto; break; default: break; } break; case t_unknown: switch (up->state) { case s_Base: if (event != e_Init) abort(); true_send(peer, "P\r"); up->state = s_InqGOES; break; case s_InqGOES: switch (event) { case e_Satellite: up->type = t_goes; true_doevent(peer, e_Init); break; case e_Init: /*FALLTHROUGH*/ case e_Huh: /*FALLTHROUGH*/ case e_TS: up->state = s_InqOmega; true_send(peer, "C\r"); break; default: abort(); } break; case s_InqOmega: switch (event) { case e_TS: up->type = t_omega; up->state = s_Auto; /* Inq side-effect. */ break; case e_Init: /*FALLTHROUGH*/ case e_Huh: up->state = s_InqTM; true_send(peer, "F18\r"); break; default: abort(); } break; case s_InqTM: switch (event) { case e_F18: up->type = t_tm; true_doevent(peer, e_Init); break; case e_Init: /*FALLTHROUGH*/ case e_Huh: true_send(peer, "PO\r"); up->state = s_InqTCU; break; default: abort(); } break; case s_InqTCU: switch (event) { case e_Location: up->type = t_tcu; true_doevent(peer, e_Init); break; case e_Init: /*FALLTHROUGH*/ case e_Huh: up->state = s_Base; sleep(1); /* XXX */ break; default: abort(); } break; } break; default: abort(); /* NOTREACHED */ }#ifdef PPS720 if ((pp->sloppyclockflag & CLK_FLAG4) && !up->pcl720init) { /* Make counter trigger on gate0, count down from 65535. */ pcl720_load(PCL720_IOB, PCL720_CTR, i8253_oneshot, 65535); /* * (These constants are OK since * they represent hardware maximums.) */ NLOG(NLOG_CLOCKINFO) { msyslog(LOG_NOTICE, "PCL-720 initialized"); } up->pcl720init++; }#endif}/* * true_poll - called by the transmit procedure */static voidtrue_poll(unit, peer) int unit; struct peer *peer;{ struct true_unit *up; struct refclockproc *pp; /* * You don't need to poll this clock. It puts out timecodes * once per second. If asked for a timestamp, take note. * The next time a timecode comes in, it will be fed back. */ pp = peer->procptr; up = (struct true_unit *)pp->unitptr; if (up->pollcnt > 0) up->pollcnt--; else { true_doevent(peer, e_Init); refclock_report(peer, CEVNT_TIMEOUT); } /* * polled every 64 seconds. Ask true_receive to hand in a * timestamp. */ up->polled = 1; pp->polls++;}#ifdef PPS720/* * true_sample720 - sample the PCL-720 */static u_longtrue_sample720(){ unsigned long f; /* We wire the PCL-720's 8253.OUT0 to bit 0 of connector 3. * If it is not being held low now, we did not get called * within 65535us. */ if (inb(pcl720_data_16_23(PCL720_IOB)) & 0x01) { NLOG(NLOG_CLOCKINFO) { msyslog(LOG_NOTICE, "PCL-720 out of synch"); } return (0); } f = (65536 - pcl720_read(PCL720_IOB, PCL720_CTR));#ifdef PPS720_DEBUG msyslog(LOG_DEBUG, "PCL-720: %luus", f);#endif return (f);}#endif#endif /*defined(REFCLOCK) && defined(TRUETIME)*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -