Annotation of embedaddon/ntp/ntpd/refclock_hopfpci.c, revision 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>