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

📄 refclock_chu.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
}/* * chu_uart - maximum likelihood UART * * This routine updates a shift register holding the last 11 envelope * samples. It then computes the slice level and span over these samples * and determines the tentative data bits and distance. The calling * program selects over the last eight survivors the one with maximum * distance to determine the decoded character. */static voidchu_uart(	struct surv *sp,	/* survivor structure pointer */	double	sample		/* baseband signal */	){	double	es_max, es_min;	/* max/min envelope */	double	slice;		/* slice level */	double	dist;		/* distance */	double	dtemp;	int	i;	/*	 * Save the sample and shift right. At the same time, measure	 * the maximum and minimum over all eleven samples.	 */	es_max = -1e6;	es_min = 1e6;	sp->shift[0] = sample;	for (i = 11; i > 0; i--) {		sp->shift[i] = sp->shift[i - 1];		if (sp->shift[i] > es_max)			es_max = sp->shift[i];		if (sp->shift[i] < es_min)			es_min = sp->shift[i];	}	/*	 * Determine the slice level midway beteen the maximum and	 * minimum and the span as the maximum less the minimum. Compute	 * the distance on the assumption the first and last bits must	 * be mark, the second space and the rest either mark or space.	 */ 	slice = (es_max + es_min) / 2.;	dist = 0;	sp->uart = 0;	for (i = 1; i < 12; i++) {		sp->uart <<= 1;		dtemp = sp->shift[i];		if (dtemp > slice)			sp->uart |= 0x1;		if (i == 1 || i == 11) {			dist += dtemp - es_min;		} else if (i == 10) {			dist += es_max - dtemp;		} else {			if (dtemp > slice)				dist += dtemp - es_min;			else				dist += es_max - dtemp;		}	}	sp->es_max = es_max;	sp->es_min = es_min;	sp->dist = dist / (11 * (es_max - es_min));}#endif /* HAVE_AUDIO *//* * chu_serial_receive - receive data from the serial device */static voidchu_serial_receive(	struct recvbuf *rbufp	/* receive buffer structure pointer */	){	struct chuunit *up;	struct refclockproc *pp;	struct peer *peer;	u_char	*dpt;		/* receive buffer pointer */	peer = (struct peer *)rbufp->recv_srcclock;	pp = peer->procptr;	up = (struct chuunit *)pp->unitptr;	/*	 * Initialize pointers and read the timecode and timestamp.	 */	up->timestamp = rbufp->recv_time;	dpt = (u_char *)&rbufp->recv_space;	chu_decode(peer, *dpt);}/* * chu_decode - decode the character data */static voidchu_decode(	struct peer *peer,	/* peer structure pointer */	int	hexhex		/* data character */	){	struct refclockproc *pp;	struct chuunit *up;	l_fp	tstmp;		/* timestamp temp */	double	dtemp;	pp = peer->procptr;	up = (struct chuunit *)pp->unitptr;	/*	 * If the interval since the last character is greater than the	 * longest burst, process the last burst and start a new one. If	 * the interval is less than this but greater than two	 * characters, consider this a noise burst and reject it.	 */	tstmp = up->timestamp;	if (L_ISZERO(&up->laststamp))		up->laststamp = up->timestamp;	L_SUB(&tstmp, &up->laststamp);	up->laststamp = up->timestamp;	LFPTOD(&tstmp, dtemp);	if (dtemp > BURST * CHAR) {		chu_burst(peer);		up->ndx = 0;	} else if (dtemp > 2.5 * CHAR) {		up->ndx = 0;	}	/*	 * Append the character to the current burst and append the	 * timestamp to the timestamp list.	 */	if (up->ndx < BURST) {		up->cbuf[up->ndx] = hexhex & 0xff;		up->cstamp[up->ndx] = up->timestamp;		up->ndx++;	}}/* * chu_burst - search for valid burst format */static voidchu_burst(	struct peer *peer	){	struct chuunit *up;	struct refclockproc *pp;	int	i;	pp = peer->procptr;	up = (struct chuunit *)pp->unitptr;	/*	 * Correlate a block of five characters with the next block of	 * five characters. The burst distance is defined as the number	 * of bits that match in the two blocks for format A and that	 * match the inverse for format B.	 */	if (up->ndx < MINCHAR) {		up->status |= RUNT;		return;	}	up->burdist = 0;	for (i = 0; i < 5 && i < up->ndx - 5; i++)		up->burdist += chu_dist(up->cbuf[i], up->cbuf[i + 5]);	/*	 * If the burst distance is at least MINDIST, this must be a	 * format A burst; if the value is not greater than -MINDIST, it	 * must be a format B burst. If the B burst is perfect, we	 * believe it; otherwise, it is a noise burst and of no use to	 * anybody.	 */	if (up->burdist >= MINDIST) {		chu_a(peer, up->ndx);	} else if (up->burdist <= -MINDIST) {		chu_b(peer, up->ndx);	} else {		up->status |= NOISE;		return;	}	/*	 * If this is a valid burst, wait a guard time of ten seconds to	 * allow for more bursts, then arm the poll update routine to	 * process the minute. Don't do this if this is called from the	 * timer interrupt routine.	 */	if (peer->outdate != current_time)		peer->nextdate = current_time + 10;}/* * chu_b - decode format B burst */static voidchu_b(	struct peer *peer,	int	nchar	){	struct	refclockproc *pp;	struct	chuunit *up;	u_char	code[11];	/* decoded timecode */	char	tbuf[80];	/* trace buffer */	l_fp	offset;		/* timestamp offset */	int	i;	pp = peer->procptr;	up = (struct chuunit *)pp->unitptr;	/*	 * In a format B burst, a character is considered valid only if	 * the first occurrence matches the last occurrence. The burst	 * is considered valid only if all characters are valid; that	 * is, only if the distance is 40. Note that once a valid frame	 * has been found errors are ignored.	 */	sprintf(tbuf, "chuB %04x %2d %2d ", up->status, nchar,	    -up->burdist);	for (i = 0; i < nchar; i++)		sprintf(&tbuf[strlen(tbuf)], "%02x", up->cbuf[i]);	if (pp->sloppyclockflag & CLK_FLAG4)		record_clock_stats(&peer->srcadr, tbuf);#ifdef DEBUG	if (debug)		printf("%s\n", tbuf);#endif	if (up->burdist > -40) {		up->status |= BFRAME;		return;	}	up->status |= BVALID;	/*	 * Convert the burst data to internal format. If this succeeds,	 * save the timestamps for later.	 */	for (i = 0; i < 5; i++) {		code[2 * i] = hexchar[up->cbuf[i] & 0xf];		code[2 * i + 1] = hexchar[(up->cbuf[i] >>		    4) & 0xf];	}	if (sscanf((char *)code, "%1x%1d%4d%2d%2x", &up->leap, &up->dut,	    &pp->year, &up->tai, &up->dst) != 5) {		up->status |= BFORMAT;		return;	}	if (up->leap & 0x8)		up->dut = -up->dut;	offset.l_ui = 31;	offset.l_f = 0;	for (i = 0; i < nchar && i < 10; i++) {		up->tstamp[up->ntstamp] = up->cstamp[i];		L_SUB(&up->tstamp[up->ntstamp], &offset);		L_ADD(&offset, &up->charstamp);		if (up->ntstamp < MAXSTAGE) 			up->ntstamp++;	}}/* * chu_a - decode format A burst */static voidchu_a(	struct peer *peer,	int nchar	){	struct refclockproc *pp;	struct chuunit *up;	char	tbuf[80];	/* trace buffer */	l_fp	offset;		/* timestamp offset */	int	val;		/* distance */	int	temp;	int	i, j, k;	pp = peer->procptr;	up = (struct chuunit *)pp->unitptr;	/*	 * Determine correct burst phase. There are three cases	 * corresponding to in-phase, one character early or one	 * character late. These cases are distinguished by the position	 * of the framing digits x6 at positions 0 and 5 and x3 at	 * positions 4 and 9. The correct phase is when the distance	 * relative to the framing digits is maximum. The burst is valid	 * only if the maximum distance is at least MINSYNC.	 */	up->syndist = k = 0;	val = -16;	for (i = -1; i < 2; i++) {		temp = up->cbuf[i + 4] & 0xf;		if (i >= 0)			temp |= (up->cbuf[i] & 0xf) << 4;		val = chu_dist(temp, 0x63);		temp = (up->cbuf[i + 5] & 0xf) << 4;		if (i + 9 < nchar)			temp |= up->cbuf[i + 9] & 0xf;		val += chu_dist(temp, 0x63);		if (val > up->syndist) {			up->syndist = val;			k = i;		}	}	temp = (up->cbuf[k + 4] >> 4) & 0xf;	if (temp > 9 || k + 9 >= nchar || temp != ((up->cbuf[k + 9] >>	    4) & 0xf))		temp = 0;#ifdef HAVE_AUDIO	if (up->fd_audio)		sprintf(tbuf, "chuA %04x %4.0f %2d %2d %2d %2d %1d ",		    up->status, up->maxsignal, nchar, up->burdist, k,		    up->syndist, temp);	else		sprintf(tbuf, "chuA %04x %2d %2d %2d %2d %1d ",		    up->status, nchar, up->burdist, k, up->syndist,		    temp);#else	sprintf(tbuf, "chuA %04x %2d %2d %2d %2d %1d ", up->status,	    nchar, up->burdist, k, up->syndist, temp);#endif /* HAVE_AUDIO */	for (i = 0; i < nchar; i++)		sprintf(&tbuf[strlen(tbuf)], "%02x",		    up->cbuf[i]);	if (pp->sloppyclockflag & CLK_FLAG4)		record_clock_stats(&peer->srcadr, tbuf);#ifdef DEBUG	if (debug)		printf("%s\n", tbuf);#endif	if (up->syndist < MINSYNC) {		up->status |= AFRAME;		return;	}	/*	 * A valid burst requires the first seconds number to match the	 * last seconds number. If so, the burst timestamps are	 * corrected to the current minute and saved for later	 * processing. In addition, the seconds decode is advanced from	 * the previous burst to the current one.	 */	if (temp != 0) {		pp->second = 30 + temp;		offset.l_ui = 30 + temp;		offset.l_f = 0;		i = 0;		if (k < 0)			offset = up->charstamp;		else if (k > 0)			i = 1;		for (; i < nchar && i < k + 10; i++) {			up->tstamp[up->ntstamp] = up->cstamp[i];			L_SUB(&up->tstamp[up->ntstamp], &offset);			L_ADD(&offset, &up->charstamp);			if (up->ntstamp < MAXSTAGE) 				up->ntstamp++;		}		while (temp > up->prevsec) {			for (j = 15; j > 0; j--) {				up->decode[9][j] = up->decode[9][j - 1];				up->decode[19][j] =				    up->decode[19][j - 1];			}			up->decode[9][j] = up->decode[19][j] = 0;			up->prevsec++;		}	}	i = -(2 * k);	for (j = 0; j < nchar; j++) {		if (i < 0 || i > 19) {			i += 2;			continue;		}		up->decode[i][up->cbuf[j] & 0xf]++;		i++;		up->decode[i][(up->cbuf[j] >> 4) & 0xf]++;		i++;	}	up->status |= AVALID;	up->burstcnt++;}/* * chu_poll - called by the transmit procedure */static voidchu_poll(	int unit,	struct peer *peer	/* peer structure pointer */	){	struct refclockproc *pp;	struct chuunit *up;	l_fp	offset;	char	synchar, qual, leapchar;	int	minset, i;	double	dtemp;	pp = peer->procptr;	up = (struct chuunit *)pp->unitptr;	if (pp->coderecv == pp->codeproc)

⌨️ 快捷键说明

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