gpsd-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gpsd-dev] [PATCH 4/4] [isync] Autodetect and configure Spectratime iSyn


From: Michael Brown
Subject: [gpsd-dev] [PATCH 4/4] [isync] Autodetect and configure Spectratime iSync device
Date: Fri, 29 Jan 2016 14:36:49 +0000

Signed-off-by: Michael Brown <address@hidden>
---
 SConstruct   |   1 +
 driver_ubx.c |   8 ++-
 drivers.c    | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 174 insertions(+), 5 deletions(-)

diff --git a/SConstruct b/SConstruct
index bf1f0b8..de3ed89 100644
--- a/SConstruct
+++ b/SConstruct
@@ -120,6 +120,7 @@ boolopts = (
     ("gpsclock",      True,  "GPSClock support"),
     ("ntrip",         True,  "NTRIP support"),
     ("oceanserver",   True,  "OceanServer support"),
+    ("isync",         True,  "Spectratime iSync LNRClok/GRCLOK support"),
     ("rtcm104v2",     True,  "rtcm104v2 support"),
     ("rtcm104v3",     True,  "rtcm104v3 support"),
     ("passthrough",   True,  "build support for passing through JSON"),
diff --git a/driver_ubx.c b/driver_ubx.c
index 41ff709..d1d29f8 100644
--- a/driver_ubx.c
+++ b/driver_ubx.c
@@ -633,12 +633,8 @@ static gps_mask_t parse_input(struct gps_device_t *session)
     if (session->lexer.type == UBX_PACKET) {
        return ubx_parse(session, session->lexer.outbuffer,
                         session->lexer.outbuflen);
-#ifdef NMEA0183_ENABLE
-    } else if (session->lexer.type == NMEA_PACKET) {
-       return nmea_parse((char *)session->lexer.outbuffer, session);
-#endif /* NMEA0183_ENABLE */
     } else
-       return 0;
+       return generic_parse_input(session);
 }
 
 bool ubx_write(struct gps_device_t * session,
@@ -730,6 +726,8 @@ static void ubx_event_hook(struct gps_device_t *session, 
event_t event)
         */
        if (session->mode == O_OPTIMIZE) {
            ubx_mode(session, MODE_BINARY);
+       } else {
+           ubx_mode(session, MODE_NMEA);
        }
 #endif /* RECONFIGURE_ENABLE */
     } else if (event == event_deactivate) {
diff --git a/drivers.c b/drivers.c
index 0ce47e8..5d62706 100644
--- a/drivers.c
+++ b/drivers.c
@@ -1152,6 +1152,173 @@ const struct gps_type_t driver_mtk3301 = {
 /* *INDENT-ON* */
 #endif /* MTK3301_ENABLE */
 
+#ifdef ISYNC_ENABLE
+/**************************************************************************
+ *
+ * Spectratime LNRCLOK / GRCLOK iSync GPS-disciplined rubidium oscillators
+ *
+ * These devices comprise a u-blox 6 attached to a separate iSync
+ * microcontroller which drives the rubidium oscillator.  The iSync
+ * microcontroller can be configured to pass through the underlying
+ * GPS communication channel, while still using the GPS PPSREF signal
+ * to discipline the rubidium oscillator.
+ *
+ * The iSync can also generate its own periodic status packets in NMEA
+ * format.  These describe the state of the oscillator (including
+ * whether or not the oscillator PPSOUT is synced to the GPS PPSREF).
+ * These packets are transmitted in the middle of the underlying GPS
+ * packets, forcing us to handle interrupted NMEA packets.
+ *
+ * The default state of the device is to generate no periodic output.
+ * We send a probe string to initiate beating of the iSync-proprietary
+ * $PTNTS,B message, which is then detected as a NMEA trigger.
+ *
+ **************************************************************************/
+
+static ssize_t isync_write(struct gps_device_t *session, const char *data)
+
+{
+    return gpsd_write(session, data, strlen(data));
+}
+
+static bool isync_detect(struct gps_device_t *session)
+{
+    speed_t old_baudrate;
+    char old_parity;
+    unsigned int old_stopbits;
+
+    /* Set 9600 8N1 */
+    old_baudrate = session->gpsdata.dev.baudrate;
+    old_parity = session->gpsdata.dev.parity;
+    old_stopbits = session->gpsdata.dev.stopbits;
+    gpsd_set_speed(session, 9600, 'N', 1);
+
+    /* Cancel pass-through mode and initiate beating of $PTNTS,B
+     * message, which can subsequently be detected as a trigger.
+     */
+    (void)isync_write(session, "@@@@\r\nMAW0C0B\r\n");
+
+    /* return serial port to original settings */
+    gpsd_set_speed(session, old_baudrate, old_parity, old_stopbits);
+
+    return false;
+}
+
+static void isync_event_hook(struct gps_device_t *session, event_t event)
+{
+    if (session->context->readonly)
+       return;
+
+    if (event == event_driver_switch) {
+       session->lexer.counter = 0;
+    }
+
+    if (event == event_configure) {
+       switch (session->lexer.counter) {
+       case 1:
+           /* Configure timing and frequency flags:
+            *  - Thermal compensation active
+            *  - PPSREF active
+            *  - PPSOUT active
+            */
+           (void)isync_write(session, "MAW040B\r\n");
+           /* Configure tracking flags:
+            *  - Save frequency every 24 hours
+            *  - Align PPSOUT to PPSINT
+            *  - Track PPSREF
+            */
+           (void)isync_write(session, "MAW0513\r\n");
+           /* Configure tracking start flags:
+            *  - Tracking restart allowed
+            *  - Align to PPSREF
+            */
+           (void)isync_write(session, "MAW0606\r\n");
+           /* Configure tracking window:
+            *  - 4us
+            */
+           (void)isync_write(session, "MAW1304\r\n");
+           /* Configure alarm window:
+            *  - 4us
+            */
+           (void)isync_write(session, "MAW1404\r\n");
+           break;
+       case 2:
+           /* Configure pulse every d second:
+            *  - pulse every second
+            */
+           (void)isync_write(session, "MAW1701\r\n");
+           /* Configure pulse origin:
+            *  - zero offset
+            */
+           (void)isync_write(session, "MAW1800\r\n");
+           /* Configure pulse width:
+            *  - 600ms
+            */
+           (void)isync_write(session, "MAW1223C34600\r\n");
+           break;
+       case 3:
+           /* Configure GPS resource utilization:
+            *  - do not consider GPS messages
+            */
+           (void)isync_write(session, "MAW2200\r\n");
+           /* Restart sync */
+           (void)isync_write(session, "SY1\r\n");
+           /* Restart tracking */
+           (void)isync_write(session, "TR1\r\n");
+           break;
+       case 4:
+           /* Cancel BTx messages (if any) */
+           (void)isync_write(session, "BT0\r\n");
+           /* Configure messages coming out every second:
+            *  - Oscillator status ($PTNTA) at 750ms
+            */
+           (void)isync_write(session, "MAW0B00\r\n");
+           (void)isync_write(session, "MAW0C0A\r\n");
+           break;
+       case 5:
+           /* Enable GPS passthrough and force u-blox driver to
+            * select NMEA mode.
+            */
+           session->mode = 0;
+           session->drivers_identified = 0;
+           (void)isync_write(session, "@@@@GPS\r\n");
+           break;
+       case 6:
+           /* Trigger detection of underlying u-blox (if necessary) */
+           (void)ubx_write(session, 0x06, 0x00, NULL, 0);
+           break;
+       }
+    }
+}
+
+/* *INDENT-OFF* */
+const struct gps_type_t driver_isync = {
+    .type_name      = "iSync",         /* full name of type */
+    .packet_type    = NMEA_PACKET,     /* associated lexer packet type */
+    .flags          = DRIVER_STICKY,   /* remember this */
+    .trigger       = "$PTNTS,B,",      /* iSync status message */
+    .channels       = 50,              /* copied from driver_ubx */
+    .probe_detect   = isync_detect,    /* how to detect at startup time */
+    .get_packet     = generic_get,     /* how to get a packet */
+    .parse_packet   = generic_parse_input,     /* how to interpret a packet */
+    .init_query     = NULL,            /* non-perturbing initial query */
+    .event_hook     = isync_event_hook,        /* lifetime event handler */
+#ifdef RECONFIGURE_ENABLE
+    .speed_switcher = NULL,            /* no speed switcher */
+    .mode_switcher  = NULL,            /* no mode switcher */
+    .rate_switcher  = NULL,            /* no sample-rate switcher */
+    .min_cycle      = 1,               /* not relevant, no rate switch */
+#endif /* RECONFIGURE_ENABLE */
+#ifdef CONTROLSEND_ENABLE
+    .control_send   = nmea_write,      /* how to send control strings */
+#endif /* CONTROLSEND_ENABLE */
+#ifdef TIMEHINT_ENABLE
+    .time_offset     = NULL,           /* no method for NTP fudge factor */
+#endif /* TIMEHINT_ENABLE */
+};
+/* *INDENT-ON* */
+#endif /* ISYNC_ENABLE */
+
 #ifdef AIVDM_ENABLE
 /**************************************************************************
  *
@@ -1626,6 +1793,9 @@ static const struct gps_type_t *gpsd_driver_array[] = {
 #ifdef TSIP_ENABLE
     &driver_tsip,
 #endif /* TSIP_ENABLE */
+#ifdef ISYNC_ENABLE
+    &driver_isync,
+#endif /* ISYNC_ENABLE */
 #ifdef UBLOX_ENABLE
     &driver_ubx,
 #endif /* UBLOX_ENABLE */
-- 
2.3.8




reply via email to

[Prev in Thread] Current Thread [Next in Thread]