diff --git a/userspace/tools/Makefile b/userspace/tools/Makefile index 345e2f8c377247395a72be4692261f21817671bd..acb65105fe7ec5faec55c252fea10125fb5f96c6 100644 --- a/userspace/tools/Makefile +++ b/userspace/tools/Makefile @@ -46,6 +46,7 @@ CFLAGS += -Wall \ -I$(LINUX)/arch/arm/mach-at91/include \ -I../wrsw_rtud \ -I../wrsw_hal \ + -I../wrsw_hal/nmea \ -I../mini-rpc \ -I../libsdb \ -I../include \ @@ -89,6 +90,7 @@ wrs_dump_shmem: wrs_dump_shmem.o wrs_dump_shmem_ppsi.o time_lib.o wr_mon: wr_mon.o term.o time_lib.o ${CC} -o $@ $^ $(LDFLAGS) +wr_date: nmea/wr_nmea.o nmea/nmea.o nmea/serial_linux.o wr_date: wr_date.o time_lib.o ${CC} -o $@ $^ $(LDFLAGS) @@ -103,7 +105,7 @@ wr_management: wr_management.o term.o ${CC} -o $@ $^ $(LDFLAGS) clean: - rm -f $(TOOLS) *.o *~ + rm -f $(TOOLS) *.o nmea/*.o *~ install: all install -d $(WR_INSTALL_ROOT)/bin diff --git a/userspace/tools/wr_date.c b/userspace/tools/wr_date.c index 538b740c50f795ecfb2f99bdcb9f51796f5b88b6..1876e927e393c4c7a6a2e6e250c2f0c8ed8a119f 100644 --- a/userspace/tools/wr_date.c +++ b/userspace/tools/wr_date.c @@ -22,11 +22,14 @@ #include <libwr/util.h> #include <time_lib.h> #include <rt_ipc.h> +#include "nmea/serial.h" +#include "nmea/wr_nmea.h" #ifndef MOD_TAI #define MOD_TAI 0x80 #endif #define WRDATE_CFG_FILE "/etc/wr_date.conf" +#define NMEA_SERIAL_PORT "/dev/ttyS2" /* Address for hardware, from nic-hardware.h */ #define FPGA_BASE_PPSG 0x10010500 @@ -36,6 +39,10 @@ extern int init_module(void *module, unsigned long len, const char *options); extern int delete_module(const char *module, unsigned int flags); static int opt_verbose, opt_force, opt_not; +static int opt_nmea_en = 0; +static int opt_nmea_baud = 9600; +static char *opt_nmea_fmt = "GPZDA"; +static struct wr_nmea nmea; static char *opt_cfgfile = WRDATE_CFG_FILE; static char *prgname; @@ -49,6 +56,8 @@ void help(void) " -c <cfg> configfile to use in place of the default\n" " -v verbose: report what the program does\n" " -n do not act in practice - dry run\n" + " -g <baud> <format> use nmea/gps input with a given baudrate and format (GPZDA|GPRMC)\n" + " default: %s, %d\n" " get print WR time to stdout\n" " get tohost print WR time and set system time\n" " set <value> set WR time to scalar seconds\n" @@ -58,7 +67,7 @@ void help(void) " diff show the difference between WR FPGA time (HW) and linux time (SW)\n" /* " set ntp set TAI from ntp and leap seconds" */ /* " set ntp:<ip> set from specified ntp server\n" */ - , WRDATE_CFG_FILE); + , WRDATE_CFG_FILE, opt_nmea_fmt, opt_nmea_baud); exit(1); } @@ -127,6 +136,23 @@ int get_kern_leaps(void) //return t.tai; } +static int wrdate_get_nmea(int64_t *t_out) +{ + if (nmea_read_tai(&nmea, t_out) < 0) { + fprintf(stderr, "wr_date: %s: error reading nmea\n", __func__); + return -1; + } + return 0; +} + +static void wrdate_gettimeofday(struct timeval *tv) +{ + if (opt_nmea_en) { + wrdate_get_nmea((int64_t *)&tv->tv_sec); + } else { + gettimeofday(tv, NULL); + } +} int wrdate_get(volatile struct PPSG_WB *pps, int tohost) { @@ -139,9 +165,8 @@ int wrdate_get(volatile struct PPSG_WB *pps, int tohost) int tai_offset; tai_offset = get_kern_leaps(); - if (opt_not) { - gettimeofday(&sw, NULL); + wrdate_gettimeofday(&sw); taih = 0; tail = sw.tv_sec + tai_offset; nsec = sw.tv_usec * 1000; @@ -155,14 +180,16 @@ int wrdate_get(volatile struct PPSG_WB *pps, int tohost) tmp2 = pps->CNTR_UTCLO; } while((tmp1 != taih) || (tmp2 != tail)); } - gettimeofday(&sw, NULL); - tai = (uint64_t)(taih) << 32 | tail; + wrdate_gettimeofday(&sw); + tai = opt_nmea_en ? (sw.tv_sec) : (uint64_t)(taih) << 32 | tail; /* Before printing (which takes time), set host time if so asked to */ if (tohost) { - hw.tv_sec = tai - tai_offset; - hw.tv_usec = nsec / 1000; + + hw.tv_sec = opt_nmea_en ? sw.tv_sec : tai - tai_offset; + hw.tv_usec = opt_nmea_en ? sw.tv_usec : nsec/1000; + if (settimeofday(&hw, NULL)) fprintf(stderr, "wr_date: settimeofday(): %s\n", strerror(errno)); @@ -210,8 +237,7 @@ int wrdate_diff(volatile struct PPSG_WB *pps) struct timeval ht, wt; gettimeof_wr(&wt, pps); - gettimeofday(&ht, NULL); - + wrdate_gettimeofday(&ht); return __wrdate_diff(pps,&ht, &wt); } @@ -321,7 +347,7 @@ int __wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly, int tai_ } usleep(100); - gettimeofday(&tvh, NULL); + wrdate_gettimeofday(&tvh); gettimeof_wr(&tvr, pps); /* diff is the expected step to be added, so host - WR */ @@ -389,7 +415,7 @@ int __wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly, int tai_ } if (opt_verbose && deep==0) { usleep(100); - gettimeofday(&tvh, NULL); + wrdate_gettimeofday(&tvh); gettimeof_wr(&tvr, pps); printf("Host time: %9li.%06li\n", (long)(tvh.tv_sec), @@ -555,7 +581,7 @@ int wrdate_stat(volatile struct PPSG_WB *pps) // Get time usleep(100); // Increase stability of measures : less preempted during time measures gettimeof_wr(&tv_tai,pps); - gettimeofday(&tv_host, NULL); + wrdate_gettimeofday(&tv_host); // Calculate difference *udiff_tmp=(tv_host.tv_sec-tv_tai.tv_sec)*1000000; @@ -594,7 +620,7 @@ int main(int argc, char **argv) prgname = argv[0]; - while ( (c = getopt(argc, argv, "fc:vn")) != -1) { + while ( (c = getopt(argc, argv, "fcg:vn")) != -1) { switch(c) { case 'f': opt_force = 1; @@ -602,6 +628,11 @@ int main(int argc, char **argv) case 'c': opt_cfgfile = optarg; break; + case 'g': + opt_nmea_en = 1; + opt_nmea_baud = atoi(optarg); + opt_nmea_fmt = argv[optind++]; + break; case 'v': opt_verbose = 1; break; @@ -613,6 +644,7 @@ int main(int argc, char **argv) help(); } } + if (optind > argc - 1) help(); @@ -627,6 +659,14 @@ int main(int argc, char **argv) wrdate_cfgfile(opt_cfgfile); + if (opt_nmea_en) { + nmea_init(&nmea, NMEA_SERIAL_PORT, opt_nmea_baud, opt_nmea_fmt); + } + + if (cmd == NULL) { + return -1; + } + if (!strcmp(cmd, "get")) { /* parse the optional "tohost" argument */ if (optind == argc - 1 && !strcmp(argv[optind], "tohost"))