pps-api.c 2.51 KB
Newer Older
1
/*
2 3 4 5 6 7 8 9 10
 *
 * Try to run this code to see what the PPS-API finds. You give it the
 * device as argument and you may have to modify the pp.mode = BLA assignment.
 *
 * Code originally by Poul-Henning Kemp.
 *
 * Copyright 2015 by the NTPsec project contributors
 *  SPDX-License-Identifier: BSD-2-Clause
 */
11

12
#include <stdlib.h>
13 14 15 16 17 18
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <time.h>
#include <sys/timepps.h>
Hal Murray's avatar
Hal Murray committed
19
#include <unistd.h>
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

#define timespecsub(vvp, uvp)                                           \
        do {                                                            \
                (vvp)->tv_sec -= (uvp)->tv_sec;                         \
                (vvp)->tv_nsec -= (uvp)->tv_nsec;                       \
                if ((vvp)->tv_nsec < 0) {                               \
                        (vvp)->tv_sec--;                                \
                        (vvp)->tv_nsec += 1000000000;                   \
                }                                                       \
        } while (0)


void
Chew(struct timespec *tsa, struct timespec *tsc, unsigned sa, unsigned sc)
{
	struct timespec ts;

37 38
	printf("%ld.%09ld ", tsa->tv_sec, tsa->tv_nsec);
	printf("%ld.%09ld ", tsc->tv_sec, tsc->tv_nsec);
39 40 41 42 43 44 45 46 47
	printf("%u %u ", sa, sc);

	ts = *tsc;
	timespecsub(&ts,tsa);
	printf("%.9f ", ts.tv_sec + ts.tv_nsec / 1e9);
	printf("\n");
	fflush(stdout);
}

48 49
static int err(int out, const char *legend)
{
50
    fprintf(stderr, "ntpfrob: %s\n", legend);
51 52 53
    exit(out);
}

54
void ppscheck(char *device)
55 56 57 58 59 60 61 62 63
{
	int fd;
	pps_info_t pi;
	pps_params_t pp;
	pps_handle_t ph;
	int i, mode;
	u_int olda, oldc;
	struct timespec to;

64 65
	if (device == NULL)
		device = "/dev/cuaa1";
66
	setbuf(stdout, 0);
67
	fd = open(device, O_RDONLY);
68
	if (fd < 0) 
69
		err(1, device);
70 71 72 73 74 75 76 77 78 79
	i = time_pps_create(fd, &ph);
	if (i < 0)
		err(1, "time_pps_create");

	i = time_pps_getcap(ph, &mode);
	if (i < 0)
		err(1, "time_pps_getcap");

	pp.mode = PPS_CAPTUREASSERT | PPS_ECHOASSERT;
	pp.mode = PPS_CAPTUREBOTH;
80
	/* pp.mode = PPS_CAPTUREASSERT; */
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

	i = time_pps_setparams(ph, &pp);
	if (i < 0)
		err(1, "time_pps_setparams");

	while (1) {
		to.tv_nsec = 0;
		to.tv_sec = 0;
		i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
		if (i < 0)
			err(1, "time_pps_fetch");
		if (olda == pi.assert_sequence &&
		    oldc == pi.clear_sequence) {
			usleep(10000);
			continue;
		}

		Chew(&pi.assert_timestamp, &pi.clear_timestamp,
			pi.assert_sequence, pi.clear_sequence);
		olda = pi.assert_sequence;
		oldc = pi.clear_sequence;
	}
}
104 105

/* end */