summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/refclock_hopfpci.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/ntpd/refclock_hopfpci.c')
-rw-r--r--contrib/ntp/ntpd/refclock_hopfpci.c274
1 files changed, 274 insertions, 0 deletions
diff --git a/contrib/ntp/ntpd/refclock_hopfpci.c b/contrib/ntp/ntpd/refclock_hopfpci.c
new file mode 100644
index 0000000..a9deb21
--- /dev/null
+++ b/contrib/ntp/ntpd/refclock_hopfpci.c
@@ -0,0 +1,274 @@
+/*
+ * refclock_hopfpci.c
+ *
+ * - clock driver for hopf 6039 PCI board (GPS or DCF77)
+ * Bernd Altmeier altmeier@atlsoft.de
+ *
+ * latest source and further information can be found at:
+ * http://www.ATLSoft.de/ntp
+ *
+ * In order to run this driver you have to install and test
+ * the PCI-board driver for your system first.
+ *
+ * On Linux/UNIX
+ *
+ * The driver attempts to open the device /dev/hopf6039 .
+ * The device entry will be made by the installation process of
+ * the kernel module for the PCI-bus board. The driver sources
+ * belongs to the delivery equipment of the PCI-board.
+ *
+ * On Windows NT/2000
+ *
+ * The driver attempts to open the device by calling the function
+ * "OpenHopfDevice()". This function will be installed by the
+ * Device Driver for the PCI-bus board. The driver belongs to the
+ * delivery equipment of the PCI-board.
+ *
+ *
+ * Start 21.03.2000 Revision: 01.20
+ * changes 22.12.2000 Revision: 01.40 flag1 = 1 sync even if Quarz
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_HOPF_PCI)
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_refclock.h"
+#include "ntp_unixtime.h"
+#include "ntp_stdlib.h"
+
+#undef fileno
+#include <ctype.h>
+#undef fileno
+
+#ifndef SYS_WINNT
+# include <sys/ipc.h>
+# include <assert.h>
+# include <unistd.h>
+# include <stdio.h>
+# include "hopf6039.h"
+#else
+# include "hopf_PCI_io.h"
+#endif
+
+/*
+ * hopfpci interface definitions
+ */
+#define PRECISION (-10) /* precision assumed (1 ms) */
+#define REFID "hopf" /* reference ID */
+#define DESCRIPTION "hopf Elektronik PCI radio board"
+
+#define NSAMPLES 3 /* stages of median filter */
+#ifndef SYS_WINNT
+# define DEVICE "/dev/hopf6039" /* device name inode*/
+#else
+# define DEVICE "hopf6039" /* device name WinNT */
+#endif
+
+#define LEWAPWAR 0x20 /* leap second warning bit */
+
+#define HOPF_OPMODE 0xC0 /* operation mode mask */
+#define HOPF_INVALID 0x00 /* no time code available */
+#define HOPF_INTERNAL 0x40 /* internal clock */
+#define HOPF_RADIO 0x80 /* radio clock */
+#define HOPF_RADIOHP 0xC0 /* high precision radio clock */
+
+
+/*
+ * hopfclock unit control structure.
+ */
+struct hopfclock_unit {
+ short unit; /* NTP refclock unit number */
+ char leap_status; /* leap second flag */
+};
+int fd; /* file descr. */
+
+/*
+ * Function prototypes
+ */
+static int hopfpci_start (int, struct peer *);
+static void hopfpci_shutdown (int, struct peer *);
+static void hopfpci_poll (int unit, struct peer *);
+
+/*
+ * Transfer vector
+ */
+struct refclock refclock_hopfpci = {
+ hopfpci_start, /* start up driver */
+ hopfpci_shutdown, /* shut down driver */
+ hopfpci_poll, /* transmit poll message */
+ noentry, /* not used */
+ noentry, /* initialize driver (not used) */
+ noentry, /* not used */
+ NOFLAGS /* not used */
+};
+
+/*
+ * hopfpci_start - attach to hopf PCI board 6039
+ */
+static int
+hopfpci_start(
+ int unit,
+ struct peer *peer
+ )
+{
+ struct refclockproc *pp;
+ struct hopfclock_unit *up;
+
+ /*
+ * Allocate and initialize unit structure
+ */
+ up = (struct hopfclock_unit *) emalloc(sizeof(struct hopfclock_unit));
+
+ if (!(up)) {
+ msyslog(LOG_ERR, "hopfPCIClock(%d) emalloc: %m",unit);
+#ifdef DEBUG
+ printf("hopfPCIClock(%d) emalloc\n",unit);
+#endif
+ return (0);
+ }
+ memset((char *)up, 0, sizeof(struct hopfclock_unit));
+
+#ifndef SYS_WINNT
+
+ fd = open(DEVICE,O_RDWR); /* try to open hopf clock device */
+
+#else
+ if (!OpenHopfDevice()){
+ msyslog(LOG_ERR,"Start: %s unit: %d failed!",DEVICE,unit);
+ return (0);
+ }
+#endif
+
+ pp = peer->procptr;
+ pp->io.clock_recv = noentry;
+ pp->io.srcclock = (caddr_t)peer;
+ pp->io.datalen = 0;
+ pp->io.fd = -1;
+ pp->unitptr = (caddr_t)up;
+
+ get_systime(&pp->lastrec);
+
+ /*
+ * Initialize miscellaneous peer variables
+ */
+ if (pp->unitptr!=0) {
+ memcpy((char *)&pp->refid, REFID, 4);
+ peer->precision = PRECISION;
+ pp->clockdesc = DESCRIPTION;
+ up->leap_status = 0;
+ up->unit = (short) unit;
+ return (1);
+ }
+ else {
+ return 0;
+ }
+}
+
+
+/*
+ * hopfpci_shutdown - shut down the clock
+ */
+static void
+hopfpci_shutdown(
+ int unit,
+ struct peer *peer
+ )
+{
+ struct refclockproc *pp;
+ register struct hopfpciTime *up;
+
+ pp = peer->procptr;
+ up = (struct hopfpciTime *)pp->unitptr;
+
+#ifndef SYS_WINNT
+ close(fd);
+#else
+ CloseHopfDevice();
+// UnmapViewOfFile (up);
+#endif
+}
+
+
+/*
+ * hopfpci_poll - called by the transmit procedure
+ */
+static void
+hopfpci_poll(
+ int unit,
+ struct peer *peer
+ )
+{
+ struct refclockproc *pp;
+ register struct hopfpciTime *up;
+ HOPFTIME m_time;
+
+ pp = peer->procptr;
+ up = (struct hopfpciTime *)pp->unitptr;
+
+#ifndef SYS_WINNT
+ ioctl(fd,HOPF_CLOCK_GET_UTC,&m_time);
+#else
+ GetHopfSystemTime(&m_time);
+#endif
+ pp->polls++;
+
+ pp->day = ymd2yd(m_time.wYear,m_time.wMonth,m_time.wDay);
+ pp->hour = m_time.wHour;
+ pp->minute = m_time.wMinute;
+ pp->second = m_time.wSecond;
+ pp->msec=m_time.wMilliseconds;
+ pp->usec=0;
+ if (m_time.wStatus & LEWAPWAR)
+ pp->leap = LEAP_ADDSECOND;
+ else
+ pp->leap = LEAP_NOWARNING;
+
+ sprintf(pp->a_lastcode,"ST: %02X T: %02d:%02d:%02d.%03d D: %02d.%02d.%04d",
+ m_time.wStatus, pp->hour, pp->minute, pp->second, pp->msec,
+ m_time.wDay, m_time.wMonth, m_time.wYear);
+ pp->lencode = strlen(pp->a_lastcode);
+
+ get_systime(&pp->lastrec);
+
+ /*
+ * If clock has no valid status then report error and exit
+ */
+ if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INVALID) { /* time ok? */
+ refclock_report(peer, CEVNT_BADTIME);
+ pp->leap = LEAP_NOTINSYNC;
+ return;
+ }
+
+ /*
+ * Test if time is running on internal quarz
+ * if CLK_FLAG1 is set, sychronize even if no radio operation
+ */
+
+ if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INTERNAL){
+ if ((pp->sloppyclockflag & CLK_FLAG1) == 0) {
+ refclock_report(peer, CEVNT_BADTIME);
+ pp->leap = LEAP_NOTINSYNC;
+ return;
+ }
+ }
+
+ if (!refclock_process(pp)) {
+ refclock_report(peer, CEVNT_BADTIME);
+ return;
+ }
+ refclock_receive(peer);
+
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
+
+ return;
+}
+
+#else
+int refclock_hopfpci_bs;
+#endif /* REFCLOCK */
OpenPOWER on IntegriCloud