From: Fernando Hauscarriaga Date: Mon, 22 Jan 2007 06:28:51 +0000 (-0500) Subject: refclock_palisade.c, driver29.html, refclock_palisade.h: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=baca794ae0dd0b132e991de89ce7a142dd684675;p=thirdparty%2Fntp.git refclock_palisade.c, driver29.html, refclock_palisade.h: [BUG 592] Added support for Thunderbolt Receiver (mode 2). bk: 45b459a34Np4SzYoxI6I0FBz1NsUuQ --- diff --git a/html/drivers/driver29.html b/html/drivers/driver29.html index 479978f8f4..dde58ff684 100644 --- a/html/drivers/driver29.html +++ b/html/drivers/driver29.html @@ -4,15 +4,24 @@ - Trimble Palisade Receiver + Trimble Palisade and Thunderbolt Receivers -

Trimble Palisade Receiver +

Trimble Palisade and Thunderbolt Receivers

+ + + + + +

gif

+
+

jpg

+

Synopsis

@@ -50,12 +59,20 @@ + + + +
9600 baud, 8-bits, 1-stop, odd parity
+
+ Serial I/O (Thunderbolt):
+
9600 baud, 8-bits, 1-stop, no parity

Description

The refclock_palisade driver supports Trimble Navigation's Palisade Smart Antenna GPS receiver.
Additional software and information about the Palisade GPS is available from: http://www.trimble.com/oem/ntp.
Latest NTP driver source, executables and documentation is maintained at: ftp://ftp.trimble.com/pub/ntp

This documentation describes version 7.12 of the GPS Firmware and version 2.46 (July 15, 1999) and later, of the driver source.
 

+

This documentation describes version 1 of the Thunderbolt Receiver Firmware, no tests have been made on further firmwares, please read "Notes on the Thunderbolt Receiver's Firmware" at the end of this documentation for more information.

Operating System Compatibility

The Palisade driver has been tested on the following software and hardware platforms:
 
@@ -97,7 +114,8 @@ 20 us -
+

+ Attention: Thunderbolt Receiver has not being tested on the previous software and hardware plataforms.

GPS Receiver

The Palisade GPS receiver is an 8-channel smart antenna, housing the GPS receiver, antenna and interface in a single unit, and is designed for rooftop deployment in static timing applications.

Palisade generates a PPS synchronized to UTC within +/- 100 ns.  The Palisade's external event input with 40 nanosecond resolution is utilized by the Palisade NTP driver for asynchronous precision time transfer.

@@ -199,6 +217,19 @@ # and set flag2 to turn off event polling.
fudge 127.127.29.0 flag2 1
#------------------------------------------------------------------------------
 

+ +

Thunderbolt NTP Configuration file

+ #------------------------------------------------------------------------------ +

Configuration without event polling:
+ #------------------------------------------------------------------------------
+ # The Primary reference
+ server 127.127.29.0 mode 2 # Trimble Thunderbolt GPS (Stratum 1).
+ # Set packet delay
+ fudge 127.127.29.0 time1 0.020
+ # and set flag2 to turn off event polling.
+ fudge 127.127.29.0 flag2 1
+ #------------------------------------------------------------------------------
 

+ Currently the Thunderbolt mode doesn't support event polling, the reasons are explained on the "Notes on the Thunderbolt Receiver's Firmware" section at the end of this documentation.

Time Transfer and Polling

Time transfer to the NTP host is performed via the Palisade's comprehensive time packet output. The time packets are output once per second, and whenever an event timestamp is requested.

The driver requests an event time stamp at the end of each polling interval, by pulsing the RTS (request to send) line on the serial port. The Palisade GPS responds with a time stamped event packet.

@@ -235,7 +266,7 @@

Mode Parameter

