[BUG 592] Added support for Thunderbolt Receiver (mode 2).
bk: 45b459a34Np4SzYoxI6I0FBz1NsUuQ
<head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
- <title>Trimble Palisade Receiver</title>
+ <title>Trimble Palisade and Thunderbolt Receivers</title>
<link href="scripts/style.css" type="text/css" rel="stylesheet">
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
- <h1><font size="+2">Trimble Palisade Receiver</font>
+ <h1><font size="+2">Trimble Palisade and Thunderbolt Receivers</font>
<hr>
</h1>
+ <table>
+ <tr>
+ <td>
<h2><img src="../pic/driver29.gif" alt="gif" nosave height="100" width="420"></h2>
+ </td>
+ <td>
+ <h2><img src="../pic/thunderbolt.jpg" alt="jpg" nosave height="270" width="420"></h2>
+ </td>
+ </tr>
+ </table>
<h2><font size="+1">Synopsis</font></h2>
<table>
<tr>
</td>
<td><b>9600 baud, 8-bits, 1-stop, odd parity</b></td>
</tr>
+ <tr>
+ <td>
+ <div align="right">
+ <tt><font size="+1">Serial I/O (Thunderbolt):</font></tt></div>
+ </td>
+ <td><b>9600 baud, 8-bits, 1-stop, no parity</b></td>
+ </tr>
</table>
<h2><font size="+1">Description</font></h2>
The <b>refclock_palisade</b> driver supports <a href="http://www.trimble.com/products/ntp">Trimble Navigation's Palisade Smart Antenna GPS receiver</a>.<br>
Additional software and information about the Palisade GPS is available from: <a href="http://www.trimble.com/oem/ntp">http://www.trimble.com/oem/ntp</a>.<br>
Latest NTP driver source, executables and documentation is maintained at: <a href="ftp://ftp.trimble.com/pub/ntp">ftp://ftp.trimble.com/pub/ntp</a>
<p>This documentation describes version 7.12 of the GPS Firmware and version 2.46 (July 15, 1999) and later, of the driver source.<br> </p>
+ <p>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.</p>
<h2><font size="+1">Operating System Compatibility</font></h2>
The Palisade driver has been tested on the following software and hardware platforms:<br>
<center>
<td>20 us</td>
</tr>
</table>
- </center>
+ </center><P>
+ <b>Attention</b>: Thunderbolt Receiver has not being tested on the previous software and hardware plataforms.
<h2><font size="+1">GPS Receiver</font></h2>
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.
<p>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.</p>
<tt># and set flag2 to turn off event polling.</tt><br>
<tt><a href="#flag2">fudge 127.127.29.0 flag2 1</a></tt><br>
<tt>#------------------------------------------------------------------------------</tt><br> </p>
+
+ <h4>Thunderbolt NTP Configuration file</h4>
+ <tt>#------------------------------------------------------------------------------</tt>
+ <p>Configuration without event polling:<br>
+ <tt>#------------------------------------------------------------------------------</tt><br>
+ <tt># The Primary reference</tt><br>
+ <tt>server 127.127.29.0 mode 2 # Trimble Thunderbolt GPS (Stratum 1).</tt><br>
+ <tt># Set packet delay</tt><br>
+ <tt><a href="#time1">fudge 127.127.29.0 time1 0.020</a></tt><br>
+ <tt># and set flag2 to turn off event polling.</tt><br>
+ <tt><a href="#flag2">fudge 127.127.29.0 flag2 1</a></tt><br>
+ <tt>#------------------------------------------------------------------------------</tt><br> </p>
+ 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.
<h2><a name="TimeTransfer"></a><font size="+1">Time Transfer and Polling</font></h2>
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.
<p>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.</p>
<h2><font size="+1">Mode Parameter</font></h2>
<dl>
<dt><tt><font size="+1">mode <i>number</i></font></tt>
- <dd>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.
+ <dd>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 <b>1</b> for an <b>Endrun Praecis</b> in Trimble emulation mode, and <b>2</b> for the <b>Trimble Thunderbolt</b> GPS Disciplined Clock Receiver.
</dl>
<h2><font size="+1">DEFINEs</font></h2>
The following constants are defined in the driver source code. These defines may be modified to improve performance or adapt to new operating systems.<br>
</tr>
</table>
</center>
+
<blockquote>
<h4>Leap Second Flag Definition:</h4>Bit 0: (1) UTC Time is available<br>
Bits 1 - 3: Undefined<br>Bit 4: (1) Leap Scheduled: Leap second pending asserted by GPS control segment.<br>Bit 5: (1) Leap Pending: set 24 hours before, until beginning of leap second.<br>Bit 6: (1) GPS Leap Warning: 6 hours before until 6 hours after leap event<br>Bit 7: (1) Leap In Progress. Only set during the leap second.
</tr>
</table>
</center>
+ <h3>Thunderbolt Timing packets Data Format</h3>
+ Thunderbolt can output 2 synchronous packets.
+ <h4><b>Primary Timing Packet - 0x8FAB</h4>
+ <center>
+ <table>
+ <tr>
+ <td><b>Byte</b></td>
+ <td><b>Bit</b></td>
+ <td><b>Item</b></td>
+ <td><b>Type</b></td>
+ <td><b>Value</b></td>
+ <td><b>Description</b></td>
+ </tr>
+ <tr>
+ <td>0</td>
+ <td></td>
+ <td>Subcode</td>
+ <td>UINT8</td>
+ <td></td>
+ <td>0xAB</td>
+ </tr>
+ <tr>
+ <td>1-4</td>
+ <td></td>
+ <td>Time of Week</td>
+ <td>UINT32</td>
+ <td></td>
+ <td>GPS seconds of week</td>
+ </tr>
+ <tr>
+ <td>5-6</td>
+ <td></td>
+ <td>Week Number</td>
+ <td>UINT16</td>
+ <td></td>
+ <td>GPS Week Number</td>
+ </tr>
+ <tr>
+ <td>7-8</td>
+ <td></td>
+ <td>UTC Offset</td>
+ <td>SINT16</td>
+ <td></td>
+ <td>UTC Offset (seconds)</td>
+ </tr>
+ <tr>
+ <td valign="top">9</td>
+ <td><table><tr><td>0</td></tr><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</tr><tr><td>4</tr></table></td>
+ <td valign="top">Timing Flag</td>
+ <td valign="top">Bit field</td>
+ <td valign="top"><table><tr><td>0 or 1</td></tr><tr><td>0 or 1</td></tr><tr><td>0 or 1</td></tr><tr><td>0 or 1</tr><tr><td>0 or 1</tr></table></td></td>
+ <td valign="top"><table><tr><td>GPS Time or UTC Time</td></tr><tr><td>GPS PPS or UTC PPS</td></tr><tr><td>time is set or time is not set</td></tr><tr><td>have UTC info or no UTC info</td></tr><tr><td>Time from GPS or time from user</td></tr></table></td>
+ </tr>
+ <tr>
+ <td>10</td>
+ <td></td>
+ <td>Seconds</td>
+ <td>UINT8</td>
+ <td>0-59</td>
+ <td>(60 for UTC leap second event)</td>
+ </tr>
+ <tr>
+ <td>11</td>
+ <td></td>
+ <td>Minutes</td>
+ <td>UINT8</td>
+ <td>0-59</td>
+ <td>Minutes of Hour</td>
+ </tr>
+ <tr>
+ <td>12</td>
+ <td></td>
+ <td>Hours</td>
+ <td>UINT8</td>
+ <td>0-23</td>
+ <td>Hour of Day</td>
+ </tr>
+ <tr>
+ <td>13</td>
+ <td></td>
+ <td>Day of Month</td>
+ <td>UINT8</td>
+ <td>1-31</td>
+ <td>Day of Month</td>
+ </tr>
+ <tr>
+ <td>14</td>
+ <td></td>
+ <td>Month</td>
+ <td>UINT8</td>
+ <td>1-12</td>
+ <td>Month of Year</td>
+ </tr>
+ <tr>
+ <td>15-16</td>
+ <td></td>
+ <td>Year</td>
+ <td>UINT16</td>
+ <td></td>
+ <td>Four digits of Year (e.g. 1998)</td>
+ </tr>
+ </table>
+ </center>
+ <h4><b>Supplemental Timing Packet - 0x8FAC</h4>
+ <center>
+ <table>
+ <tr>
+ <td><b>Byte</b></td>
+ <td><b>Bit</b></td>
+ <td><b>Item</b></td>
+ <td><b>Type</b></td>
+ <td><b>Value</b></td>
+ <td><b>Description</b></td>
+ </tr>
+ <tr>
+ <td>0</td>
+ <td></td>
+ <td>Subcode</td>
+ <td>UINT8</td>
+ <td></td>
+ <td>0xAC</td>
+ </tr>
+ <tr>
+ <td valign="top">1</td>
+ <td></td>
+ <td valign="top">Receiver Mode</td>
+ <td valign="top">UINT8</td>
+ <td valign="top"><table><tr><td>0</td></tr><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</td></tr><tr><td>4</td></tr><tr><td>5</td></tr><tr><td>6</td></tr></table></td>
+ <td valign="top"><table><tr><td>Automatic (2D/3D)</td></tr><tr><td>Single Satellite (Time)</td></tr><tr><td>Horizontal (2D)</td></tr><tr><td>Full Position (3D)</td></tr><tr><td>DGPS Reference</td></tr><tr><td>Clock Hold (2D)</td></tr><tr><td>Overdetermined Clock</td></tr></table></td>
+ </tr>
+ <tr>
+ <td valign="top">2</td>
+ <td></td>
+ <td valign="top">Disciplining Mode</td>
+ <td valign="top">UINT8</td>
+ <td valign="top"><table><tr><td>0</td></tr><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</td></tr><tr><td>4</td></tr><tr><td>5</td></tr><tr><td>6</td></tr></table></td>
+ <td valign="top"><table><tr>Normal<td></td></tr><tr><td>Power-Up</td></tr><tr><td>Auto Holdover</td></tr><tr><td>Manual Holdover</td></tr><tr><td>Recovery</td></tr><tr><td>Not Used</td></tr><tr><td>Disciplining disabled</td></tr></table></td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td></td>
+ <td>Self-Survey Progress</td>
+ <td>UINT 8</td>
+ <td>0-100%</td>
+ <td></td>
+ <tr>
+ <td>4-7</td>
+ <td></td>
+ <td>Holdover Duration</td>
+ <td>UINT 32</td>
+ <td></td>
+ <td>seconds</td>
+ </tr>
+ <tr>
+ <td valign="top">8-9</td>
+ <td><table><tr><td>0</td></tr><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</tr><tr><td>4</tr></table></td>
+ <td valign="top">Critical Alarms</td>
+ <td valign="top">UINT16</td>
+ <td valign="top">Bit field</td>
+ <td valign="top"><table><tr><td>ROM checksum error</td></tr><tr><td>RAM check has failed</td></tr><tr><td>Power supply failure</td></tr><tr><td>FPGA check has failed</td></tr><tr><td>Oscillator control voltage at rail</td></tr></table></td>
+ </tr>
+ <tr>
+ <td valign="top">10-11</td>
+ <td valign="top"><table><tr><td>0</td></tr><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</tr><tr><td>4</tr><tr><td>5</td></tr><tr><td>6</td></tr></table></td>
+ <td valign="top">Minor Alarms</td>
+ <td valign="top">UINT16</td>
+ <td valign="top">Bit field</td>
+ <td valign="top"><table><tr><td>Normal</td></tr><tr><td>Power-Up</td></tr><tr><td>Auto Holdover</td></tr><tr><td>Manual Holdover</tr><tr><td>Recovery</tr><tr><td>Not Used</td></tr><tr><td>Disciplining disabled</td></tr></table></td>
+ </tr>
+ <tr>
+ <td valign="top">12</td>
+ <td></td>
+ <td valign="top">GPS Decoding Status</td>
+ <td valign="top">UINT8</td>
+ <td valign="top"><table><tr><td>0</td></tr><tr><td>1</td></tr><tr><td>3</td></tr><tr><td>8</tr><tr><td>9</tr><tr><td>0x0A</td></tr><tr><td>0x0B</td></tr><tr><td>0x0C</td></tr><tr><td>0x10</tr></table></td>
+ <td valign="top"><table><tr><td>Doing fixes</td></tr><tr><td>Don t have GPS time</td></tr><tr><td>PDOP is too high</td></tr><tr><td>No usable sats</tr><tr><td>Only 1 usable sat</tr><tr><td>Only 2 usable sats</td></tr><tr><td>Only 3 usable sats</td></tr><tr><td>The chosen sat is unusable</td></tr><tr><td>TRAIM rejected the fix</tr></table></td>
+ </tr>
+ <tr>
+ <td valign="top">13</td>
+ <td></td>
+ <td valign="top">Disciplining Activity</td>
+ <td valign="top">UINT8</td>
+ <td><table><tr><td>0</td></tr><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</tr><tr><td>4</tr><tr><td>5</td></tr><tr><td>6</td></tr><tr><td>7</td></tr><tr><td>8</tr></table></td>
+ <td><table><tr><td>Phase locking</td></tr><tr><td>Oscillator warming up</td></tr><tr><td>Frequency locking</td></tr><tr><td>Placing PPS</tr><tr><td>Initializing loop filter</tr><tr><td>Compensating OCXO</td></tr><tr><td>Inactive</td></tr><tr><td>Not used</td></tr><tr><td>Recovery mode</tr></table></td>
+ </tr>
+ <tr>
+ <td>14</td>
+ <td></td>
+ <td>Spare Status 1</td>
+ <td>UINT8</td>
+ <td>0</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>15</td>
+ <td></td>
+ <td>Spare Status 2</td>
+ <td>UINT8</td>
+ <td>0</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>16-19</td>
+ <td></td>
+ <td>PPS Offset</td>
+ <td>Single</td>
+ <td></td>
+ <td>Estimate of UTC/GPS offset (ns)</td>
+ </tr>
+ <tr>
+ <td>20-23</td>
+ <td></td>
+ <td>10 MHz Offset</td>
+ <td>Single</td>
+ <td></td>
+ <td>Estimate of UTC/GPS offset (ns)</td>
+ </tr>
+ <tr>
+ <td>24-27</td>
+ <td></td>
+ <td>DAC Value</td>
+ <td>UINT32</td>
+ <td></td>
+ <td>Offset binary (0x00 - 0xFFFFF)</td>
+ </tr>
+ <tr>
+ <td>28-31</td>
+ <td></td>
+ <td>DAC Voltage</td>
+ <td>Single</td>
+ <td></td>
+ <td>Volts</td>
+ </tr>
+ <tr>
+ <td>32-35</td>
+ <td></td>
+ <td>Temperature</td>
+ <td>Single</td>
+ <td></td>
+ <td>degrees C</td>
+ </tr>
+ <tr>
+ <td>36-43</td>
+ <td></td>
+ <td>Latitude</td>
+ <td>Double</td>
+ <td></td>
+ <td>radians</td>
+ </tr>
+ <tr>
+ <td>44-51</td>
+ <td></td>
+ <td>Longitude</td>
+ <td>Double</td>
+ <td></td>
+ <td>radians</td>
+ </tr>
+ <tr>
+ <td>52-59</td>
+ <td></td>
+ <td>Altitude</td>
+ <td>Double</td>
+ <td></td>
+ <td>Meters</td>
+ </tr>
+ <tr>
+ <td>60-67</td>
+ <td></td>
+ <td>Spare</td>
+ <td></td>
+ <td></td>
+ <td>For Future Expantion</td>
+ </tr>
+ </table>
+ </center>
<h2><a name="Pinouts"></a><font size="+1">Pinouts</font></h2>
<a href="#Connection">The following connections are required when connecting Palisade with a host:</a><br> <br>
<center>
</tr>
</table>
</center>
+
+ <b><h3>Notes on the Thunderbolt Receiver's Firmware</h3></b>
+
+ 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:<p>
+<a href="https://lists.ntp.isc.org/pipermail/hackers/2006-April/002216.html">https://lists.ntp.isc.org/pipermail/hackers/2006-April/002216.html
<p></p>
<hr>
<p>Questions or Comments:<br>
<a href="mailto:sven_dietrich@trimble.com">Sven Dietrich</a><br>
<a href="http://www.trimble.com/">Trimble Navigation Ltd.</a></p>
- <p>(last updated July 29, 1999)</p>
+ <a href="mailto:fernandoph@iar.unlp.edu.ar">Fernando P. Hauscarriaga</a><br>
+ <p>(last updated January 15, 2007)</p>
<hr>
<script type="text/javascript" language="javascript" src="scripts/footer.txt"></script>
;
*
* 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
/* 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
*/
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
*/
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;
up->rpt_status = TSIP_PARSED_EMPTY;
up->rpt_cnt = 0;
+ if (up->type == CLK_THUNDERBOLT)
+ init_thunderbolt(fd);
+
return 1;
}
* 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) ||
/* 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
switch (mb(0) & 0xff) {
int GPS_UTC_Offset;
+ long tow;
+
case PACKET_8F0B:
if (up->polled <= 0)
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
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 */
# define _SVID3
# endif
# include <termios.h>
+# include <sys/stat.h>
# ifdef TERMIOS_NEEDS__SVID3
# undef _SVID3
# endif
#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
#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.
*/
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 */