#include #include #include #include #define filename "/dev/ttyS0" #define DEBUG 0 #define PPS_ECHO 0 #define CLEAR_EDGE 1 #define ASSERT_EDGE 0 /* Vladimir Smotlacha, vs@cesnet.cz 21.12.2001 */ int fd; long last_sequence; struct timespec ts; /* last timestamp */ pps_params_t pps_params; /* pps parameters */ pps_info_t pps_info; /* last pps data */ pps_handle_t handle; /* pps handlebars */ init (int clear_edge) { int capability; int edge; last_sequence = 0; fd = open (filename, O_RDWR, 0); time_pps_create(fd, &handle); if (time_pps_getcap(handle, &capability) < 0) { printf( "time_pps_getcap failed: %m\n"); return (0); } memset(&pps_params, 0, sizeof(pps_params_t)); if (clear_edge) pps_params.mode = capability & PPS_CAPTURECLEAR; else pps_params.mode = capability & PPS_CAPTUREASSERT; if (!pps_params.mode) { printf( "invalid capture edge %d\n", !clear_edge); return (0); } #ifdef PPS_ECHO pps_params.mode |= PPS_ECHOCLEAR; #endif pps_params.mode |= PPS_TSFMT_TSPEC; if (time_pps_setparams(handle, &pps_params) < 0) { printf( "time_pps_setparams failed: %m\n"); return (0); } edge = 0; /* clear all previous binds */ if (time_pps_kcbind(handle, PPS_KC_HARDPPS, edge, PPS_TSFMT_TSPEC) < 0) { printf( "time_pps_kcbind failed: %m\n"); return (0); } time_pps_getparams(handle, &pps_params); printf("capability 0x%x version %d mode 0x%x\n", capability, pps_params.api_version, pps_params.mode); return (1); } /* * Get PPSAPI timestamps. * * Return 0 on failure and 1 on success. */ static int pps(void) { struct timespec timeout; if (handle == 0) return (0); timeout.tv_sec = 0; timeout.tv_nsec = 0; if (time_pps_fetch(handle, PPS_TSFMT_TSPEC, &pps_info, &timeout) < 0) return (0); if (pps_params.mode & PPS_CAPTUREASSERT) { if (pps_info.assert_sequence == last_sequence) return (0); ts = pps_info.assert_timestamp; last_sequence = pps_info.assert_sequence; } else if (pps_params.mode & PPS_CAPTURECLEAR) { if (pps_info.clear_sequence == last_sequence) return (0); ts = pps_info.clear_timestamp; last_sequence = pps_info.clear_sequence; } else { return (0); } return (1); } /* record of offset between local time and PPS */ static void record(struct timespec t) { long d_sec, nsec; int hod,min,s, x_sec; d_sec = t.tv_sec % 86400L; hod = d_sec / 3600; x_sec = d_sec - hod * 3600; min = x_sec / 60; s = x_sec - min * 60; nsec = t.tv_nsec; if (nsec > 5e8) nsec -= 1e9; printf ("%2d:%02d:%02d %6ld %09ld\n", hod,min,s, d_sec, nsec); } /* delays given time in [ns] */ delay_ns (long ns) { struct timespec ns_delay; ns_delay.tv_sec = 0, ns_delay.tv_nsec = ns; nanosleep (&ns_delay,&ns_delay); } main () { int i; init(CLEAR_EDGE); while (1) { delay_ns (2e8); if (pps()) record (ts); } }