mode number -
The mode parameter to the server command specifies the specific hardware this driver is for. The default is 0 for a normal Trimble Palisade. The only other option at this time is 1 for a Endrun Praecis in Trimble emulation mode. +
The mode parameter to the server command specifies the specific hardware this driver is for. The default is 0 for a normal Trimble Palisade. The other options are 1 for an Endrun Praecis in Trimble emulation mode, and 2 for the Trimble Thunderbolt GPS Disciplined Clock Receiver.

DEFINEs

The following constants are defined in the driver source code. These defines may be modified to improve performance or adapt to new operating systems.
  @@ -369,6 +400,7 @@ +

Leap Second Flag Definition:

Bit 0:  (1) UTC Time is available
Bits 1 - 3: Undefined
Bit 4:  (1) Leap Scheduled: Leap second pending asserted by GPS control segment.
Bit 5:  (1) Leap Pending: set 24 hours before, until beginning of leap second.
Bit 6:  (1) GPS Leap Warning: 6 hours before until 6 hours after leap event
Bit 7:  (1) Leap In Progress. Only set during the leap second. @@ -576,6 +608,281 @@ +

Thunderbolt Timing packets Data Format

+ Thunderbolt can output 2 synchronous packets. +

Primary Timing Packet - 0x8FAB

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ByteBitItemTypeValueDescription
0SubcodeUINT80xAB
1-4Time of WeekUINT32GPS seconds of week
5-6Week NumberUINT16GPS Week Number
7-8UTC OffsetSINT16UTC Offset (seconds)
9
0
1
2
3
4
Timing FlagBit field
0 or 1
0 or 1
0 or 1
0 or 1
0 or 1
GPS Time or UTC Time
GPS PPS or UTC PPS
time is set or time is not set
have UTC info or no UTC info
Time from GPS or time from user
10SecondsUINT80-59(60 for UTC leap second event)
11MinutesUINT80-59Minutes of Hour
12HoursUINT80-23Hour of Day
13Day of MonthUINT81-31Day of Month
14MonthUINT81-12Month of Year
15-16YearUINT16Four digits of Year (e.g. 1998)
+
+

Supplemental Timing Packet - 0x8FAC

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ByteBitItemTypeValueDescription
0SubcodeUINT80xAC
1Receiver ModeUINT8
0
1
2
3
4
5
6
Automatic (2D/3D)
Single Satellite (Time)
Horizontal (2D)
Full Position (3D)
DGPS Reference
Clock Hold (2D)
Overdetermined Clock
2Disciplining ModeUINT8
0
1
2
3
4
5
6
Normal
Power-Up
Auto Holdover
Manual Holdover
Recovery
Not Used
Disciplining disabled
3Self-Survey ProgressUINT 80-100%
4-7Holdover DurationUINT 32seconds
8-9
0
1
2
3
4
Critical AlarmsUINT16Bit field
ROM checksum error
RAM check has failed
Power supply failure
FPGA check has failed
Oscillator control voltage at rail
10-11
0
1
2
3
4
5
6
Minor AlarmsUINT16Bit field
Normal
Power-Up
Auto Holdover
Manual Holdover
Recovery
Not Used
Disciplining disabled
12GPS Decoding StatusUINT8
0
1
3
8
9
0x0A
0x0B
0x0C
0x10
Doing fixes
Don t have GPS time
PDOP is too high
No usable sats
Only 1 usable sat
Only 2 usable sats
Only 3 usable sats
The chosen sat is unusable
TRAIM rejected the fix
13Disciplining ActivityUINT8
0
1
2
3
4
5
6
7
8
Phase locking
Oscillator warming up
Frequency locking
Placing PPS
Initializing loop filter
Compensating OCXO
Inactive
Not used
Recovery mode
14Spare Status 1UINT80
15Spare Status 2UINT80
16-19PPS OffsetSingleEstimate of UTC/GPS offset (ns)
20-2310 MHz OffsetSingleEstimate of UTC/GPS offset (ns)
24-27DAC ValueUINT32Offset binary (0x00 - 0xFFFFF)
28-31DAC VoltageSingleVolts
32-35TemperatureSingledegrees C
36-43LatitudeDoubleradians
44-51LongitudeDoubleradians
52-59AltitudeDoubleMeters
60-67SpareFor Future Expantion
+

