MCPcopy Create free account
hub / github.com/F-Stack/f-stack / hardpps

Function hardpps

freebsd/kern/kern_ntptime.c:773–964  ·  view source on GitHub ↗

* hardpps() - discipline CPU clock oscillator to external PPS signal * * This routine is called at each PPS interrupt in order to discipline * the CPU clock oscillator to the PPS signal. There are two independent * first-order feedback loops, one for the phase, the other for the * frequency. The phase loop measures and grooms the PPS phase offset * and leaves it in a handy spot for the secon

Source from the content-addressed store, hash-verified

771 * nsec - hardware counter at PPS
772 */
773void
774hardpps(struct timespec *tsp, long nsec)
775{
776 long u_sec, u_nsec, v_nsec; /* temps */
777 l_fp ftemp;
778
779 NTP_LOCK();
780
781 /*
782 * The signal is first processed by a range gate and frequency
783 * discriminator. The range gate rejects noise spikes outside
784 * the range +-500 us. The frequency discriminator rejects input
785 * signals with apparent frequency outside the range 1 +-500
786 * PPM. If two hits occur in the same second, we ignore the
787 * later hit; if not and a hit occurs outside the range gate,
788 * keep the later hit for later comparison, but do not process
789 * it.
790 */
791 time_status |= STA_PPSSIGNAL | STA_PPSJITTER;
792 time_status &= ~(STA_PPSWANDER | STA_PPSERROR);
793 pps_valid = PPS_VALID;
794 u_sec = tsp->tv_sec;
795 u_nsec = tsp->tv_nsec;
796 if (u_nsec >= (NANOSECOND >> 1)) {
797 u_nsec -= NANOSECOND;
798 u_sec++;
799 }
800 v_nsec = u_nsec - pps_tf[0].tv_nsec;
801 if (u_sec == pps_tf[0].tv_sec && v_nsec < NANOSECOND - MAXFREQ)
802 goto out;
803 pps_tf[2] = pps_tf[1];
804 pps_tf[1] = pps_tf[0];
805 pps_tf[0].tv_sec = u_sec;
806 pps_tf[0].tv_nsec = u_nsec;
807
808 /*
809 * Compute the difference between the current and previous
810 * counter values. If the difference exceeds 0.5 s, assume it
811 * has wrapped around, so correct 1.0 s. If the result exceeds
812 * the tick interval, the sample point has crossed a tick
813 * boundary during the last second, so correct the tick. Very
814 * intricate.
815 */
816 u_nsec = nsec;
817 if (u_nsec > (NANOSECOND >> 1))
818 u_nsec -= NANOSECOND;
819 else if (u_nsec < -(NANOSECOND >> 1))
820 u_nsec += NANOSECOND;
821 pps_fcount += u_nsec;
822 if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ)
823 goto out;
824 time_status &= ~STA_PPSJITTER;
825
826 /*
827 * A three-stage median filter is used to help denoise the PPS
828 * time. The median sample becomes the time offset estimate; the
829 * difference between the other two samples becomes the time
830 * dispersion (jitter) estimate.

Callers 1

pps_eventFunction · 0.85

Calls 3

lmaxFunction · 0.85
qminFunction · 0.85
tc_getfrequencyFunction · 0.85

Tested by

no test coverage detected