lkml.org 
[lkml]   [2008]   [Feb]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH] PPS: userland header file for PPS API.
    This patch adds into the PPS's documentation directory a possible
    implementation of the PPS API (RFC 2783) by using the LinuxPPS's char
    devices.

    This file is not just an example but it can be used into real
    systems. :)

    Signed-off-by: Rodolfo Giometti <giometti@linux.it>
    ---
    Documentation/pps/timepps.h | 195 +++++++++++++++++++++++++++++++++++++++++++
    1 files changed, 195 insertions(+), 0 deletions(-)
    create mode 100644 Documentation/pps/timepps.h

    diff --git a/Documentation/pps/timepps.h b/Documentation/pps/timepps.h
    new file mode 100644
    index 0000000..2372949
    --- /dev/null
    +++ b/Documentation/pps/timepps.h
    @@ -0,0 +1,195 @@
    +/*
    + * timepps.h -- PPS API main header
    + *
    + * Copyright (C) 2005-2007 Rodolfo Giometti <giometti@linux.it>
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; either version 2 of the License, or
    + * (at your option) any later version.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program; if not, write to the Free Software
    + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    + */
    +
    +#ifndef _SYS_TIMEPPS_H_
    +#define _SYS_TIMEPPS_H_
    +
    +#include <sys/syscall.h>
    +#include <unistd.h>
    +#include <errno.h>
    +#include <linux/pps.h>
    +
    +#define LINUXPPS 1 /* signal we are using LinuxPPS */
    +
    +/*
    + * New data structures
    + */
    +
    +struct ntp_fp {
    + unsigned int integral;
    + unsigned int fractional;
    +};
    +
    +union pps_timeu {
    + struct timespec tspec;
    + struct ntp_fp ntpfp;
    + unsigned long longpad[3];
    +};
    +
    +struct pps_info {
    + unsigned long assert_sequence; /* seq. num. of assert event */
    + unsigned long clear_sequence; /* seq. num. of clear event */
    + union pps_timeu assert_tu; /* time of assert event */
    + union pps_timeu clear_tu; /* time of clear event */
    + int current_mode; /* current mode bits */
    +};
    +
    +struct pps_params {
    + int api_version; /* API version # */
    + int mode; /* mode bits */
    + union pps_timeu assert_off_tu; /* offset compensation for assert */
    + union pps_timeu clear_off_tu; /* offset compensation for clear */
    +};
    +
    +typedef int pps_handle_t; /* represents a PPS source */
    +typedef unsigned long pps_seq_t; /* sequence number */
    +typedef struct ntp_fp ntp_fp_t; /* NTP-compatible time stamp */
    +typedef union pps_timeu pps_timeu_t; /* generic data type for time stamps */
    +typedef struct pps_info pps_info_t;
    +typedef struct pps_params pps_params_t;
    +
    +#define assert_timestamp assert_tu.tspec
    +#define clear_timestamp clear_tu.tspec
    +
    +#define assert_timestamp_ntpfp assert_tu.ntpfp
    +#define clear_timestamp_ntpfp clear_tu.ntpfp
    +
    +#define assert_offset assert_off_tu.tspec
    +#define clear_offset clear_off_tu.tspec
    +
    +#define assert_offset_ntpfp assert_off_tu.ntpfp
    +#define clear_offset_ntpfp clear_off_tu.ntpfp
    +
    +/*
    + * The PPS API
    + */
    +
    +static __inline int time_pps_create(int source, pps_handle_t *handle)
    +{
    + int ret;
    +
    + if (!handle) {
    + errno = EINVAL;
    + return -1;
    + }
    +
    + /* First we check if current device is a PPS valid PPS one...
    + */
    + ret = ioctl(source, PPS_CHECK);
    + if (ret) {
    + errno = EOPNOTSUPP;
    + return -1;
    + }
    +
    + /* ... then since in LinuxPPS there are no differences between a
    + * "PPS source" and a "PPS handle", we simply return the same value.
    + */
    + *handle = source;
    +
    + return 0;
    +}
    +
    +static __inline int time_pps_destroy(pps_handle_t handle)
    +{
    + return close(handle);
    +}
    +
    +static __inline int time_pps_getparams(pps_handle_t handle,
    + pps_params_t *ppsparams)
    +{
    + int ret;
    + struct pps_kparams __ppsparams;
    +
    + ret = ioctl(handle, PPS_GETPARAMS, &__ppsparams);
    +
    + ppsparams->api_version = __ppsparams.api_version;
    + ppsparams->mode = __ppsparams.mode;
    + ppsparams->assert_off_tu.tspec.tv_sec = __ppsparams.assert_off_tu.sec;
    + ppsparams->assert_off_tu.tspec.tv_nsec = __ppsparams.assert_off_tu.nsec;
    + ppsparams->clear_off_tu.tspec.tv_sec = __ppsparams.clear_off_tu.sec;
    + ppsparams->clear_off_tu.tspec.tv_nsec = __ppsparams.clear_off_tu.nsec;
    +
    + return ret;
    +}
    +
    +static __inline int time_pps_setparams(pps_handle_t handle,
    + const pps_params_t *ppsparams)
    +{
    + struct pps_kparams __ppsparams;
    +
    + __ppsparams.api_version = ppsparams->api_version;
    + __ppsparams.mode = ppsparams->mode;
    + __ppsparams.assert_off_tu.sec = ppsparams->assert_off_tu.tspec.tv_sec;
    + __ppsparams.assert_off_tu.nsec = ppsparams->assert_off_tu.tspec.tv_nsec;
    + __ppsparams.clear_off_tu.sec = ppsparams->clear_off_tu.tspec.tv_sec;
    + __ppsparams.clear_off_tu.nsec = ppsparams->clear_off_tu.tspec.tv_nsec;
    +
    + return ioctl(handle, PPS_SETPARAMS, &__ppsparams);
    +}
    +
    +/* Get capabilities for handle */
    +static __inline int time_pps_getcap(pps_handle_t handle, int *mode)
    +{
    + return ioctl(handle, PPS_GETCAP, mode);
    +}
    +
    +static __inline int time_pps_fetch(pps_handle_t handle, const int tsformat,
    + pps_info_t *ppsinfobuf,
    + const struct timespec *timeout)
    +{
    + struct pps_fdata __fdata;
    + int ret;
    +
    + /* Sanity checks */
    + if (tsformat != PPS_TSFMT_TSPEC) {
    + errno = EINVAL;
    + return -1;
    + }
    +
    + if (timeout) {
    + __fdata.timeout.sec = timeout->tv_sec;
    + __fdata.timeout.nsec = timeout->tv_nsec;
    + __fdata.timeout.flags = ~PPS_TIME_INVALID;
    + } else
    + __fdata.timeout.flags = PPS_TIME_INVALID;
    +
    + ret = ioctl(handle, PPS_FETCH, &__fdata);
    +
    + ppsinfobuf->assert_sequence = __fdata.info.assert_sequence;
    + ppsinfobuf->clear_sequence = __fdata.info.clear_sequence;
    + ppsinfobuf->assert_tu.tspec.tv_sec = __fdata.info.assert_tu.sec;
    + ppsinfobuf->assert_tu.tspec.tv_nsec = __fdata.info.assert_tu.nsec;
    + ppsinfobuf->clear_tu.tspec.tv_sec = __fdata.info.clear_tu.sec;
    + ppsinfobuf->clear_tu.tspec.tv_nsec = __fdata.info.clear_tu.nsec;
    + ppsinfobuf->current_mode = __fdata.info.current_mode;
    +
    + return ret;
    +}
    +
    +static __inline int time_pps_kcbind(pps_handle_t handle,
    + const int kernel_consumer,
    + const int edge, const int tsformat)
    +{
    + /* LinuxPPS doesn't implement kernel consumer feature */
    + errno = EOPNOTSUPP;
    + return -1;
    +}
    +
    +#endif /* _SYS_TIMEPPS_H_ */
    --
    1.5.2.5


    \
     
     \ /
      Last update: 2008-02-19 00:31    [W:0.047 / U:62.180 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site