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

📄 refclock_chu.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * refclock_chu - clock driver for Canadian CHU time/frequency station */#ifdef HAVE_CONFIG_H#include <config.h>#endif#if defined(REFCLOCK) && defined(CLOCK_CHU)#include "ntpd.h"#include "ntp_io.h"#include "ntp_refclock.h"#include "ntp_calendar.h"#include "ntp_stdlib.h"#include <stdio.h>#include <ctype.h>#include <math.h>#ifdef HAVE_AUDIO#include "audio.h"#endif /* HAVE_AUDIO */#define ICOM 	1		/* undefine to suppress ICOM code */#ifdef ICOM#include "icom.h"#endif /* ICOM *//* * Audio CHU demodulator/decoder * * This driver synchronizes the computer time using data encoded in * radio transmissions from Canadian time/frequency station CHU in * Ottawa, Ontario. Transmissions are made continuously on 3330 kHz, * 7335 kHz and 14670 kHz in upper sideband, compatible AM mode. An * ordinary shortwave receiver can be tuned manually to one of these * frequencies or, in the case of ICOM receivers, the receiver can be * tuned automatically using this program as propagation conditions * change throughout the day and night. * * The driver receives, demodulates and decodes the radio signals when * connected to the audio codec of a suported workstation hardware and * operating system. These include Solaris, SunOS, FreeBSD, NetBSD and * Linux. In this implementation, only one audio driver and codec can be * supported on a single machine. * * The driver can be compiled to use a Bell 103 compatible modem or * modem chip to receive the radio signal and demodulate the data. * Alternatively, the driver can be compiled to use the audio codec of * the Sun workstation or another with compatible audio drivers. In the * latter case, the driver implements the modem using DSP routines, so * the radio can be connected directly to either the microphone on line * input port. In either case, the driver decodes the data using a * maximum likelihood technique which exploits the considerable degree * of redundancy available to maximize accuracy and minimize errors. * * The CHU time broadcast includes an audio signal compatible with the * Bell 103 modem standard (mark = 2225 Hz, space = 2025 Hz). It consist * of nine, ten-character bursts transmitted at 300 bps and beginning * each second from second 31 to second 39 of the minute. Each character * consists of eight data bits plus one start bit and two stop bits to * encode two hex digits. The burst data consist of five characters (ten * hex digits) followed by a repeat of these characters. In format A, * the characters are repeated in the same polarity; in format B, the * characters are repeated in the opposite polarity. * * Format A bursts are sent at seconds 32 through 39 of the minute in * hex digits * *	6dddhhmmss6dddhhmmss * * The first ten digits encode a frame marker (6) followed by the day * (ddd), hour (hh in UTC), minute (mm) and the second (ss). Since * format A bursts are sent during the third decade of seconds the tens * digit of ss is always 3. The driver uses this to determine correct * burst synchronization. These digits are then repeated with the same * polarity. * * Format B bursts are sent at second 31 of the minute in hex digits * *	xdyyyyttaaxdyyyyttaa * * The first ten digits encode a code (x described below) followed by * the DUT1 (d in deciseconds), Gregorian year (yyyy), difference TAI - * UTC (tt) and daylight time indicator (aa) peculiar to Canada. These * digits are then repeated with inverted polarity. * * The x is coded * * 1 Sign of DUT (0 = +) * 2 Leap second warning. One second will be added. * 4 Leap second warning. One second will be subtracted. * 8 Even parity bit for this nibble. * * By design, the last stop bit of the last character in the burst * coincides with 0.5 second. Since characters have 11 bits and are * transmitted at 300 bps, the last stop bit of the first character * coincides with 0.5 - 10 * 11/300 = 0.133 second. Depending on the * UART, character interrupts can vary somewhere between the beginning * of bit 9 and end of bit 11. These eccentricities can be corrected * along with the radio propagation delay using fudge time 1. * * Debugging aids * * The timecode format used for debugging and data recording includes * data helpful in diagnosing problems with the radio signal and serial * connections. With debugging enabled (-d on the ntpd command line), * the driver produces one line for each burst in two formats * corresponding to format A and B. Following is format A: * *	n b f s m code * * where n is the number of characters in the burst (0-11), b the burst * distance (0-40), f the field alignment (-1, 0, 1), s the * synchronization distance (0-16), m the burst number (2-9) and code * the burst characters as received. Note that the hex digits in each * character are reversed, so the burst * *	10 38 0 16 9 06851292930685129293 * * is interpreted as containing 11 characters with burst distance 38, * field alignment 0, synchronization distance 16 and burst number 9. * The nibble-swapped timecode shows day 58, hour 21, minute 29 and * second 39. * * When the audio driver is compiled, format A is preceded by * the current gain (0-255) and relative signal level (0-9999). The * receiver folume control should be set so that the gain is somewhere * near the middle of the range 0-255, which results in a signal level * near 1000. * * Following is format B: *  *	n b s code * * where n is the number of characters in the burst (0-11), b the burst * distance (0-40), s the synchronization distance (0-40) and code the * burst characters as received. Note that the hex digits in each * character are reversed and the last ten digits inverted, so the burst * *	11 40 1091891300ef6e76ecff * * is interpreted as containing 11 characters with burst distance 40. * The nibble-swapped timecode shows DUT1 +0.1 second, year 1998 and TAI * - UTC 31 seconds. * * In addition to the above, the reference timecode is updated and * written to the clockstats file and debug score after the last burst * received in the minute. The format is * *	qq yyyy ddd hh:mm:ss nn dd tt * * where qq are the error flags, as described below, yyyy is the year, * ddd the day, hh:mm:ss the time of day, nn the number of format A * bursts received during the previous minute, dd the decoding distance * and tt the number of timestamps. The error flags are cleared after * every update. * * Fudge factors * * For accuracies better than the low millisceconds, fudge time1 can be * set to the radio propagation delay from CHU to the receiver. This can * be done conviently using the minimuf program. * * Fudge flag4 causes the dubugging output described above to be * recorded in the clockstats file. When the audio driver is compiled, * fudge flag2 selects the audio input port, where 0 is the mike port * (default) and 1 is the line-in port. It does not seem useful to * select the compact disc player port. Fudge flag3 enables audio * monitoring of the input signal. For this purpose, the monitor gain is * set to a default value. * * The audio codec code is normally compiled in the driver if the * architecture supports it (HAVE_AUDIO defined), but is used only if * the link /dev/chu_audio is defined and valid. The serial port code is * always compiled in the driver, but is used only if the autdio codec * is not available and the link /dev/chu%d is defined and valid. * * The ICOM code is normally compiled in the driver if selected (ICOM * defined), but is used only if the link /dev/icom%d is defined and * valid and the mode keyword on the server configuration command * specifies a nonzero mode (ICOM ID select code). The C-IV speed is * 9600 bps if the high order 0x80 bit of the mode is zero and 1200 bps * if one. The C-IV trace is turned on if the debug level is greater * than one. *//* * Interface definitions */#define	SPEED232	B300	/* uart speed (300 baud) */#define	PRECISION	(-10)	/* precision assumed (about 1 ms) */#define	REFID		"CHU"	/* reference ID */#define	DEVICE		"/dev/chu%d" /* device name and unit */#define	SPEED232	B300	/* UART speed (300 baud) */#ifdef ICOM#define TUNE		.001	/* offset for narrow filter (kHz) */#define DWELL		5	/* minutes in a probe cycle */#define NCHAN		3	/* number of channels */#define ISTAGE		3	/* number of integrator stages */#endif /* ICOM */#ifdef HAVE_AUDIO/* * Audio demodulator definitions */#define SECOND		8000	/* nominal sample rate (Hz) */#define BAUD		300	/* modulation rate (bps) */#define OFFSET		128	/* companded sample offset */#define SIZE		256	/* decompanding table size */#define	MAXSIG		6000.	/* maximum signal level */#define	MAXCLP		100	/* max clips above reference per s */#define LIMIT		1000.	/* soft limiter threshold */#define AGAIN		6.	/* baseband gain */#define LAG		10	/* discriminator lag */#define	DEVICE_AUDIO	"/dev/audio" /* device name */#define	DESCRIPTION	"CHU Audio/Modem Receiver" /* WRU */#define	AUDIO_BUFSIZ	240	/* audio buffer size (30 ms) */#else#define	DESCRIPTION	"CHU Modem Receiver" /* WRU */#endif /* HAVE_AUDIO *//* * Decoder definitions */#define CHAR		(11. / 300.) /* character time (s) */#define	FUDGE		.185	/* offset to first stop bit (s) */#define BURST		11	/* max characters per burst */#define MINCHAR		9	/* min characters per burst */#define MINDIST		28	/* min burst distance (of 40)  */#define MINBURST	4	/* min bursts in minute */#define MINSYNC		8	/* min sync distance (of 16) */#define MINSTAMP	20	/* min timestamps (of 60) */#define METRIC		50.	/* min channel metric */#define PANIC		1440	/* panic timeout (m) */#define HOLD		30	/* reach hold (m) *//* * Hex extension codes (>= 16) */#define HEX_MISS	16	/* miss _ */#define HEX_SOFT	17	/* soft error * */#define HEX_HARD	18	/* hard error = *//* * Status bits (status) */#define RUNT		0x0001	/* runt burst */#define NOISE		0x0002	/* noise burst */#define BFRAME		0x0004	/* invalid format B frame sync */#define BFORMAT		0x0008	/* invalid format B data */#define AFRAME		0x0010	/* invalid format A frame sync */#define AFORMAT		0x0020	/* invalid format A data */#define DECODE		0x0040	/* invalid data decode */#define STAMP		0x0080	/* too few timestamps */#define AVALID		0x0100	/* valid A frame */#define BVALID		0x0200	/* valid B frame */#define INSYNC		0x0400	/* clock synchronized *//* * Alarm status bits (alarm) * * These alarms are set at the end of a minute in which at least one * burst was received. SYNERR is raised if the AFRAME or BFRAME status * bits are set during the minute, FMTERR is raised if the AFORMAT or * BFORMAT status bits are set, DECERR is raised if the DECODE status * bit is set and TSPERR is raised if the STAMP status bit is set. */#define SYNERR		0x01	/* frame sync error */#define FMTERR		0x02	/* data format error */#define DECERR		0x04	/* data decoding error */#define TSPERR		0x08	/* insufficient data */#ifdef HAVE_AUDIO/* * Maximum likelihood UART structure. There are eight of these * corresponding to the number of phases. */ struct surv {	double	shift[12];	/* mark register */	double	es_max, es_min;	/* max/min envelope signals */	double	dist;		/* sample distance */	int	uart;		/* decoded character */};#endif /* HAVE_AUDIO */#ifdef ICOM/* * CHU station structure. There are three of these corresponding to the * three frequencies. */struct xmtr {	double	integ[ISTAGE];	/* circular integrator */	double	metric;		/* integrator sum */	int	iptr;		/* integrator pointer */	int	probe;		/* dwells since last probe */};#endif /* ICOM *//* * CHU unit control structure */struct chuunit {	u_char	decode[20][16];	/* maximum likelihood decoding matrix */	l_fp	cstamp[BURST];	/* character timestamps */	l_fp	tstamp[MAXSTAGE]; /* timestamp samples */	l_fp	timestamp;	/* current buffer timestamp */	l_fp	laststamp;	/* last buffer timestamp */	l_fp	charstamp;	/* character time as a l_fp */	int	errflg;		/* error flags */	int	status;		/* status bits */	char	ident[5];	/* station ID and channel */#ifdef ICOM	int	fd_icom;	/* ICOM file descriptor */	int	chan;		/* data channel */	int	achan;		/* active channel */	int	dwell;		/* dwell cycle */	struct xmtr xmtr[NCHAN]; /* station metric */#endif /* ICOM */	/*	 * Character burst variables	 */	int	cbuf[BURST];	/* character buffer */	int	ntstamp;	/* number of timestamp samples */	int	ndx;		/* buffer start index */	int	prevsec;	/* previous burst second */	int	burdist;	/* burst distance */	int	syndist;	/* sync distance */	int	burstcnt;	/* format A bursts this minute */	/*	 * Format particulars	 */	int	leap;		/* leap/dut code */	int	dut;		/* UTC1 correction */	int	tai;		/* TAI - UTC correction */	int	dst;		/* Canadian DST code */#ifdef HAVE_AUDIO	/*	 * Audio codec variables	 */	int	fd_audio;	/* audio port file descriptor */	double	comp[SIZE];	/* decompanding table */	int	port;		/* codec port */	int	gain;		/* codec gain */	int	mongain;	/* codec monitor gain */	int	clipcnt;	/* sample clip count */	int	seccnt;		/* second interval counter */	/*	 * Modem variables	 */	l_fp	tick;		/* audio sample increment */	double	bpf[9];		/* IIR bandpass filter */	double	disc[LAG];	/* discriminator shift register */	double	lpf[27];	/* FIR lowpass filter */	double	monitor;	/* audio monitor */	double	maxsignal;	/* signal level */	int	discptr;	/* discriminator pointer */	/*	 * Maximum likelihood UART variables	 */	double	baud;		/* baud interval */	struct surv surv[8];	/* UART survivor structures */	int	decptr;		/* decode pointer */	int	dbrk;		/* holdoff counter */#endif /* HAVE_AUDIO */};/* * Function prototypes */static	int	chu_start	P((int, struct peer *));static	void	chu_shutdown	P((int, struct peer *));static	void	chu_receive	P((struct recvbuf *));static	void	chu_poll	P((int, struct peer *));/* * More function prototypes */static	void	chu_decode	P((struct peer *, int));static	void	chu_burst	P((struct peer *));static	void	chu_clear	P((struct peer *));static	void	chu_a		P((struct peer *, int));static	void	chu_b		P((struct peer *, int));static	int	chu_dist	P((int, int));static	double	chu_major	P((struct peer *));#ifdef HAVE_AUDIOstatic	void	chu_uart	P((struct surv *, double));static	void	chu_rf		P((struct peer *, double));static	void	chu_gain	P((struct peer *));static	void	chu_audio_receive P((struct recvbuf *rbufp));#endif /* HAVE_AUDIO */#ifdef ICOMstatic	int	chu_newchan	P((struct peer *, double));#endif /* ICOM */static	void	chu_serial_receive P((struct recvbuf *rbufp));/* * Global variables */static char hexchar[] = "0123456789abcdef_*=";#ifdef ICOM/* * Note the tuned frequencies are 1 kHz higher than the carrier. CHU * transmits on USB with carrier so we can use AM and the narrow SSB * filter. */static double qsy[NCHAN] = {3.330, 7.335, 14.670}; /* freq (MHz) */#endif /* ICOM *//* * Transfer vector */struct	refclock refclock_chu = {	chu_start,		/* start up driver */	chu_shutdown,		/* shut down driver */	chu_poll,		/* transmit poll message */

⌨️ 快捷键说明

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