FreeBSD/contrib/ntp/ntpd/refclock_wwv.c
/*
 * wwv_epoch - epoch scanner
 *
 * This routine extracts data signals from the 100-Hz subcarrier. It
 * scans the receiver second epoch to determine the signal amplitudes
 * and pulse timings. Receiver synchronization is determined by the
 * minute sync pulse detected in the wwv_rf() routine and the second
 * sync pulse detected in the wwv_epoch() routine. The transmitted
 * signals are delayed by the propagation delay, receiver delay and
 * filter delay of this program. Delay corrections are introduced
 * separately for WWV and WWVH. 
 *
 * Most communications radios use a highpass filter in the audio stages,
 * which can do nasty things to the subcarrier phase relative to the
 * sync pulses. Therefore, the data subcarrier reference phase is
 * disciplined using the hardlimited quadrature-phase signal sampled at
 * the same time as the in-phase signal. The phase tracking loop uses
 * phase adjustments of plus-minus one sample (125 us). 
 */
epoch scanner
This routine extracts data signals from the 100-Hz subcarrier. It
scans the receiver second epoch to determine the signal amplitudes
and pulse timings. Receiver synchronization is determined by the
minute sync pulse detected in the wwv_rf() routine and the second
sync pulse detected in the wwv_epoch() routine. The transmitted
signals are delayed by the propagation delay, receiver delay and
filter delay of this program. Delay corrections are introduced
separately for WWV and WWVH.

Most communications radios use a highpass filter in the audio stages,
which can do nasty things to the subcarrier phase relative to the
sync pulses. Therefore, the data subcarrier reference phase is
disciplined using the hardlimited quadrature-phase signal sampled at
the same time as the in-phase signal. The phase tracking loop uses
phase adjustments of plus-minus one sample (125 us).
epoch scanner This routine extracts data signals from the 100 - Hz subcarrier . It scans the receiver second epoch to determine the signal amplitudes and pulse timings . Receiver synchronization is determined by the minute sync pulse detected in the wwv_rf () routine and the second sync pulse detected in the wwv_epoch () routine . The transmitted signals are delayed by the propagation delay receiver delay and filter delay of this program . Delay corrections are introduced separately for WWV and WWVH . Most communications radios use a highpass filter in the audio stages which can do nasty things to the subcarrier phase relative to the sync pulses . Therefore the data subcarrier reference phase is disciplined using the hardlimited quadrature - phase signal sampled at the same time as the in - phase signal . The phase tracking loop uses phase adjustments of plus - minus one sample ( 125 us ) .
static void
wwv_epoch(
	struct peer *peer	
	)
{
	struct refclockproc *pp;
	struct wwvunit *up;
	struct chan *cp;
	static double sigmin, sigzer, sigone, engmax, engmin;
	pp = peer->procptr;
	up = pp->unitptr;
	cp = &up->mitig[up->achan];
	if (cp->wwv.amp > cp->wwv.syneng) 
		cp->wwv.syneng = cp->wwv.amp;
	if (cp->wwvh.amp > cp->wwvh.syneng) 
		cp->wwvh.syneng = cp->wwvh.amp;
	if (up->rphase == 800 * MS)
		up->repoch = up->yepoch;
	if (up->rphase == 15 * MS)
		sigmin = sigzer = sigone = up->irig;
	if (up->rphase == 200 * MS) {
		sigzer = up->irig;
		engmax = sqrt(up->irig * up->irig + up->qrig *
		    up->qrig);
		up->datpha = up->qrig / up->avgint;
		if (up->datpha >= 0) {
			up->datapt++;
			if (up->datapt >= 80)
				up->datapt -= 80;
		} else {
			up->datapt--;
			if (up->datapt < 0)
				up->datapt += 80;
		}
	}
	else if (up->rphase == 500 * MS)
		sigone = up->irig;
	up->rphase++;
	if (up->mphase % WWV_SEC == up->repoch) {
		up->status &= ~(DGATE | BGATE);
		engmin = sqrt(up->irig * up->irig + up->qrig *
		    up->qrig);
		up->datsig = engmax;
		up->datsnr = wwv_snr(engmax, engmin);
		if (engmax < DTHR || up->datsnr < DSNR) {
			up->status |= DGATE;
			wwv_rsec(peer, 0);
		} else {
			sigzer -= sigone;
			sigone -= sigmin;
			wwv_rsec(peer, sigone - sigzer);
		}
		if (up->status & (DGATE | BGATE))
			up->errcnt++;
		if (up->errcnt > MAXERR)
			up->alarm |= LOWERR;
		wwv_gain(peer);
		cp = &up->mitig[up->achan];
		cp->wwv.syneng = 0;
		cp->wwvh.syneng = 0;
		up->rphase = 0;
	}
}
static void wwv_epoch ( struct peer * peer ) { struct refclockproc * pp ; struct wwvunit * up ; struct chan * cp ; static double sigmin , sigzer , sigone , engmax , engmin ; pp = peer -> procptr ; up = pp -> unitptr ; cp = & up -> mitig [ up -> achan ] ; if ( cp -> wwv . amp > cp -> wwv . syneng ) cp -> wwv . syneng = cp -> wwv . amp ; if ( cp -> wwvh . amp > cp -> wwvh . syneng ) cp -> wwvh . syneng = cp -> wwvh . amp ; if ( up -> rphase == 800 * MS ) up -> repoch = up -> yepoch ; if ( up -> rphase == 15 * MS ) sigmin = sigzer = sigone = up -> irig ; if ( up -> rphase == 200 * MS ) { sigzer = up -> irig ; engmax = sqrt ( up -> irig * up -> irig + up -> qrig * up -> qrig ) ; up -> datpha = up -> qrig / up -> avgint ; if ( up -> datpha >= 0 ) { up -> datapt ++ ; if ( up -> datapt >= 80 ) up -> datapt -= 80 ; } else { up -> datapt -- ; if ( up -> datapt < 0 ) up -> datapt += 80 ; } } else if ( up -> rphase == 500 * MS ) sigone = up -> irig ; up -> rphase ++ ; if ( up -> mphase % WWV_SEC == up -> repoch ) { up -> status &= ~ ( DGATE | BGATE ) ; engmin = sqrt ( up -> irig * up -> irig + up -> qrig * up -> qrig ) ; up -> datsig = engmax ; up -> datsnr = wwv_snr ( engmax , engmin ) ; if ( engmax < DTHR || up -> datsnr < DSNR ) { up -> status |= DGATE ; wwv_rsec ( peer , 0 ) ; } else { sigzer -= sigone ; sigone -= sigmin ; wwv_rsec ( peer , sigone - sigzer ) ; } if ( up -> status & ( DGATE | BGATE ) ) up -> errcnt ++ ; if ( up -> errcnt > MAXERR ) up -> alarm |= LOWERR ; wwv_gain ( peer ) ; cp = & up -> mitig [ up -> achan ] ; cp -> wwv . syneng = 0 ; cp -> wwvh . syneng = 0 ; up -> rphase = 0 ; } }
wwv_epoch - epoch scanner
 This routine extracts data signals from the 100-Hz subcarrier.