Pinouts

The following connections are required when connecting Palisade with a host:
 
 
@@ -762,12 +1069,19 @@
+ +

Notes on the Thunderbolt Receiver's Firmware

+ + The support for Thunderbolt Receiver in the palisade driver doesn't support (for now) event-polling, the reason is that the Thunderbolt receiver the patch is written for doesn't support time-on-request, so you just have to sit there and wait for the time to arrive with the PPS. We tried to contact Trimble because there's presumably a firmware update that support it, but we didn't have much luck. +Here is a link explaining the situation:

+https://lists.ntp.isc.org/pipermail/hackers/2006-April/002216.html


Questions or Comments:
Sven Dietrich
Trimble Navigation Ltd.

-

(last updated July 29, 1999)

+ Fernando P. Hauscarriaga
+

(last updated January 15, 2007)


; diff --git a/ntpd/refclock_palisade.c b/ntpd/refclock_palisade.c index 0b114f0118..31ed89efc5 100644 --- a/ntpd/refclock_palisade.c +++ b/ntpd/refclock_palisade.c @@ -50,6 +50,18 @@ * * Version 2.45; July 14, 1999 * + * + * + * 31/03/06: Added support for Thunderbolt GPS Disciplined Clock. + * Contact: Fernando Pablo Hauscarriaga + * E-mail: fernandoph@iar.unlp.edu.ar + * Home page: www.iar.unlp.edu.ar/~fernandoph + * Instituto Argentino de Radioastronomia + * www.iar.unlp.edu.ar + * + * 14/01/07: Conditinal compilation for Thunderbolt support no longer needed + * now we use mode 2 for decode thunderbolt packets. + * Fernando P. Hauscarriaga */ #ifdef HAVE_CONFIG_H @@ -99,10 +111,112 @@ int day_of_year (char *dt); /* Supported clock types */ #define CLK_TRIMBLE 0 /* Trimble Palisade */ #define CLK_PRAECIS 1 /* Endrun Technologies Praecis */ +#define CLK_THUNDERBOLT 2 /* Trimble Thunderbolt GPS Receiver */ int praecis_msg; static void praecis_parse(struct recvbuf *rbufp, struct peer *peer); +/* These routines are for sending packets to the Thunderbolt receiver + * They are taken from Markus Prosch + */ + +/* + * sendcmd - Build data packet for sending + */ +static void +sendcmd ( + struct packettx *buffer, int c + ) +{ + buffer->data[0] = DLE; + buffer->data[1] = (unsigned char)c; + buffer->size = 2; +} + +/* + * sendsupercmd - Build super data packet for sending + */ +static void +sendsupercmd ( + struct packettx *buffer, int c1, int c2 + ) +{ + buffer->data[0] = DLE; + buffer->data[1] = (unsigned char)c1; + buffer->data[2] = (unsigned char)c2; + buffer->size = 3; +} + +/* + * sendbyte - + */ +static void +sendbyte ( + struct packettx *buffer, int b + ) +{ + if (b == DLE) + buffer->data[buffer->size++] = DLE; + buffer->data[buffer->size++] = (unsigned char)b; +} + +/* + * sendint - + */ +static void +sendint ( + struct packettx *buffer, int a + ) +{ + sendbyte(buffer, (unsigned char)((a>>8) & 0xff)); + sendbyte(buffer, (unsigned char)(a & 0xff)); +} + +/* + * sendetx - Send packet or super packet to the device + */ +static int +sendetx ( + struct packettx *buffer, int fd + ) +{ + int result; + + buffer->data[buffer->size++] = DLE; + buffer->data[buffer->size++] = ETX; + result = write(fd, buffer->data, (unsigned long)buffer->size); + + if (result != -1) + return(result); + else + return (-1); +} + +/* + * init_thunderbolt - Prepares Thunderbolt receiver to be used with + * NTP (also taken from Markus Prosch). + */ +static void +init_thunderbolt ( + int fd + ) +{ + u_char buffer[256]; + struct packettx buf; + + buf.data = buffer; + + /* set UTC time */ + sendsupercmd (&buf, 0x8E, 0xA2); + sendbyte (&buf, 0x3); + sendetx (&buf, fd); + + /* activate packets 0x8F-AB and 0x8F-AC */ + sendsupercmd (&buf, 0x8F, 0xA5); + sendint (&buf, 0x5); + sendetx (&buf, fd); +} + /* * palisade_start - open the devices and initialize data for processing */ @@ -186,14 +300,6 @@ palisade_start ( tio.c_iflag &= ~ICRNL; #endif /* NTP 4.x */ - if (tcsetattr(fd, TCSANOW, &tio) == -1) { - msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit); -#ifdef DEBUG - printf("Palisade(%d) tcsetattr(fd, &tio)\n",unit); -#endif - return 0; - } - /* * Allocate and initialize unit structure */ @@ -218,10 +324,21 @@ palisade_start ( case CLK_PRAECIS: msyslog(LOG_NOTICE, "Palisade(%d) Praecis mode enabled\n",unit); break; + case CLK_THUNDERBOLT: + msyslog(LOG_NOTICE, "Palisade(%d) Thunderbolt mode enabled\n",unit); + tio.c_cflag = (CS8|CLOCAL|CREAD); + break; default: msyslog(LOG_NOTICE, "Palisade(%d) mode unknown\n",unit); break; } + if (tcsetattr(fd, TCSANOW, &tio) == -1) { + msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit); +#ifdef DEBUG + printf("Palisade(%d) tcsetattr(fd, &tio)\n",unit); +#endif + return 0; + } pp = peer->procptr; pp->io.clock_recv = palisade_io; @@ -254,6 +371,9 @@ palisade_start ( up->rpt_status = TSIP_PARSED_EMPTY; up->rpt_cnt = 0; + if (up->type == CLK_THUNDERBOLT) + init_thunderbolt(fd); + return 1; } @@ -349,6 +469,7 @@ TSIP_decode ( * proper format, declare bad format and exit. */ + if (up->type != CLK_THUNDERBOLT){ if ((up->rpt_buf[0] == (char) 0x41) || (up->rpt_buf[0] == (char) 0x46) || (up->rpt_buf[0] == (char) 0x54) || @@ -358,10 +479,11 @@ TSIP_decode ( /* standard time packet - GPS time and GPS week number */ #ifdef DEBUG printf("Palisade Port B packets detected. Connect to Port A\n"); -#endif return 0; } + } +#endif /* * We cast both to u_char to as 0x8f uses the sign bit on a char @@ -377,6 +499,8 @@ TSIP_decode ( switch (mb(0) & 0xff) { int GPS_UTC_Offset; + long tow; + case PACKET_8F0B: if (up->polled <= 0) @@ -513,12 +637,185 @@ printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d UTC % return 1; break; + case PACKET_8FAC: + if (up->polled <= 0) + return 0; + + if (up->rpt_cnt != LENCODE_8FAC)/* check length */ + break; + +#ifdef DEBUG +if (debug > 1) { + double lat, lon, alt; + lat = getdbl((u_char *) &mb(36)) * R2D; + lon = getdbl((u_char *) &mb(44)) * R2D; + alt = getdbl((u_char *) &mb(52)); + + printf("TSIP_decode: unit %d: Latitude: %03.4f Longitude: %03.4f Alt: %05.2f m\n", + up->unit, lat,lon,alt); + printf("TSIP_decode: unit %d\n", up->unit); + } +#endif + if (getint((u_char *) &mb(10)) & 0x80) + pp->leap = LEAP_ADDSECOND; /* we ASSUME addsecond */ + else + pp->leap = LEAP_NOWARNING; + +#ifdef DEBUG + if (debug > 1) + printf("TSIP_decode: unit %d: 0x%02x leap %d\n", + up->unit, mb(0) & 0xff, pp->leap); + if (debug > 1) { + printf("Receiver MODE: 0x%02X\n", (u_char)mb(1)); + if (mb(1) == 0x00) + printf(" AUTOMATIC\n"); + if (mb(1) == 0x01) + printf(" SINGLE SATELLITE\n"); + if (mb(1) == 0x03) + printf(" HORIZONTAL(2D)\n"); + if (mb(1) == 0x04) + printf(" FULL POSITION(3D)\n"); + if (mb(1) == 0x05) + printf(" DGPR REFERENCE\n"); + if (mb(1) == 0x06) + printf(" CLOCK HOLD(2D)\n"); + if (mb(1) == 0x07) + printf(" OVERDETERMINED CLOCK\n"); + + printf("\n** Disciplining MODE 0x%02X:\n", (u_char)mb(2)); + if (mb(2) == 0x00) + printf(" NORMAL\n"); + if (mb(2) == 0x01) + printf(" POWER-UP\n"); + if (mb(2) == 0x02) + printf(" AUTO HOLDOVER\n"); + if (mb(2) == 0x03) + printf(" MANUAL HOLDOVER\n"); + if (mb(2) == 0x04) + printf(" RECOVERY\n"); + if (mb(2) == 0x06) + printf(" DISCIPLINING DISABLED\n"); + } +#endif + return 0; + break; + + case PACKET_8FAB: + /* Thunderbolt Primary Timing Packet */ + + if (up->rpt_cnt != LENCODE_8FAB) /* check length */ + break; + + if (up->polled <= 0) + return 0; + + GPS_UTC_Offset = getint((u_char *) &mb(7)); + + if (GPS_UTC_Offset == 0){ /* Check UTC Offset */ +#ifdef DEBUG + printf("TSIP_decode: UTC Offset Unknown\n"); +#endif + break; + } + + + if ((mb(9) & 0x1d) == 0x0) { + /* if we know the GPS time and the UTC offset, + we expect UTC timing information !!! */ + + pp->leap = LEAP_NOTINSYNC; + refclock_report(peer, CEVNT_BADTIME); + up->polled = -1; + return 0; + } + + pp->nsec = 0; +#ifdef DEBUG + printf("\nTiming Flags are:\n"); + printf("Timing flag value is: 0x%X\n", mb(9)); + if ((mb(9) & 0x01) != 0) + printf (" Getting UTC time\n"); + else + printf (" Getting GPS time\n"); + if ((mb(9) & 0x02) != 0) + printf (" PPS is from UTC\n"); + else + printf (" PPS is from GPS\n"); + if ((mb(9) & 0x04) != 0) + printf (" Time is not Set\n"); + else + printf (" Time is Set\n"); + if ((mb(9) & 0x08) != 0) + printf(" I dont have UTC info\n"); + else + printf (" I have UTC info\n"); + if ((mb(9) & 0x10) != 0) + printf (" Time is from USER\n\n"); + else + printf (" Time is from GPS\n\n"); +#endif + + if ((pp->day = day_of_year(&mb(13))) < 0) + break; + tow = getlong((u_char *) &mb(1)); +#ifdef DEBUG + if (debug > 1) { + printf("pp->day: %d\n", pp->day); + printf("TOW: %ld\n", tow); + printf("DAY: %d\n", mb(13)); + } +#endif + pp->year = getint((u_char *) &mb(15)); + pp->hour = mb(12); + pp->minute = mb(11); + pp->second = mb(10); + + +#ifdef DEBUG + if (debug > 1) +printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%06ld %02d/%02d/%04d ",up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, pp->second, pp->nsec, mb(14), mb(13), pp->year); +#endif + return 1; + break; + default: /* Ignore Packet */ return 0; } /* switch */ }/* if 8F packets */ + else if (up->rpt_buf[0] == (u_char)0x42) { + printf("0x42\n"); + return 0; + } + else if (up->rpt_buf[0] == (u_char)0x43) { + printf("0x43\n"); + return 0; + } + else if (up->rpt_buf[0] == PACKET_41) { + printf("0x41\n"); + return 0; + } + else if (up->rpt_buf[0] == PACKET_6D) { +#ifdef DEBUG + int sats; + + if ((mb(0) & 0x01) && (mb(0) & 0x02)) + printf("2d Fix Dimension\n"); + if (mb(0) & 0x04) + printf("3d Fix Dimension\n"); + + if (mb(0) & 0x08) + printf("Fix Mode is MANUAL\n"); + else + printf("Fix Mode is AUTO\n"); + + sats = mb(0) & 0xF0; + sats = sats >> 4; + printf("Tracking %d Satellites\n", sats); +#endif + return 0; + } /* else if not super packet */ refclock_report(peer, CEVNT_BADREPLY); up->polled = -1; #ifdef DEBUG @@ -949,6 +1246,25 @@ getint ( return (short) (bp[1] + (bp[0] << 8)); } +/* + * cast a 32 bit character array into a long (32 bit) int + */ +long +getlong( +#ifdef PALISADE + bp + ) + u_char *bp; #else + u_char *bp + ) +#endif +{ +return (long) (bp[0] << 24) | + (bp[1] << 16) | + (bp[2] << 8) | + bp[3]; +} + int refclock_palisade_bs; #endif /* REFCLOCK */ diff --git a/ntpd/refclock_palisade.h b/ntpd/refclock_palisade.h index c3340f8f05..9c2ae9272e 100644 --- a/ntpd/refclock_palisade.h +++ b/ntpd/refclock_palisade.h @@ -71,6 +71,7 @@ # define _SVID3 # endif # include +# include # ifdef TERMIOS_NEEDS__SVID3 # undef _SVID3 # endif @@ -108,10 +109,19 @@ #define LENCODE_8F0B 74 /* Length of TSIP 8F-0B Packet & header */ #define LENCODE_NTP 22 /* Length of Palisade NTP Packet */ +#define LENCODE_8FAC 68 /* Length of Thunderbolt 8F-AC Position Packet*/ +#define LENCODE_8FAB 17 /* Length of Thunderbolt Primary Timing Packet*/ + /* Allowed Sub-Packet ID's */ #define PACKET_8F0B 0x0B #define PACKET_NTP 0xAD +/* Thunderbolt Packets */ +#define PACKET_8FAC 0xAC /* Supplementary Thunderbolt Time Packet */ +#define PACKET_8FAB 0xAB /* Primary Thunderbolt Time Packet */ +#define PACKET_6D 0x6D /* Supplementary Thunderbolt Tracking Stats */ +#define PACKET_41 0x41 /* Thunderbolt I dont know what this packet is, it's not documented on my manual*/ + #define DLE 0x10 #define ETX 0x03 @@ -138,6 +148,16 @@ #define GPS_PI (3.1415926535898) #define R2D (180.0/GPS_PI) +/* + * Structure for build data packets for send (thunderbolt uses it only) + * taken from Markus Prosch + */ +struct packettx +{ + short size; + u_char *data; +}; + /* * Palisade unit control structure. */ @@ -166,5 +186,14 @@ long HW_poll (struct refclockproc *); float getfloat (u_char *); double getdbl (u_char *); short getint (u_char *); +long getlong (u_char *); + +/* Thunderbolt specific function prototypes */ +static void sendcmd (struct packettx *buffer, int c); +static void sendsupercmd (struct packettx *buffer, int c1, int c2); +static void sendbyte (struct packettx *buffer, int b); +static void sendint (struct packettx *buffer, int a); +static int sendetx (struct packettx *buffer, int fd); +static void init_thunderbolt (int fd); #endif /* PALISADE_H */