Subject: Re: ntpd problems with GPS receiver under NetBSD-amd64
To: Alicia da Conceicao <alicia@engine.ca>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-net
Date: 02/05/2005 00:39:12
Alicia da Conceicao wrote:

> Greetings:
> 
> I have a GPS receiver with a TTL PPS feed, which I managed to successfully
> wire up to a RS232 (DB9) serial port.  When I connect it to a NetBSD-amd64
> version 2.0 computer running minicom at 4800 bps for tty02, I am able to
> read all of the GPS data (including time, position, etc.) in the
> raw NMEA-0183 strings.  So far so good right.
> 
> Note that the DB9 serial port was wired as follows (male view):
> 
>          ------------------------------------------
> 	\  [1-TTL] [2-TX] [3-RX] [4-???] [5-GND] /
>           \    [6-???] [7-???] [8-???] [9-???]   /
>            --------------------------------------
> 
> with the TTL on pin1, transmit on pin2, receive on pin3, and ground on
> pin5.

I think pin 1 is DCD.  If so that matches my setup here, on an alpha
with a 2.0BETA kernel.

> 	pidfile /var/run/ntpd.pid
> 	driftfile /var/db/ntp.drift
> 	logconfig -syncstatus
> 	peer 127.127.20.0 prefer
> 	fudge 127.127.20.0 stratum 0
> 	fudge 127.127.20.0 time1 -1.0
> 	peer 127.127.22.0
> 	fudge 127.127.22.0 stratum 0
> 	fudge 127.127.22.0 flag2 0
> 	fudge 127.127.22.0 flag3 1
> 
> and with symlinks:
> 
> 	/dev/gps0 => /dev/tty02
> 	/dev/pps0 => /dev/tty02

I don't use the PPS driver, just the NMEA driver (driver 20).  It
knows how to deal with PPS internally.  The relevant lines from my
/etc/ntp.conf are:

	server  127.127.20.0    mode 2          prefer
	fudge   127.127.20.0    time1 1.0       flag2 1 flag3 1

Mode 2 uses the GLL NMEA sentences - I honestly can't recall why I
needed to set this.  I also needed flag2 set because the PPS rising edge
was coming in at about 0.9 of second, and the falling edge is on the
second.

/dev/gps0 is a symlink to /dev/ttyC2.  /dev/tty02 on PC-type hardware
should be the equivalent.

I've included a little program I wrote below that makes sure that the
kernel can actually see the PPS pulses.  Output looks something like:

	carrier time 1107523541.999748 - since last: 1666562277.2000860 **
	carrier time 1107523542.999752 - since last: 1.000004
	carrier time 1107523543.999755 - since last: 1.000003
	carrier time 1107523544.999740 - since last: 0.999985
	carrier time 1107523545.999739 - since last: 0.999999
	carrier time 1107523546.999757 - since last: 1.000018

An entry with "**" indicates that it was more than 0.01 secs difference
from the previously detected PPS pulse.

Simon.
--
Simon Burge                            <simonb@wasabisystems.com>
NetBSD Support and Service:         http://www.wasabisystems.com/


#include <sys/ioctl.h>
#include <err.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
	struct termios t;
	struct timeval tv, otv, tdiff;
	int fd, i;

	fd = open("/dev/gps0", 0);
	if (fd < 0)
		err(1, "open /dev/gps0");
	tcgetattr(fd, &t);
	cfsetspeed(&t, B4800);
	tcsetattr(fd, TCSANOW, &t);

	for (i = 0; i < 100; i++) {
		ioctl(fd, TIOCDCDTIMESTAMP, &tv);
		if ((tv.tv_sec != otv.tv_sec) || (tv.tv_usec != otv.tv_usec)) {
			double d;

			timersub(&tv, &otv, &tdiff);
			d = tdiff.tv_sec + tdiff.tv_usec / 1000000.0;

			printf("carrier time %d.%06d", tv.tv_sec, tv.tv_usec);
			printf(" - since last: %d.%06d",
			    tdiff.tv_sec, tdiff.tv_usec);
			if (d < 0.99 || d > 1.01)
				printf(" **");
			printf("\n");
			otv = tv;
		}
		usleep(200 * 1000);
	}
	exit(0);
}