wwv_epoch - epoch scanner This routine extracts data signals from the 100 - Hz subcarrier .
/* peer structure pointer */ /*
	 * Find the maximum minute sync pulse energy for both the
	 * WWV and WWVH stations. This will be used later for channel
	 * and station mitigation. Also set the seconds epoch at 800 ms
	 * well before the end of the second to make sure we never set
	 * the epoch backwards.
	 */ /*
	 * Use the signal amplitude at epoch 15 ms as the noise floor.
	 * This gives a guard time of +-15 ms from the beginning of the
	 * second until the second pulse rises at 30 ms. There is a
	 * compromise here; we want to delay the sample as long as
	 * possible to give the radio time to change frequency and the
	 * AGC to stabilize, but as early as possible if the second
	 * epoch is not exact.
	 */ /*
	 * Latch the data signal at 200 ms. Keep this around until the
	 * end of the second. Use the signal energy as the peak to
	 * compute the SNR. Use the Q sample to adjust the 100-Hz
	 * reference oscillator phase.
	 */ /*
	 * Latch the data signal at 500 ms. Keep this around until the
	 * end of the second.
	 */ /*
	 * At the end of the second crank the clock state machine and
	 * adjust the codec gain. Note the epoch is buffered from the
	 * center of the second in order to avoid jitter while the
	 * seconds synch is diddling the epoch. Then, determine the true
	 * offset and update the median filter in the driver interface.
	 *
	 * Use the energy at the end of the second as the noise to
	 * compute the SNR for the data pulse. This gives a better
	 * measurement than the beginning of the second, especially when
	 * returning from the probe channel. This gives a guard time of
	 * 30 ms from the decay of the longest pulse to the rise of the
	 * next pulse.
	 */ /*
		 * If the amplitude or SNR is below threshold, average a
		 * 0 in the the integrators; otherwise, average the
		 * bipolar signal. This is done to avoid noise polution.
		 */