PageRenderTime 36ms CodeModel.GetById 19ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/ntp/ntpd/refclock_hopfpci.c

https://bitbucket.org/freebsd/freebsd-head/
C | 265 lines | 163 code | 37 blank | 65 comment | 13 complexity | 39d34d6cecf7325fed7712528d5c9260 MD5 | raw file
  1/*
  2 * refclock_hopfpci.c
  3 *
  4 * - clock driver for hopf 6039 PCI board (GPS or DCF77)
  5 * Bernd Altmeier altmeier@atlsoft.de
  6 *
  7 * latest source and further information can be found at:
  8 * http://www.ATLSoft.de/ntp
  9 *
 10 * In order to run this driver you have to install and test
 11 * the PCI-board driver for your system first.
 12 *
 13 * On Linux/UNIX
 14 *
 15 * The driver attempts to open the device /dev/hopf6039 .
 16 * The device entry will be made by the installation process of
 17 * the kernel module for the PCI-bus board. The driver sources
 18 * belongs to the delivery equipment of the PCI-board.
 19 *
 20 * On Windows NT/2000
 21 *
 22 * The driver attempts to open the device by calling the function
 23 * "OpenHopfDevice()". This function will be installed by the
 24 * Device Driver for the PCI-bus board. The driver belongs to the
 25 * delivery equipment of the PCI-board.
 26 *
 27 *
 28 * Start   21.03.2000 Revision: 01.20
 29 * changes 22.12.2000 Revision: 01.40 flag1 = 1 sync even if Quarz
 30 *
 31 */
 32
 33#ifdef HAVE_CONFIG_H
 34# include <config.h>
 35#endif
 36
 37#if defined(REFCLOCK) && defined(CLOCK_HOPF_PCI)
 38
 39#include "ntpd.h"
 40#include "ntp_io.h"
 41#include "ntp_refclock.h"
 42#include "ntp_unixtime.h"
 43#include "ntp_stdlib.h"
 44
 45#undef fileno
 46#include <ctype.h>
 47#undef fileno
 48
 49#ifndef SYS_WINNT
 50# include <sys/ipc.h>
 51# include <sys/ioctl.h>
 52# include <assert.h>
 53# include <unistd.h>
 54# include <stdio.h>
 55# include "hopf6039.h"
 56#else
 57# include "hopf_PCI_io.h"
 58#endif
 59
 60/*
 61 * hopfpci interface definitions
 62 */
 63#define PRECISION       (-10)    /* precision assumed (1 ms) */
 64#define REFID           "hopf"   /* reference ID */
 65#define DESCRIPTION     "hopf Elektronik PCI radio board"
 66
 67#define NSAMPLES        3       /* stages of median filter */
 68#ifndef SYS_WINNT
 69# define	DEVICE	"/dev/hopf6039" 	/* device name inode*/
 70#else
 71# define	DEVICE	"hopf6039" 	/* device name WinNT  */
 72#endif
 73
 74#define LEWAPWAR	0x20	/* leap second warning bit */
 75
 76#define	HOPF_OPMODE	0xC0	/* operation mode mask */
 77#define HOPF_INVALID	0x00	/* no time code available */
 78#define HOPF_INTERNAL	0x40	/* internal clock */
 79#define HOPF_RADIO	0x80	/* radio clock */
 80#define HOPF_RADIOHP	0xC0	/* high precision radio clock */
 81
 82
 83/*
 84 * hopfclock unit control structure.
 85 */
 86struct hopfclock_unit {
 87	short	unit;		/* NTP refclock unit number */
 88	char	leap_status;	/* leap second flag */
 89};
 90int	fd;			/* file descr. */
 91
 92/*
 93 * Function prototypes
 94 */
 95static  int     hopfpci_start       (int, struct peer *);
 96static  void    hopfpci_shutdown    (int, struct peer *);
 97static  void    hopfpci_poll        (int unit, struct peer *);
 98
 99/*
100 * Transfer vector
101 */
102struct  refclock refclock_hopfpci = {
103	hopfpci_start,          /* start up driver */
104	hopfpci_shutdown,       /* shut down driver */
105	hopfpci_poll,           /* transmit poll message */
106	noentry,                /* not used */
107	noentry,                /* initialize driver (not used) */
108	noentry,                /* not used */
109	NOFLAGS                 /* not used */
110};
111
112/*
113 * hopfpci_start - attach to hopf PCI board 6039
114 */
115static int
116hopfpci_start(
117	int unit,
118	struct peer *peer
119	)
120{
121	struct refclockproc *pp;
122	struct hopfclock_unit *up;
123
124	/*
125	 * Allocate and initialize unit structure
126	 */
127	up = (struct hopfclock_unit *) emalloc(sizeof(struct hopfclock_unit));
128
129	if (!(up)) {
130                msyslog(LOG_ERR, "hopfPCIClock(%d) emalloc: %m",unit);
131#ifdef DEBUG
132                printf("hopfPCIClock(%d) emalloc\n",unit);
133#endif
134		return (0);
135	}
136	memset((char *)up, 0, sizeof(struct hopfclock_unit));
137
138#ifndef SYS_WINNT
139
140 	fd = open(DEVICE,O_RDWR); /* try to open hopf clock device */
141
142#else
143	if (!OpenHopfDevice()){
144		msyslog(LOG_ERR,"Start: %s unit: %d failed!",DEVICE,unit);
145		return (0);
146	}
147#endif
148
149	pp = peer->procptr;
150	pp->io.clock_recv = noentry;
151	pp->io.srcclock = (caddr_t)peer;
152	pp->io.datalen = 0;
153	pp->io.fd = INVALID_SOCKET;
154	pp->unitptr = (caddr_t)up;
155
156	get_systime(&pp->lastrec);
157
158	/*
159	 * Initialize miscellaneous peer variables
160	 */
161	if (pp->unitptr!=0) {
162		memcpy((char *)&pp->refid, REFID, 4);
163		peer->precision = PRECISION;
164		pp->clockdesc = DESCRIPTION;
165		up->leap_status = 0;
166		up->unit = (short) unit;
167		return (1);
168	}
169	else {
170		return 0;
171	}
172}
173
174
175/*
176 * hopfpci_shutdown - shut down the clock
177 */
178static void
179hopfpci_shutdown(
180	int unit,
181	struct peer *peer
182	)
183{
184
185#ifndef SYS_WINNT
186	close(fd);
187#else
188	CloseHopfDevice();
189#endif
190}
191
192
193/*
194 * hopfpci_poll - called by the transmit procedure
195 */
196static void
197hopfpci_poll(
198	int unit,
199	struct peer *peer
200	)
201{
202	struct refclockproc *pp;
203	HOPFTIME m_time;
204
205	pp = peer->procptr;
206
207#ifndef SYS_WINNT
208	ioctl(fd,HOPF_CLOCK_GET_UTC,&m_time);
209#else
210	GetHopfSystemTime(&m_time);
211#endif
212	pp->polls++;
213
214	pp->day    = ymd2yd(m_time.wYear,m_time.wMonth,m_time.wDay);
215	pp->hour   = m_time.wHour;
216	pp->minute = m_time.wMinute;
217	pp->second = m_time.wSecond;
218	pp->nsec   = m_time.wMilliseconds * 1000000;
219	if (m_time.wStatus & LEWAPWAR)
220		pp->leap = LEAP_ADDSECOND;
221	else
222		pp->leap = LEAP_NOWARNING;
223
224	sprintf(pp->a_lastcode,"ST: %02X T: %02d:%02d:%02d.%03ld D: %02d.%02d.%04d",
225		m_time.wStatus, pp->hour, pp->minute, pp->second,
226		pp->nsec / 1000000, m_time.wDay, m_time.wMonth, m_time.wYear);
227	pp->lencode = (u_short)strlen(pp->a_lastcode);
228
229	get_systime(&pp->lastrec);
230
231	/*
232	 * If clock has no valid status then report error and exit
233	 */
234	if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INVALID) {  /* time ok? */
235		refclock_report(peer, CEVNT_BADTIME);
236		pp->leap = LEAP_NOTINSYNC;
237		return;
238	}
239
240	/*
241	 * Test if time is running on internal quarz
242	 * if CLK_FLAG1 is set, sychronize even if no radio operation
243	 */
244
245	if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INTERNAL){
246		if ((pp->sloppyclockflag & CLK_FLAG1) == 0) {
247			refclock_report(peer, CEVNT_BADTIME);
248			pp->leap = LEAP_NOTINSYNC;
249			return;
250		}
251	}
252
253	if (!refclock_process(pp)) {
254		refclock_report(peer, CEVNT_BADTIME);
255		return;
256	}
257	pp->lastref = pp->lastrec;
258	refclock_receive(peer);
259	record_clock_stats(&peer->srcadr, pp->a_lastcode);
260	return;
261}
262
263#else
264int refclock_hopfpci_bs;
265#endif /* REFCLOCK */