Annotation of embedaddon/ntp/ntpd/refclock_hopfpci.c, revision 1.1.1.1
1.1 misho 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: */
86: struct hopfclock_unit {
87: short unit; /* NTP refclock unit number */
88: char leap_status; /* leap second flag */
89: };
90: int fd; /* file descr. */
91:
92: /*
93: * Function prototypes
94: */
95: static int hopfpci_start (int, struct peer *);
96: static void hopfpci_shutdown (int, struct peer *);
97: static void hopfpci_poll (int unit, struct peer *);
98:
99: /*
100: * Transfer vector
101: */
102: struct 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: */
115: static int
116: hopfpci_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 = emalloc(sizeof(*up));
128: memset(up, 0, sizeof(*up));
129:
130: #ifndef SYS_WINNT
131:
132: fd = open(DEVICE,O_RDWR); /* try to open hopf clock device */
133:
134: #else
135: if (!OpenHopfDevice()) {
136: msyslog(LOG_ERR, "Start: %s unit: %d failed!", DEVICE, unit);
137: free(up);
138: return (0);
139: }
140: #endif
141:
142: pp = peer->procptr;
143: pp->io.clock_recv = noentry;
144: pp->io.srcclock = (caddr_t)peer;
145: pp->io.datalen = 0;
146: pp->io.fd = INVALID_SOCKET;
147: pp->unitptr = (caddr_t)up;
148:
149: get_systime(&pp->lastrec);
150:
151: /*
152: * Initialize miscellaneous peer variables
153: */
154: memcpy((char *)&pp->refid, REFID, 4);
155: peer->precision = PRECISION;
156: pp->clockdesc = DESCRIPTION;
157: up->leap_status = 0;
158: up->unit = (short) unit;
159: return (1);
160: }
161:
162:
163: /*
164: * hopfpci_shutdown - shut down the clock
165: */
166: static void
167: hopfpci_shutdown(
168: int unit,
169: struct peer *peer
170: )
171: {
172:
173: #ifndef SYS_WINNT
174: close(fd);
175: #else
176: CloseHopfDevice();
177: #endif
178: if (NULL != peer->procptr->unitptr)
179: free(peer->procptr->unitptr);
180: }
181:
182:
183: /*
184: * hopfpci_poll - called by the transmit procedure
185: */
186: static void
187: hopfpci_poll(
188: int unit,
189: struct peer *peer
190: )
191: {
192: struct refclockproc *pp;
193: HOPFTIME m_time;
194:
195: pp = peer->procptr;
196:
197: #ifndef SYS_WINNT
198: ioctl(fd,HOPF_CLOCK_GET_UTC,&m_time);
199: #else
200: GetHopfSystemTime(&m_time);
201: #endif
202: pp->polls++;
203:
204: pp->day = ymd2yd(m_time.wYear,m_time.wMonth,m_time.wDay);
205: pp->hour = m_time.wHour;
206: pp->minute = m_time.wMinute;
207: pp->second = m_time.wSecond;
208: pp->nsec = m_time.wMilliseconds * 1000000;
209: if (m_time.wStatus & LEWAPWAR)
210: pp->leap = LEAP_ADDSECOND;
211: else
212: pp->leap = LEAP_NOWARNING;
213:
214: snprintf(pp->a_lastcode, sizeof(pp->a_lastcode),
215: "ST: %02X T: %02d:%02d:%02d.%03ld D: %02d.%02d.%04d",
216: m_time.wStatus, pp->hour, pp->minute, pp->second,
217: pp->nsec / 1000000, m_time.wDay, m_time.wMonth,
218: m_time.wYear);
219: pp->lencode = (u_short)strlen(pp->a_lastcode);
220:
221: get_systime(&pp->lastrec);
222:
223: /*
224: * If clock has no valid status then report error and exit
225: */
226: if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INVALID) { /* time ok? */
227: refclock_report(peer, CEVNT_BADTIME);
228: pp->leap = LEAP_NOTINSYNC;
229: return;
230: }
231:
232: /*
233: * Test if time is running on internal quarz
234: * if CLK_FLAG1 is set, sychronize even if no radio operation
235: */
236:
237: if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INTERNAL){
238: if ((pp->sloppyclockflag & CLK_FLAG1) == 0) {
239: refclock_report(peer, CEVNT_BADTIME);
240: pp->leap = LEAP_NOTINSYNC;
241: return;
242: }
243: }
244:
245: if (!refclock_process(pp)) {
246: refclock_report(peer, CEVNT_BADTIME);
247: return;
248: }
249: pp->lastref = pp->lastrec;
250: refclock_receive(peer);
251: record_clock_stats(&peer->srcadr, pp->a_lastcode);
252: return;
253: }
254:
255: #else
256: int refclock_hopfpci_bs;
257: #endif /* REFCLOCK */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>