Annotation of embedaddon/ntp/ntpd/refclock_tt560.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * refclock_tt560 - clock driver for the TrueTime 560 IRIG-B decoder
                      3:  */
                      4: 
                      5: #ifdef HAVE_CONFIG_H
                      6: #include <config.h>
                      7: #endif
                      8: 
                      9: #if defined(REFCLOCK) && defined(CLOCK_TT560)
                     10: 
                     11: #include "ntpd.h"
                     12: #include "ntp_io.h"
                     13: #include "ntp_refclock.h"
                     14: #include "ntp_unixtime.h"
                     15: #include "sys/tt560_api.h"
                     16: #include "ntp_stdlib.h"
                     17: 
                     18: #include <stdio.h>
                     19: #include <ctype.h>
                     20: 
                     21: /*
                     22:  * This driver supports the TrueTime 560 IRIG-B decoder for the PCI bus.
                     23:  */ 
                     24: 
                     25: /*
                     26:  * TT560 interface definitions
                     27:  */
                     28: #define        DEVICE           "/dev/tt560%d" /* device name and unit */
                     29: #define        PRECISION       (-20)   /* precision assumed (1 us) */
                     30: #define        REFID           "IRIG"  /* reference ID */
                     31: #define        DESCRIPTION     "TrueTime 560 IRIG-B PCI Decoder"
                     32: 
                     33: /*
                     34:  * Unit control structure
                     35:  */
                     36: struct tt560unit {
                     37:        tt_mem_space_t   *tt_mem;       /* mapped address of PCI board */
                     38:        time_freeze_reg_t tt560rawt;    /* data returned from PCI board */
                     39: };
                     40: 
                     41: typedef union byteswap_u
                     42: {
                     43:     unsigned int long_word;
                     44:     unsigned char byte[4];
                     45: } byteswap_t;
                     46: 
                     47: /*
                     48:  * Function prototypes
                     49:  */
                     50: static int     tt560_start     (int, struct peer *);
                     51: static void    tt560_shutdown  (int, struct peer *);
                     52: static void    tt560_poll      (int unit, struct peer *);
                     53: 
                     54: /*
                     55:  * Transfer vector
                     56:  */
                     57: struct refclock refclock_tt560 = {
                     58:        tt560_start,            /* clock_start    */
                     59:        tt560_shutdown,         /* clock_shutdown */
                     60:        tt560_poll,             /* clock_poll     */
                     61:        noentry,                /* clock_control (not used) */
                     62:        noentry,                /* clock_init    (not used) */
                     63:        noentry,                /* clock_buginfo (not used) */
                     64:        NOFLAGS                 /* clock_flags   (not used) */
                     65: };
                     66: 
                     67: 
                     68: /*
                     69:  * tt560_start - open the TT560 device and initialize data for processing
                     70:  */
                     71: static int
                     72: tt560_start(
                     73:        int unit,
                     74:        struct peer *peer
                     75:        )
                     76: {
                     77:        register struct tt560unit *up;
                     78:        struct refclockproc *pp;
                     79:        char device[20];
                     80:        int     fd;
                     81:         caddr_t membase;
                     82: 
                     83:        /*
                     84:         * Open TT560 device
                     85:         */
                     86:        (void)sprintf(device, DEVICE, unit);
                     87:        fd = open(device, O_RDWR);
                     88:        if (fd == -1) {
                     89:                msyslog(LOG_ERR, "tt560_start: open of %s: %m", device);
                     90:                return (0);
                     91:        }
                     92: 
                     93:        /*
                     94:         * Map the device registers into user space.
                     95:         */
                     96:        membase = mmap ((caddr_t) 0, TTIME_MEMORY_SIZE,
                     97:                        PROT_READ | PROT_WRITE,
                     98:                        MAP_SHARED, fd, (off_t)0);
                     99: 
                    100:        if (membase == (caddr_t) -1) {
                    101:                msyslog(LOG_ERR, "tt560_start: mapping of %s: %m", device);
                    102:                (void) close(fd);
                    103:                return (0);
                    104:        }
                    105: 
                    106:        /*
                    107:         * Allocate and initialize unit structure
                    108:         */
                    109:        if (!(up = (struct tt560unit *) emalloc(sizeof(struct tt560unit)))) {
                    110:                (void) close(fd);
                    111:                return (0);
                    112:        }
                    113:        memset((char *)up, 0, sizeof(struct tt560unit));
                    114:        up->tt_mem = (tt_mem_space_t *)membase;
                    115:        pp = peer->procptr;
                    116:        pp->io.clock_recv = noentry;
                    117:        pp->io.srcclock = (caddr_t)peer;
                    118:        pp->io.datalen = 0;
                    119:        pp->io.fd = fd;
                    120:        pp->unitptr = (caddr_t)up;
                    121: 
                    122:        /*
                    123:         * Initialize miscellaneous peer variables
                    124:         */
                    125:        peer->precision = PRECISION;
                    126:        peer->burst = NSTAGE;
                    127:        pp->clockdesc = DESCRIPTION;
                    128:        memcpy((char *)&pp->refid, REFID, 4);
                    129:        return (1);
                    130: }
                    131: 
                    132: 
                    133: /*
                    134:  * tt560_shutdown - shut down the clock
                    135:  */
                    136: static void
                    137: tt560_shutdown(
                    138:        int unit,
                    139:        struct peer *peer
                    140:        )
                    141: {
                    142:        register struct tt560unit *up;
                    143:        struct refclockproc *pp;
                    144: 
                    145:        pp = peer->procptr;
                    146:        up = (struct tt560unit *)pp->unitptr;
                    147:        io_closeclock(&pp->io);
                    148:        free(up);
                    149: }
                    150: 
                    151: 
                    152: /*
                    153:  * tt560_poll - called by the transmit procedure
                    154:  */
                    155: static void
                    156: tt560_poll(
                    157:        int unit,
                    158:        struct peer *peer
                    159:        )
                    160: {
                    161:        register struct tt560unit *up;
                    162:        struct refclockproc       *pp;
                    163:        time_freeze_reg_t         *tp;
                    164:        tt_mem_space_t            *mp;
                    165: 
                    166:        int i;
                    167:        unsigned int *p_time_t, *tt_mem_t;
                    168: 
                    169:        /*
                    170:         * This is the main routine. It snatches the time from the TT560
                    171:         * board and tacks on a local timestamp.
                    172:         */
                    173:        pp = peer->procptr;
                    174:        up = (struct tt560unit *)pp->unitptr;
                    175:        mp = up->tt_mem;
                    176:        tp = &up->tt560rawt;
                    177: 
                    178:        p_time_t = (unsigned int *)tp;
                    179:        tt_mem_t = (unsigned int *)&mp->time_freeze_reg;
                    180: 
                    181:        *tt_mem_t = 0;          /* update the time freeze register */
                    182:                                /* and copy time stamp to memory */
                    183:        for (i=0; i < TIME_FREEZE_REG_LEN; i++) {
                    184:            *p_time_t = byte_swap(*tt_mem_t);
                    185:             p_time_t++;
                    186:             tt_mem_t++;
                    187:        }
                    188: 
                    189:        get_systime(&pp->lastrec);
                    190:        pp->polls++;
                    191: 
                    192:        /*
                    193:         * We get down to business, check the timecode format and decode
                    194:         * its contents. If the timecode has invalid length or is not in
                    195:         * proper format, we declare bad format and exit. Note: we
                    196:         * can't use the sec/usec conversion produced by the driver,
                    197:         * since the year may be suspect. All format error checking is
                    198:         * done by the sprintf() and sscanf() routines.
                    199:         */
                    200:        sprintf(pp->a_lastcode,
                    201:            "%1x%1x%1x %1x%1x:%1x%1x:%1x%1x.%1x%1x%1x%1x%1x%1x %1x",
                    202:            tp->hun_day,  tp->tens_day,  tp->unit_day,
                    203:                          tp->tens_hour, tp->unit_hour,
                    204:                          tp->tens_min,  tp->unit_min,
                    205:                          tp->tens_sec,  tp->unit_sec,
                    206:            tp->hun_ms,   tp->tens_ms,   tp->unit_ms,
                    207:            tp->hun_us,   tp->tens_us,   tp->unit_us,
                    208:            tp->status);
                    209:            pp->lencode = strlen(pp->a_lastcode);
                    210: #ifdef DEBUG
                    211:        if (debug)
                    212:                printf("tt560: time %s timecode %d %s\n",
                    213:                   ulfptoa(&pp->lastrec, 6), pp->lencode,
                    214:                   pp->a_lastcode);
                    215: #endif
                    216:        if (sscanf(pp->a_lastcode, "%3d %2d:%2d:%2d.%6ld", 
                    217:                   &pp->day, &pp->hour, &pp->minute, &pp->second, &pp->usec)
                    218:            != 5) {
                    219:                refclock_report(peer, CEVNT_BADTIME);
                    220:                return;
                    221:        }
                    222:        if ((tp->status & 0x6) != 0x6)
                    223:                pp->leap = LEAP_NOTINSYNC;
                    224:        else
                    225:                pp->leap = LEAP_NOWARNING;
                    226:        if (!refclock_process(pp)) {
                    227:                refclock_report(peer, CEVNT_BADTIME);
                    228:                return;
                    229:        }
                    230:        if (peer->burst > 0)
                    231:                return;
                    232:        if (pp->coderecv == pp->codeproc) {
                    233:                refclock_report(peer, CEVNT_TIMEOUT);
                    234:                return;
                    235:        }
                    236:        record_clock_stats(&peer->srcadr, pp->a_lastcode);
                    237:        refclock_receive(peer);
                    238:        peer->burst = NSTAGE;
                    239: }
                    240: 
                    241: /******************************************************************
                    242:  *
                    243:  *  byte_swap
                    244:  *
                    245:  *  Inputs: 32 bit integer
                    246:  *
                    247:  *  Output: byte swapped 32 bit integer.
                    248:  *
                    249:  *  This routine is used to compensate for the byte alignment
                    250:  *  differences between big-endian and little-endian integers.
                    251:  *
                    252:  ******************************************************************/
                    253: static unsigned int
                    254: byte_swap(unsigned int input_num)
                    255: {
                    256:     byteswap_t    byte_swap;
                    257:     unsigned char temp;
                    258: 
                    259:     byte_swap.long_word = input_num;
                    260: 
                    261:     temp              = byte_swap.byte[3];
                    262:     byte_swap.byte[3] = byte_swap.byte[0];
                    263:     byte_swap.byte[0] = temp;
                    264: 
                    265:     temp              = byte_swap.byte[2];
                    266:     byte_swap.byte[2] = byte_swap.byte[1];
                    267:     byte_swap.byte[1] = temp;
                    268: 
                    269:     return (byte_swap.long_word);
                    270: }
                    271: 
                    272: #else
                    273: int refclock_tt560_bs;
                    274: #endif /* REFCLOCK */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>