diff --git a/userspace/tools/nmea/wr_nmea.c b/userspace/tools/nmea/wr_nmea.c index b6f92662b405439b4acd59d5c8ec0b578a79355f..8ef3ec435aa4c451ed63cd9b2ea307903be79af9 100644 --- a/userspace/tools/nmea/wr_nmea.c +++ b/userspace/tools/nmea/wr_nmea.c @@ -32,10 +32,13 @@ int nmea_init(struct wr_nmea *nmea, char *dev, int baud, char *fmt) static int read_nmea_msg(char *msgbuf, int len) { - int i = 0; char c; unsigned int nmea_timeout_max = 10; unsigned int nmea_timeout; + char *msgbuf_start = msgbuf; + + /* Make sure there is enought room for \r, \n \0 at the end */ + len -= 3; while (1) { if (nmea_timeout_max <= 0) { @@ -43,7 +46,7 @@ static int read_nmea_msg(char *msgbuf, int len) return -1; } - nmea_timeout = 1; + nmea_timeout = 2; c = serial_read_byte_w_timeout(&nmea_timeout); if (nmea_timeout == 0) { nmea_timeout_max--; @@ -65,7 +68,7 @@ static int read_nmea_msg(char *msgbuf, int len) return -1; } - nmea_timeout = 1; + nmea_timeout = 2; c = serial_read_byte_w_timeout(&nmea_timeout); if (nmea_timeout == 0) { nmea_timeout_max--; @@ -75,9 +78,10 @@ static int read_nmea_msg(char *msgbuf, int len) if (c == '\r') break; - i++; - if (i >= len) + + if (msgbuf - msgbuf_start >= len) break; + *msgbuf++ = c; } @@ -86,25 +90,33 @@ static int read_nmea_msg(char *msgbuf, int len) *msgbuf++ = 0; - return 0; + /* Return message length, don't count null char at the end */ + return msgbuf - msgbuf_start - 1; } int read_nmea_msg_type(char *msgbuf, int len, const char *msg_type) { + int ret; do { - if (read_nmea_msg(msgbuf, len) < 0) + ret = read_nmea_msg(msgbuf, len); + if (ret < 0) return -1; - } while (strncmp(&msgbuf[1], msg_type, 5) != 0); //ignore starting "$" - return 0; + /* ignore starting "$" */ + } while (strncmp(&msgbuf[1], msg_type, strlen(msg_type)) != 0); + + /* Return message length */ + return ret; } int nmea_read_utc(struct wr_nmea *nmea, int64_t *t_out) { + int ret; char buf[1024]; serial_open(nmea->dev, nmea->baud); - if (read_nmea_msg_type(buf, 1024, nmea->fmt) < 0) + ret = read_nmea_msg_type(buf, 1024, nmea->fmt); + if (ret < 0) return -1; serial_close(); @@ -125,5 +137,6 @@ int nmea_read_utc(struct wr_nmea *nmea, int64_t *t_out) *t_out = utc_time_to_utc_seconds(*(nmea->utc)); - return 0; + /* Return message length */ + return ret; } diff --git a/userspace/tools/wr_date.c b/userspace/tools/wr_date.c index 9a53bf722ad22b9fecbb4fdf1d896c2761f24208..553e1b80f62ad8791c9174e6dda157203fc42f48 100644 --- a/userspace/tools/wr_date.c +++ b/userspace/tools/wr_date.c @@ -167,7 +167,7 @@ static int wrdate_get_nmea_utc(int64_t *t_out) return -1; } - return 0; + return ret; } static int wrdate_get_irig_utc(int64_t *t_out) @@ -188,8 +188,16 @@ static int wrdate_get_irig_utc(int64_t *t_out) static int wrdate_gettimeofday(struct timeval *tv) { + int ret; if (opt_nmea_en) { - return wrdate_get_nmea_utc((int64_t *)&tv->tv_sec); + /* Is blocking! */ + ret = wrdate_get_nmea_utc((int64_t *)&tv->tv_sec); + if (ret < 0) + return ret; + tv->tv_sec--; + /* Subtract message length */ + tv->tv_usec = 1000000 - (ret - 1)*1000000/opt_nmea_baud; + return ret; }else if(opt_irig_en){ return wrdate_get_irig_utc((int64_t *)&tv->tv_sec); } else { @@ -221,14 +229,9 @@ int wrdate_get(volatile struct PPSG_WB *pps, int tohost) tmp2 = pps->CNTR_UTCLO; } while((tmp1 != taih) || (tmp2 != tail)); - if (opt_nmea_en) { - /* Is blocking! */ - if (wrdate_get_nmea_utc((int64_t *)&tv.tv_sec) < 0) - return 1; - } else if(opt_irig_en) { - if (wrdate_get_irig_utc((int64_t *)&tv.tv_sec) < 0) - return 1; - } + /* Note for NMEA this function is blocking! */ + if (wrdate_gettimeofday(&tv) < 0) + return 1; if (gettimeofday(&sw, NULL) < 0) return 1; @@ -237,7 +240,9 @@ int wrdate_get(volatile struct PPSG_WB *pps, int tohost) /* Before printing (which takes time), set host time if so asked to */ if (tohost) { - if (opt_nmea_en || opt_irig_en) { + if (opt_nmea_en) { + hw = tv; + } else if (opt_irig_en) { hw.tv_sec = tv.tv_sec; hw.tv_usec = 0; } else { @@ -680,7 +685,10 @@ int wrdate_stat(volatile struct PPSG_WB *pps) ); udiff_last=udiff; - sleep(1); + /* Readout for NMEA will wait till the boundary of a second anyway */ + if (!opt_nmea_en) { + sleep(1); + } } return 0;