⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 refclock_irig.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 3 页
字号:
	/*	 * Pulse code demodulator and reference timestamp. The decoder	 * looks for a sequence of ten bits; the first two bits must be	 * one, the last two bits must be zero. Frame synch is asserted	 * when three correct frames have been found.	 */	up->pulse = (up->pulse + 1) % 10;	if (up->pulse == 1)		up->envmax = env;	else if (up->pulse == 9)		up->envmin = env;	up->dcycles <<= 1;	if (env >= (up->envmax + up->envmin) / 2.)		up->dcycles |= 1;	up->cycles <<= 1;	if (lope >= (up->maxsignal + up->noise) / 2.)		up->cycles |= 1;	if ((up->cycles & 0x303c0f03) == 0x300c0300) {		l_fp ltemp;		int bitz;		/*		 * The PLL time constant starts out small, in order to		 * sustain a frequency tolerance of 250 PPM. It		 * gradually increases as the loop settles down. Note		 * that small wiggles are not believed, unless they		 * persist for lots of samples.		 */		if (up->pulse != 9)			up->errflg |= IRIG_ERR_SYNCH;		up->pulse = 9;		up->exing = -up->yxing;		if (fabs(up->envxing - up->envphase) <= 1) {			up->tcount++;			if (up->tcount > 50 * up->tc) {				up->tc++;				if (up->tc > MAXTC)					up->tc = MAXTC;				up->tcount = 0;				up->envxing = up->envphase;			} else {				up->exing -= up->envxing - up->envphase;			}		} else {			up->tcount = 0;			up->envxing = up->envphase;		}		/*		 * Determine a reference timestamp, accounting for the		 * codec delay and filter delay. Note the timestamp is		 * for the previous frame, so we have to backtrack for		 * this plus the delay since the last carrier positive		 * zero crossing.		 */		dtemp = up->decim * ((up->exing + BAUD) / SECOND + 1.) +		    up->fdelay;		DTOLFP(dtemp, &ltemp);		pp->lastrec = up->timestamp;		L_SUB(&pp->lastrec, &ltemp);		/*		 * The data bits are collected in ten-bit frames. The		 * first two and last two bits are determined by frame		 * sync and ignored here; the resulting patterns		 * represent zero (0-1 bits), one (2-4 bits) and		 * position identifier (5-6 bits). The remaining		 * patterns represent errors and are treated as zeros.		 */		bitz = up->dcycles & 0xfc;		switch(bitz) {		case 0x00:		case 0x80:			irig_decode(peer, BIT0);			break;		case 0xc0:		case 0xe0:		case 0xf0:			irig_decode(peer, BIT1);			break;		case 0xf8:		case 0xfc:			irig_decode(peer, BITP);			break;		default:			irig_decode(peer, 0);			up->errflg |= IRIG_ERR_DECODE;		}	}}/* * irig_decode - decode the data * * This routine assembles bits into digits, digits into subfields and * subfields into the timecode field. Bits can have values of zero, one * or position identifier. There are four bits per digit, two digits per * subfield and ten subfields per field. The last bit in every subfield * and the first bit in the first subfield are position identifiers. */static voidirig_decode(	struct	peer *peer,	/* peer structure pointer */	int	bit		/* data bit (0, 1 or 2) */	){	struct refclockproc *pp;	struct irigunit *up;#ifdef IRIG_SUCKS	int	i;#endif /* IRIG_SUCKS */	/*	 * Local variables	 */	char	syncchar;	/* sync character (Spectracom) */	char	sbs[6];		/* binary seconds since 0h */	char	spare[2];	/* mulligan digits */        pp = peer->procptr;	up = (struct irigunit *)pp->unitptr;	/*	 * Assemble subfield bits.	 */	up->bits <<= 1;	if (bit == BIT1) {		up->bits |= 1;	} else if (bit == BITP && up->lastbit == BITP) {		/*		 * Frame sync - two adjacent position identifiers.		 * Monitor the reference timestamp and wiggle the		 * clock, but only if no errors have occurred.		 */		up->bitcnt = 1;		up->fieldcnt = 0;		up->lastbit = 0;		if (up->errflg == 0) {#ifdef IRIG_SUCKS			l_fp	ltemp;			/*			 * You really don't wanna know what comes down			 * here. Leave it to say Solaris 2.8 broke the			 * nice clean audio stream, apparently affected			 * by a 5-ms sawtooth jitter. Sundown on			 * Solaris. This leaves a little twilight.			 *			 * The scheme involves differentiation, forward			 * learning and integration. The sawtooth has a			 * period of 11 seconds. The timestamp			 * differences are integrated and subtracted			 * from the signal.			 */			ltemp = pp->lastrec;			L_SUB(&ltemp, &pp->lastref);			if (ltemp.l_f < 0)				ltemp.l_i = -1;			else				ltemp.l_i = 0;			pp->lastref = pp->lastrec;			if (!L_ISNEG(&ltemp))				L_CLR(&up->wigwag);			else				L_ADD(&up->wigwag, &ltemp);			L_SUB(&pp->lastrec, &up->wigwag);			up->wiggle[up->wp] = ltemp;			/*			 * Bottom fisher. To understand this, you have			 * to know about velocity microphones and AM			 * transmitters. No further explanation is			 * offered, as this is truly a black art.			 */			up->wigbot[up->wp] = pp->lastrec;			for (i = 0; i < WIGGLE; i++) {				if (i != up->wp)					up->wigbot[i].l_ui++;				L_SUB(&pp->lastrec, &up->wigbot[i]);				if (L_ISNEG(&pp->lastrec))					L_ADD(&pp->lastrec,					    &up->wigbot[i]);				else					pp->lastrec = up->wigbot[i];			}			up->wp++;			up->wp %= WIGGLE;			up->wuggle = pp->lastrec;			refclock_process(pp);#else /* IRIG_SUCKS */			pp->lastref = pp->lastrec;			up->wuggle = pp->lastrec;			refclock_process(pp);#endif /* IRIG_SUCKS */		}		up->errflg = 0;	}	up->bitcnt = (up->bitcnt + 1) % SUBFLD;	if (up->bitcnt == 0) {		/*		 * End of subfield. Encode two hexadecimal digits in		 * little-endian timecode field.		 */		if (up->fieldcnt == 0)		    up->bits <<= 1;		if (up->xptr < 2)		    up->xptr = 2 * FIELD;		up->timecode[--up->xptr] = hexchar[(up->bits >> 5) &		    0xf];		up->timecode[--up->xptr] = hexchar[up->bits & 0xf];		up->fieldcnt = (up->fieldcnt + 1) % FIELD;		if (up->fieldcnt == 0) {			/*			 * End of field. Decode the timecode and wind			 * the clock. Not all IRIG generators have the			 * year; if so, it is nonzero after year 2000.			 * Not all have the hardware status bit; if so,			 * it is lit when the source is okay and dim			 * when bad. We watch this only if the year is			 * nonzero. Not all are configured for signature			 * control. If so, all BCD digits are set to			 * zero if the source is bad. In this case the			 * refclock_process() will reject the timecode			 * as invalid.			 */			up->xptr = 2 * FIELD;			if (sscanf((char *)up->timecode,			   "%6s%2d%c%2s%3d%2d%2d%2d", sbs, &pp->year,			    &syncchar, spare, &pp->day, &pp->hour,			    &pp->minute, &pp->second) != 8)				pp->leap = LEAP_NOTINSYNC;			else				pp->leap = LEAP_NOWARNING;			up->second = (up->second + up->decim) % 60;			if (pp->year > 0)				pp->year += 2000;			if (pp->second != up->second)				up->errflg |= IRIG_ERR_CHECK;			up->second = pp->second;			sprintf(pp->a_lastcode,			    "%02x %c %2d %3d %02d:%02d:%02d %4.0f %3d %6.3f %2d %6.1f %6.1f %s",			    up->errflg, syncchar, pp->year, pp->day,			    pp->hour, pp->minute, pp->second,			    up->maxsignal, up->gain, up->modndx,			    up->tc, up->exing * 1e6 / SECOND, up->freq *			    1e6 / SECOND, ulfptoa(&up->wuggle, 6));			pp->lencode = strlen(pp->a_lastcode);			if (pp->sloppyclockflag & CLK_FLAG4) {				record_clock_stats(&peer->srcadr,				    pp->a_lastcode);#ifdef DEBUG				if (debug)					printf("irig: %s\n",					    pp->a_lastcode);#endif /* DEBUG */			}		}	}	up->lastbit = bit;}/* * irig_poll - called by the transmit procedure * * This routine sweeps up the timecode updates since the last poll. For * IRIG-B there should be at least 60 updates; for IRIG-E there should * be at least 6. If nothing is heard, a timeout event is declared and * any orphaned timecode updates are sent to foster care.  */static voidirig_poll(	int	unit,		/* instance number (not used) */	struct peer *peer	/* peer structure pointer */	){	struct refclockproc *pp;	struct irigunit *up;	pp = peer->procptr;	up = (struct irigunit *)pp->unitptr;	if (pp->coderecv == pp->codeproc) {		refclock_report(peer, CEVNT_TIMEOUT);		return;	} else {		refclock_receive(peer);		record_clock_stats(&peer->srcadr, pp->a_lastcode);#ifdef DEBUG		if (debug)			printf("irig: %s\n", pp->a_lastcode);#endif /* DEBUG */	}	pp->polls++;	}/* * irig_gain - adjust codec gain * * This routine is called once each second. If the signal envelope * amplitude is too low, the codec gain is bumped up by four units; if * too high, it is bumped down. The decoder is relatively insensitive to * amplitude, so this crudity works just fine. The input port is set and * the error flag is cleared, mostly to be ornery. */static voidirig_gain(	struct peer *peer	/* peer structure pointer */	){	struct refclockproc *pp;	struct irigunit *up;	pp = peer->procptr;	up = (struct irigunit *)pp->unitptr;	/*	 * Apparently, the codec uses only the high order bits of the	 * gain control field. Thus, it may take awhile for changes to	 * wiggle the hardware bits.	 */	if (up->clipcnt == 0) {		up->gain += 4;		if (up->gain > MAXGAIN)			up->gain = MAXGAIN;	} else if (up->clipcnt > MAXCLP) {		up->gain -= 4;		if (up->gain < 0)			up->gain = 0;	}	audio_gain(up->gain, up->mongain, up->port);	up->clipcnt = 0;}#elseint refclock_irig_bs;#endif /* REFCLOCK */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -