File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / ntpd / refclock_hopfpci.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:37 2012 UTC (12 years, 1 month ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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>