2 * This software was developed by the Software and Component Technologies
3 * group of Trimble Navigation, Ltd.
5 * Copyright (c) 1997, 1998, 1999, 2000 Trimble Navigation Ltd.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Trimble Navigation, Ltd.
19 * 4. The name of Trimble Navigation Ltd. may not be used to endorse or
20 * promote products derived from this software without specific prior
23 * THIS SOFTWARE IS PROVIDED BY TRIMBLE NAVIGATION LTD. ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL TRIMBLE NAVIGATION LTD. BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * refclock_palisade - clock driver for the Trimble Palisade GPS
40 * For detailed information on this program, please refer to the html
41 * Refclock 29 page accompanying the NTP distribution.
43 * for questions / bugs / comments, contact:
44 * sven_dietrich@trimble.com
46 * Sven-Thorsten Dietrich
47 * 645 North Mary Avenue
48 * Post Office Box 3642
49 * Sunnyvale, CA 94088-3642
51 * Version 2.45; July 14, 1999
55 * 31/03/06: Added support for Thunderbolt GPS Disciplined Clock.
56 * Contact: Fernando Pablo Hauscarriaga
57 * E-mail: fernandoph@iar.unlp.edu.ar
58 * Home page: www.iar.unlp.edu.ar/~fernandoph
59 * Instituto Argentino de Radioastronomia
62 * 14/01/07: Conditinal compilation for Thunderbolt support no longer needed
63 * now we use mode 2 for decode thunderbolt packets.
64 * Fernando P. Hauscarriaga
66 * 30/08/09: Added support for Trimble Acutime Gold Receiver.
67 * Fernando P. Hauscarriaga (fernandoph@iar.unlp.edu.ar)
74 #if defined(REFCLOCK) && defined(CLOCK_PALISADE)
77 extern int async_write(int, const void *, unsigned int);
79 #define write(fd, data, octets) async_write(fd, data, octets)
82 #include "refclock_palisade.h"
83 /* Table to get from month to day of the year */
84 const int days_of_year [12] = {
85 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
89 const char * Tracking_Status[15][15] = {
90 { "Doing Fixes\0" }, { "Good 1SV\0" }, { "Approx. 1SV\0" },
91 {"Need Time\0" }, { "Need INIT\0" }, { "PDOP too High\0" },
92 { "Bad 1SV\0" }, { "0SV Usable\0" }, { "1SV Usable\0" },
93 { "2SV Usable\0" }, { "3SV Usable\0" }, { "No Integrity\0" },
94 { "Diff Corr\0" }, { "Overdet Clock\0" }, { "Invalid\0" } };
100 struct refclock refclock_palisade = {
101 palisade_start, /* start up driver */
102 palisade_shutdown, /* shut down driver */
103 palisade_poll, /* transmit poll message */
104 noentry, /* not used */
105 noentry, /* initialize driver (not used) */
106 noentry, /* not used */
107 NOFLAGS /* not used */
110 int day_of_year (char *dt);
112 /* Extract the clock type from the mode setting */
113 #define CLK_TYPE(x) ((int)(((x)->ttl) & 0x7F))
115 /* Supported clock types */
116 #define CLK_TRIMBLE 0 /* Trimble Palisade */
117 #define CLK_PRAECIS 1 /* Endrun Technologies Praecis */
118 #define CLK_THUNDERBOLT 2 /* Trimble Thunderbolt GPS Receiver */
119 #define CLK_ACUTIME 3 /* Trimble Acutime Gold */
120 #define CLK_ACUTIMEB 4 /* Trimble Actutime Gold Port B */
123 static void praecis_parse(struct recvbuf *rbufp, struct peer *peer);
125 /* These routines are for sending packets to the Thunderbolt receiver
126 * They are taken from Markus Prosch
129 #ifdef PALISADE_SENDCMD_RESURRECTED
131 * sendcmd - Build data packet for sending
135 struct packettx *buffer,
140 *(buffer->data + 1) = (unsigned char)c;
143 #endif /* PALISADE_SENDCMD_RESURRECTED */
146 * sendsupercmd - Build super data packet for sending
150 struct packettx *buffer,
156 *(buffer->data + 1) = (unsigned char)c1;
157 *(buffer->data + 2) = (unsigned char)c2;
166 struct packettx *buffer,
171 *(buffer->data+buffer->size++) = DLE;
172 *(buffer->data+buffer->size++) = (unsigned char)b;
180 struct packettx *buffer,
184 sendbyte(buffer, (unsigned char)((a>>8) & 0xff));
185 sendbyte(buffer, (unsigned char)(a & 0xff));
189 * sendetx - Send packet or super packet to the device
193 struct packettx *buffer,
199 *(buffer->data+buffer->size++) = DLE;
200 *(buffer->data+buffer->size++) = ETX;
201 result = write(fd, buffer->data, (unsigned long)buffer->size);
210 * init_thunderbolt - Prepares Thunderbolt receiver to be used with
211 * NTP (also taken from Markus Prosch).
221 tx.data = (u_char *) malloc(100);
224 sendsupercmd (&tx, 0x8E, 0xA2);
228 /* activate packets 0x8F-AB and 0x8F-AC */
229 sendsupercmd (&tx, 0x8F, 0xA5);
237 * init_acutime - Prepares Acutime Receiver to be used with NTP
244 /* Disable all outputs, Enable Event-Polling on PortA so
245 we can ask for time packets */
249 tx.data = (u_char *) malloc(100);
251 sendsupercmd(&tx, 0x8E, 0xA5);
262 * palisade_start - open the devices and initialize data for processing
270 struct palisade_unit *up;
271 struct refclockproc *pp;
276 snprintf(gpsdev, sizeof(gpsdev), DEVICE, unit);
281 fd = refclock_open(gpsdev, SPEED232, LDISC_RAW);
284 printf("Palisade(%d) start: open %s failed\n", unit, gpsdev);
289 msyslog(LOG_NOTICE, "Palisade(%d) fd: %d dev: %s", unit, fd,
292 if (tcgetattr(fd, &tio) < 0) {
294 "Palisade(%d) tcgetattr(fd, &tio): %m",unit);
296 printf("Palisade(%d) tcgetattr(fd, &tio)\n",unit);
302 tio.c_cflag |= (PARENB|PARODD);
303 tio.c_iflag &= ~ICRNL;
306 * Allocate and initialize unit structure
308 up = emalloc_zero(sizeof(*up));
310 up->type = CLK_TYPE(peer);
313 /* Normal mode, do nothing */
316 msyslog(LOG_NOTICE, "Palisade(%d) Praecis mode enabled"
319 case CLK_THUNDERBOLT:
320 msyslog(LOG_NOTICE, "Palisade(%d) Thunderbolt mode enabled"
322 tio.c_cflag = (CS8|CLOCAL|CREAD);
325 msyslog(LOG_NOTICE, "Palisade(%d) Acutime Gold mode enabled"
329 msyslog(LOG_NOTICE, "Palisade(%d) mode unknown",unit);
332 if (tcsetattr(fd, TCSANOW, &tio) == -1) {
333 msyslog(LOG_ERR, "Palisade(%d) tcsetattr(fd, &tio): %m",unit);
335 printf("Palisade(%d) tcsetattr(fd, &tio)\n",unit);
343 pp->io.clock_recv = palisade_io;
344 pp->io.srcclock = peer;
347 if (!io_addclock(&pp->io)) {
349 printf("Palisade(%d) io_addclock\n",unit);
358 * Initialize miscellaneous variables
361 pp->clockdesc = DESCRIPTION;
363 peer->precision = PRECISION;
364 peer->sstclktype = CTL_SST_TS_UHF;
365 peer->minpoll = TRMB_MINPOLL;
366 peer->maxpoll = TRMB_MAXPOLL;
367 memcpy((char *)&pp->refid, REFID, 4);
370 up->unit = (short) unit;
371 up->rpt_status = TSIP_PARSED_EMPTY;
374 if (up->type == CLK_THUNDERBOLT)
375 init_thunderbolt(fd);
376 if (up->type == CLK_ACUTIME)
384 * palisade_shutdown - shut down the clock
392 struct palisade_unit *up;
393 struct refclockproc *pp;
397 io_closeclock(&pp->io);
405 * unpack_date - get day and year from date
415 /* Check month is inside array bounds */
416 if ((mon < 1) || (mon > 12))
419 day = dt[0] + days_of_year[mon - 1];
420 year = getint((u_char *) (dt + 2));
422 if ( !(year % 4) && ((year % 100) ||
423 (!(year % 100) && !(year%400)))
425 day ++; /* leap year and March or later */
432 * TSIP_decode - decode the TSIP data packets
443 unsigned short event = 0;
445 struct palisade_unit *up;
446 struct refclockproc *pp;
452 * Check the time packet, decode its contents.
453 * If the timecode has invalid length or is not in
454 * proper format, declare bad format and exit.
457 if ((up->type != CLK_THUNDERBOLT) & (up->type != CLK_ACUTIME)){
458 if ((up->rpt_buf[0] == (char) 0x41) ||
459 (up->rpt_buf[0] == (char) 0x46) ||
460 (up->rpt_buf[0] == (char) 0x54) ||
461 (up->rpt_buf[0] == (char) 0x4B) ||
462 (up->rpt_buf[0] == (char) 0x6D)) {
464 /* standard time packet - GPS time and GPS week number */
466 printf("Palisade Port B packets detected. Connect to Port A\n");
474 * We cast both to u_char to as 0x8f uses the sign bit on a char
476 if ((u_char) up->rpt_buf[0] == (u_char) 0x8f) {
480 event = (unsigned short) (getint((u_char *) &mb(1)) & 0xffff);
481 if (!((pp->sloppyclockflag & CLK_FLAG2) || event))
485 switch (mb(0) & 0xff) {
494 if (up->rpt_cnt != LENCODE_8F0B) /* check length */
500 double lat, lon, alt;
501 lat = getdbl((u_char *) &mb(42)) * R2D;
502 lon = getdbl((u_char *) &mb(50)) * R2D;
503 alt = getdbl((u_char *) &mb(58));
505 printf("TSIP_decode: unit %d: Latitude: %03.4f Longitude: %03.4f Alt: %05.2f m\n",
506 up->unit, lat,lon,alt);
507 printf("TSIP_decode: unit %d: Sats:",
509 for (st = 66, ts = 0; st <= 73; st++)
511 if (mb(st) > 0) ts++;
512 printf(" %02d", mb(st));
514 printf(" : Tracking %d\n", ts);
518 GPS_UTC_Offset = getint((u_char *) &mb(16));
519 if (GPS_UTC_Offset == 0) { /* Check UTC offset */
521 printf("TSIP_decode: UTC Offset Unknown\n");
526 secs = getdbl((u_char *) &mb(3));
527 secint = (long) secs;
528 secfrac = secs - secint; /* 0.0 <= secfrac < 1.0 */
530 pp->nsec = (long) (secfrac * 1000000000);
532 secint %= 86400; /* Only care about today */
533 pp->hour = secint / 3600;
535 pp->minute = secint / 60;
537 pp->second = secint % 60;
539 if ((pp->day = day_of_year(&mb(11))) < 0) break;
541 pp->year = getint((u_char *) &mb(13));
545 printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%09ld %02d/%02d/%04d UTC %02d\n",
546 up->unit, mb(0) & 0xff, event, pp->hour, pp->minute,
547 pp->second, pp->nsec, mb(12), mb(11), pp->year, GPS_UTC_Offset);
549 /* Only use this packet when no
550 * 8F-AD's are being received
553 if (up->leap_status) {
562 /* Palisade-NTP Packet */
564 if (up->rpt_cnt != LENCODE_NTP) /* check length */
567 up->leap_status = mb(19);
572 /* Check Tracking Status */
574 if (st < 0 || st > 14)
576 if ((st >= 2 && st <= 7) || st == 11 || st == 12) {
578 printf("TSIP_decode: Not Tracking Sats : %s\n",
579 *Tracking_Status[st]);
581 refclock_report(peer, CEVNT_BADTIME);
587 if (up->leap_status & PALISADE_LEAP_PENDING) {
588 if (up->leap_status & PALISADE_UTC_TIME)
589 pp->leap = LEAP_ADDSECOND;
591 pp->leap = LEAP_DELSECOND;
593 else if (up->leap_status)
594 pp->leap = LEAP_NOWARNING;
596 else { /* UTC flag is not set:
597 * Receiver may have been reset, and lost
598 * its UTC almanac data */
599 pp->leap = LEAP_NOTINSYNC;
601 printf("TSIP_decode: UTC Almanac unavailable: %d\n",
604 refclock_report(peer, CEVNT_BADTIME);
609 pp->nsec = (long) (getdbl((u_char *) &mb(3))
612 if ((pp->day = day_of_year(&mb(14))) < 0)
614 pp->year = getint((u_char *) &mb(16));
621 printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%09ld %02d/%02d/%04d UTC %02x %s\n",
622 up->unit, mb(0) & 0xff, event, pp->hour, pp->minute,
623 pp->second, pp->nsec, mb(15), mb(14), pp->year,
624 mb(19), *Tracking_Status[st]);
633 if (up->rpt_cnt != LENCODE_8FAC)/* check length */
638 double lat, lon, alt;
639 lat = getdbl((u_char *) &mb(36)) * R2D;
640 lon = getdbl((u_char *) &mb(44)) * R2D;
641 alt = getdbl((u_char *) &mb(52));
643 printf("TSIP_decode: unit %d: Latitude: %03.4f Longitude: %03.4f Alt: %05.2f m\n",
644 up->unit, lat,lon,alt);
645 printf("TSIP_decode: unit %d\n", up->unit);
648 if (getint((u_char *) &mb(10)) & 0x80)
649 pp->leap = LEAP_ADDSECOND; /* we ASSUME addsecond */
651 pp->leap = LEAP_NOWARNING;
655 printf("TSIP_decode: unit %d: 0x%02x leap %d\n",
656 up->unit, mb(0) & 0xff, pp->leap);
658 printf("Receiver MODE: 0x%02X\n", (u_char)mb(1));
660 printf(" AUTOMATIC\n");
662 printf(" SINGLE SATELLITE\n");
664 printf(" HORIZONTAL(2D)\n");
666 printf(" FULL POSITION(3D)\n");
668 printf(" DGPR REFERENCE\n");
670 printf(" CLOCK HOLD(2D)\n");
672 printf(" OVERDETERMINED CLOCK\n");
674 printf("\n** Disciplining MODE 0x%02X:\n", (u_char)mb(2));
678 printf(" POWER-UP\n");
680 printf(" AUTO HOLDOVER\n");
682 printf(" MANUAL HOLDOVER\n");
684 printf(" RECOVERY\n");
686 printf(" DISCIPLINING DISABLED\n");
693 /* Thunderbolt Primary Timing Packet */
695 if (up->rpt_cnt != LENCODE_8FAB) /* check length */
701 GPS_UTC_Offset = getint((u_char *) &mb(7));
703 if (GPS_UTC_Offset == 0){ /* Check UTC Offset */
705 printf("TSIP_decode: UTC Offset Unknown\n");
711 if ((mb(9) & 0x1d) == 0x0) {
712 /* if we know the GPS time and the UTC offset,
713 we expect UTC timing information !!! */
715 pp->leap = LEAP_NOTINSYNC;
716 refclock_report(peer, CEVNT_BADTIME);
723 printf("\nTiming Flags are:\n");
724 printf("Timing flag value is: 0x%X\n", mb(9));
725 if ((mb(9) & 0x01) != 0)
726 printf (" Getting UTC time\n");
728 printf (" Getting GPS time\n");
729 if ((mb(9) & 0x02) != 0)
730 printf (" PPS is from UTC\n");
732 printf (" PPS is from GPS\n");
733 if ((mb(9) & 0x04) != 0)
734 printf (" Time is not Set\n");
736 printf (" Time is Set\n");
737 if ((mb(9) & 0x08) != 0)
738 printf(" I dont have UTC info\n");
740 printf (" I have UTC info\n");
741 if ((mb(9) & 0x10) != 0)
742 printf (" Time is from USER\n\n");
744 printf (" Time is from GPS\n\n");
747 if ((pp->day = day_of_year(&mb(13))) < 0)
749 tow = getlong((u_char *) &mb(1));
752 printf("pp->day: %d\n", pp->day);
753 printf("TOW: %ld\n", tow);
754 printf("DAY: %d\n", mb(13));
757 pp->year = getint((u_char *) &mb(15));
765 printf("TSIP_decode: unit %d: %02X #%d %02d:%02d:%02d.%09ld %02d/%02d/%04d ",up->unit, mb(0) & 0xff, event, pp->hour, pp->minute, pp->second, pp->nsec, mb(14), mb(13), pp->year);
774 } /* if 8F packets */
776 else if (up->rpt_buf[0] == (u_char)0x42) {
780 else if (up->rpt_buf[0] == (u_char)0x43) {
784 else if ((up->rpt_buf[0] == PACKET_41) & (up->type == CLK_THUNDERBOLT)){
785 printf("Undocumented 0x41 packet on Thunderbolt\n");
788 else if ((up->rpt_buf[0] == PACKET_41A) & (up->type == CLK_ACUTIME)) {
790 printf("GPS TOW: %ld\n", (long)getlong((u_char *) &mb(0)));
791 printf("GPS WN: %d\n", getint((u_char *) &mb(4)));
792 printf("GPS UTC-GPS Offser: %ld\n", (long)getlong((u_char *) &mb(6)));
797 /* Health Status for Acutime Receiver */
798 else if ((up->rpt_buf[0] == PACKET_46) & (up->type == CLK_ACUTIME)) {
804 printf ("Doing Position Fixes\n");
807 printf ("Do no have GPS time yet\n");
810 printf ("PDOP is too high\n");
813 printf ("No usable satellites\n");
816 printf ("Only 1 usable satellite\n");
819 printf ("Only 2 usable satellites\n");
822 printf ("Only 3 usable satellites\n");
825 printf("The Chosen satellite is unusable\n");
832 refclock_report(peer, CEVNT_BADTIME);
837 printf ("Signal Processor Error, reset unit.\n");
839 printf ("Alignment error, channel or chip 1, reset unit.\n");
841 printf ("Alignment error, channel or chip 2, reset unit.\n");
843 printf ("Antenna feed line fault (open or short)\n");
845 printf ("Excessive reference frequency error, refer to packet 0x2D and packet 0x4D documentation for further information\n");
852 else if (up->rpt_buf[0] == 0x54)
855 else if (up->rpt_buf[0] == PACKET_6D) {
859 if ((mb(0) & 0x01) && (mb(0) & 0x02))
860 printf("2d Fix Dimension\n");
862 printf("3d Fix Dimension\n");
865 printf("Fix Mode is MANUAL\n");
867 printf("Fix Mode is AUTO\n");
871 printf("Tracking %d Satellites\n", sats);
874 } /* else if not super packet */
875 refclock_report(peer, CEVNT_BADREPLY);
878 printf("TSIP_decode: unit %d: bad packet %02x-%02x event %d len %d\n",
879 up->unit, up->rpt_buf[0] & 0xff, mb(0) & 0xff,
886 * palisade__receive - receive data from the serial interface
894 struct palisade_unit *up;
895 struct refclockproc *pp;
898 * Initialize pointers and read the timecode and timestamp.
903 if (! TSIP_decode(peer)) return;
906 return; /* no poll pending, already received or timeout */
908 up->polled = 0; /* Poll reply received */
909 pp->lencode = 0; /* clear time code */
913 "palisade_receive: unit %d: %4d %03d %02d:%02d:%02d.%09ld\n",
914 up->unit, pp->year, pp->day, pp->hour, pp->minute,
915 pp->second, pp->nsec);
920 * Generate timecode: YYYY DoY HH:MM:SS.microsec
924 snprintf(pp->a_lastcode, sizeof(pp->a_lastcode),
925 "%4d %03d %02d:%02d:%02d.%09ld",
927 pp->hour,pp->minute, pp->second, pp->nsec);
930 if (!refclock_process(pp)) {
931 refclock_report(peer, CEVNT_BADTIME);
934 printf("palisade_receive: unit %d: refclock_process failed!\n",
940 record_clock_stats(&peer->srcadr, pp->a_lastcode);
944 printf("palisade_receive: unit %d: %s\n",
945 up->unit, prettydate(&pp->lastrec));
947 pp->lastref = pp->lastrec;
948 refclock_receive(peer);
953 * palisade_poll - called by the transmit procedure
962 struct palisade_unit *up;
963 struct refclockproc *pp;
969 if (up->polled > 0) /* last reply never arrived or error */
970 refclock_report(peer, CEVNT_TIMEOUT);
972 up->polled = 2; /* synchronous packet + 1 event */
976 printf("palisade_poll: unit %d: polling %s\n", unit,
977 (pp->sloppyclockflag & CLK_FLAG2) ?
978 "synchronous packet" : "event");
981 if (pp->sloppyclockflag & CLK_FLAG2)
982 return; /* using synchronous packet input */
984 if(up->type == CLK_PRAECIS) {
985 if(write(peer->procptr->io.fd,"SPSTAT\r\n",8) < 0)
986 msyslog(LOG_ERR, "Palisade(%d) write: %m:",unit);
994 refclock_report(peer, CEVNT_FAULT);
999 struct recvbuf *rbufp,
1003 static char buf[100];
1005 struct refclockproc *pp;
1009 memcpy(buf+p,rbufp->recv_space.X_recv_buffer, rbufp->recv_length);
1010 p += rbufp->recv_length;
1012 if(buf[p-2] == '\r' && buf[p-1] == '\n') {
1014 record_clock_stats(&peer->srcadr, buf);
1019 if (HW_poll(pp) < 0)
1020 refclock_report(peer, CEVNT_FAULT);
1027 struct recvbuf *rbufp
1031 * Initialize pointers and read the timecode and timestamp.
1033 struct palisade_unit *up;
1034 struct refclockproc *pp;
1039 peer = rbufp->recv_peer;
1043 if(up->type == CLK_PRAECIS) {
1045 praecis_parse(rbufp,peer);
1050 c = (char *) &rbufp->recv_space;
1051 d = c + rbufp->recv_length;
1055 /* Build time packet */
1056 switch (up->rpt_status) {
1058 case TSIP_PARSED_DLE_1:
1064 up->rpt_status = TSIP_PARSED_EMPTY;
1068 up->rpt_status = TSIP_PARSED_DATA;
1069 /* save packet ID */
1070 up->rpt_buf[0] = *c;
1075 case TSIP_PARSED_DATA:
1077 up->rpt_status = TSIP_PARSED_DLE_2;
1079 mb(up->rpt_cnt++) = *c;
1082 case TSIP_PARSED_DLE_2:
1084 up->rpt_status = TSIP_PARSED_DATA;
1089 up->rpt_status = TSIP_PARSED_FULL;
1091 /* error: start new report packet */
1092 up->rpt_status = TSIP_PARSED_DLE_1;
1093 up->rpt_buf[0] = *c;
1097 case TSIP_PARSED_FULL:
1098 case TSIP_PARSED_EMPTY:
1101 up->rpt_status = TSIP_PARSED_EMPTY;
1103 up->rpt_status = TSIP_PARSED_DLE_1;
1109 if (up->rpt_status == TSIP_PARSED_DLE_1) {
1111 if (pp->sloppyclockflag & CLK_FLAG2)
1113 get_systime(&pp->lastrec);
1115 else if (up->rpt_status == TSIP_PARSED_EMPTY)
1118 else if (up->rpt_cnt > BMAX)
1119 up->rpt_status =TSIP_PARSED_EMPTY;
1121 if (up->rpt_status == TSIP_PARSED_FULL)
1122 palisade_receive(peer);
1124 } /* while chars in buffer */
1129 * Trigger the Palisade's event input, which is driven off the RTS
1131 * Take a system time stamp to match the GPS time stamp.
1136 struct refclockproc * pp /* pointer to unit structure */
1139 int x; /* state before & after RTS set */
1140 struct palisade_unit *up;
1144 /* read the current status, so we put things back right */
1145 if (ioctl(pp->io.fd, TIOCMGET, &x) < 0) {
1146 DPRINTF(1, ("Palisade HW_poll: unit %d: GET %m\n",
1148 msyslog(LOG_ERR, "Palisade(%d) HW_poll: ioctl(fd,GET): %m",
1153 x |= TIOCM_RTS; /* turn on RTS */
1156 if (up->type == CLK_ACUTIME)
1157 write (pp->io.fd, "", 1);
1159 if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) {
1162 printf("Palisade HW_poll: unit %d: SET \n", up->unit);
1165 "Palisade(%d) HW_poll: ioctl(fd, SET, RTS_on): %m",
1170 x &= ~TIOCM_RTS; /* turn off RTS */
1172 /* poll timestamp */
1173 get_systime(&pp->lastrec);
1175 if (ioctl(pp->io.fd, TIOCMSET, &x) == -1) {
1178 printf("Palisade HW_poll: unit %d: UNSET \n", up->unit);
1181 "Palisade(%d) HW_poll: ioctl(fd, UNSET, RTS_off): %m",
1190 * copy/swap a big-endian palisade double into a host double
1197 #ifdef WORDS_BIGENDIAN
1200 memcpy(&out, bp, sizeof(out));
1213 memcpy(ui.ch, bp, sizeof(ui.ch));
1214 /* least-significant 32 bits of double from swapped bp[4] to bp[7] */
1215 uo.u32[0] = ntohl(ui.u32[1]);
1216 /* most-significant 32 bits from swapped bp[0] to bp[3] */
1217 uo.u32[1] = ntohl(ui.u32[0]);
1224 * copy/swap a big-endian palisade short into a host short
1233 memcpy(&us, bp, sizeof(us));
1234 return (short)ntohs(us);
1238 * copy/swap a big-endian palisade 32-bit int into a host 32-bit int
1247 memcpy(&u32, bp, sizeof(u32));
1248 return (int32)(u_int32)ntohl(u32);
1251 #else /* REFCLOCK && CLOCK_PALISADE*/
1252 int refclock_palisade_c_notempty;