Sergey S / MODGPS

Fork of MODGPS by Andy K

Files at this revision

API Documentation at this revision

Comitter:
xanter
Date:
Sat Sep 29 20:31:31 2018 +0000
Parent:
6:64771e31464e
Commit message:
Fixed compiler errors/warnings; Removed hardcode for LPC17xx

Changed in this revision

GPS.cpp Show annotated file Show diff for this revision Revisions of this file
GPS.h Show annotated file Show diff for this revision Revisions of this file
GPS_Time.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/GPS.cpp	Thu Apr 21 14:06:17 2011 +0000
+++ b/GPS.cpp	Sat Sep 29 20:31:31 2018 +0000
@@ -22,81 +22,68 @@
 
 #include "GPS.h"
 
-GPS::GPS(PinName tx, PinName rx, const char *name) : Serial(tx, rx, name) 
+GPS::GPS(PinName tx, PinName rx, const char *name) 
+    : RawSerial(tx, rx)
+    , _ppsInUse(false)
+    , _pps(NULL)
+    , _second100(new Ticker)
+    , _lastByte(0)
+    , _gga(NULL)
+    , _rmc(NULL)
+    , _vtg(NULL)
+    , _ukn(NULL)
+    , _nmeaOnUart0(false)
 {
-    _nmeaOnUart0 = false;
-    
-    _lastByte = 0;
-    
-    _gga = (char *)NULL;
-    
-    _rmc = (char *)NULL;
-    
-    _vtg = (char *)NULL;
-    
-    switch(_uidx) {
-        case 1:   _base = LPC_UART1; break;
-        case 2:   _base = LPC_UART2; break;
-        case 3:   _base = LPC_UART3; break;
-        default : _base = NULL;      break;
-    }
-    
-    _pps = NULL;
-    _ppsInUse = false;
-    
-    if (_base != NULL) attach(this, &GPS::rx_irq);
-    
-    _second100 = new Ticker;
-    _second100->attach_us(this, &GPS::ticktock, GPS_TICKTOCK);
+    attach(callback(this, &GPS::rx_irq));
+    _second100->attach_us(callback(this, &GPS::ticktock), GPS_TICKTOCK);
 }
 
-void 
-GPS::ppsAttach(PinName irq, ppsEdgeType type) 
-{
-    if (_pps != NULL) delete(_pps);
+void GPS::ppsAttach(PinName irq, ppsEdgeType type) {
+    if (_pps != NULL) 
+        delete _pps;
     _pps = new InterruptIn(irq);
-    if (type == ppsRise) _pps->rise(this, &GPS::pps_irq);
-    else _pps->fall(this, &GPS::pps_irq);
+    if (type == ppsRise) 
+        _pps->rise(callback(this, &GPS::pps_irq));
+    else 
+        _pps->fall(callback(this, &GPS::pps_irq));
     _ppsInUse = true;     
 }
     
-void 
-GPS::ppsUnattach(void) 
-{
-    if (_pps != NULL) delete(_pps);
+void GPS::ppsUnattach() {
+    if (_pps != NULL) 
+        delete _pps;
     _ppsInUse = false;
 }
     
-double 
-GPS::latitude(void)  
-{
+double GPS::latitude() {
     double a, b;
-    do { a = thePlace.lat; b = thePlace.lat; }  while (a != b);
+    do { 
+        a = thePlace.lat; b = thePlace.lat; 
+    } while (a != b);
     return a; 
 }
 
-double 
-GPS::longitude(void) 
-{ 
+double GPS::longitude() { 
     double a, b;
-    do { a = thePlace.lon; b = thePlace.lon; } while (a != b);
+    do { 
+        a = thePlace.lon; b = thePlace.lon; 
+    } while (a != b);
     return a; 
 }
 
-double 
-GPS::altitude(void)  
-{ 
+double GPS::altitude() { 
     double a, b;
-    do { a = thePlace.alt; b = thePlace.alt; } while (a != b);
+    do { 
+        a = thePlace.alt; b = thePlace.alt; 
+    } while (a != b);
     return a; 
 }
 
-GPS_Geodetic *
-GPS::geodetic(GPS_Geodetic *q)
-{
+GPS_Geodetic * GPS::geodetic(GPS_Geodetic *q) {
     GPS_Geodetic a;
     
-    if (q == NULL) q = new GPS_Geodetic;
+    if (q == NULL) 
+        q = new GPS_Geodetic;
     
     do {
         memcpy(&a, &thePlace, sizeof(GPS_Geodetic));
@@ -107,12 +94,11 @@
     return q;
 }
 
-GPS_VTG *
-GPS::vtg(GPS_VTG *q)
-{
+GPS_VTG * GPS::vtg(GPS_VTG *q) {
     GPS_VTG a;
     
-    if (q == NULL) q = new GPS_VTG;
+    if (q == NULL) 
+        q = new GPS_VTG;
     
     do {
         memcpy(&a, &theVTG, sizeof(GPS_VTG));
@@ -123,11 +109,7 @@
     return q;
 }
 
-void
-GPS::ticktock(void)
-{
-    int i;
-    
+void GPS::ticktock() {   
     // Increment the time structure by 1/100th of a second.
     ++theTime; 
     
@@ -136,42 +118,47 @@
         char *s = buffer[active_buffer == 0 ? 1 : 0];
         if (!strncmp(s, "$GPRMC", 6)) {
             if (_rmc) {
-                for(i = 0; s[i] != '\n'; i++) {
+                int i;
+                for(i = 0; s[i] != '\n'; i++)
                     _rmc[i] = s[i];
-                }
                 _rmc[i++] = '\n'; _rmc[i] = '\0';
             }
             theTime.nmea_rmc(s);
-            cb_rmc.call();
-            if (!_ppsInUse) theTime.fractionalReset();
+            if (cb_rmc)
+                cb_rmc.call();
+            if (!_ppsInUse) 
+                theTime.fractionalReset();
         }
         else if (!strncmp(s, "$GPGGA", 6)) {
             if (_gga) {
-                for(int i = 0; s[i] != '\n'; i++) {
+                int i;
+                for(i = 0; s[i] != '\n'; i++)
                     _gga[i] = s[i];
-                }
                 _gga[i++] = '\n'; _gga[i] = '\0';
             }            
-            thePlace.nmea_gga(s);            
-            cb_gga.call();
+            thePlace.nmea_gga(s);       
+            if (cb_gga)     
+                cb_gga.call();
         }
         else if (!strncmp(s, "$GPVTG", 6)) {
             if (_vtg) {
-                for(int i = 0; s[i] != '\n'; i++) {
+                int i;
+                for(i = 0; s[i] != '\n'; i++)
                     _vtg[i] = s[i];
-                }
                 _vtg[i++] = '\n'; _vtg[i] = '\0';
             }
-            theVTG.nmea_vtg(s);            
-            cb_vtg.call();
+            theVTG.nmea_vtg(s);    
+            if (cb_vtg)        
+                cb_vtg.call();
         }
         else {
             if (_ukn) {
-                for(int i = 0; s[i] != '\n'; i++) {
+                int i;
+                for(i = 0; s[i] != '\n'; i++)
                     _ukn[i] = s[i];
-                }
                 _ukn[i++] = '\n'; _ukn[i] = '\0';
-                cb_ukn.call();
+                if (cb_ukn)
+                    cb_ukn.call();
             }
         }
         process_required = false;
@@ -186,51 +173,43 @@
     
 }
 
-void 
-GPS::pps_irq(void)
-{
+void GPS::pps_irq() {
     theTime.fractionalReset();
     theTime++; // Increment the time/date by one second. 
-    cb_pps.call();
+    if (cb_pps)
+        cb_pps.call();
 }
 
-void 
-GPS::rx_irq(void)
-{
-    uint32_t iir __attribute__((unused));
+void GPS::rx_irq() {
     char c;
-    
-    if (_base) {
-        iir = (uint32_t)*((char *)_base + GPS_IIR); 
-        while((int)(*((char *)_base + GPS_LSR) & 0x1)) {
-            c = (char)(*((char *)_base + GPS_RBR) & 0xFF);             
-            
-            // strtok workaround. 
-            // Found that ,, together (which some NMEA sentences
-            // contain for a null/empty field) confuses strtok()
-            // function. Solution:- Push a "zero" into the string 
-            // for missing/empty fields.
-            if (c == ',' && _lastByte == ',') {
-                buffer[active_buffer][rx_buffer_in] = '0';
-                if (++rx_buffer_in >= GPS_BUFFER_LEN) rx_buffer_in = 0;
-            }
-            
-            // Debugging/dumping data. 
-            if (_nmeaOnUart0) LPC_UART0->RBR = c; 
-            
-            // Put the byte into the string.
-            buffer[active_buffer][rx_buffer_in] = c;
+    while(readable()) {
+        c = static_cast<char>(getc());             
+        
+        // strtok workaround. 
+        // Found that ,, together (which some NMEA sentences
+        // contain for a null/empty field) confuses strtok()
+        // function. Solution:- Push a "zero" into the string 
+        // for missing/empty fields.
+        if (c == ',' && _lastByte == ',') {
+            buffer[active_buffer][rx_buffer_in] = '0';
             if (++rx_buffer_in >= GPS_BUFFER_LEN) rx_buffer_in = 0;
-            
-            // Save for next time an irq occurs. See strtok() above.
-            _lastByte = c;
-            
-            // If end of NMEA sentence flag for processing.
-            if (c == '\n') {
-                active_buffer = active_buffer == 0 ? 1 : 0;
-                process_required = true;
-                rx_buffer_in = 0;                
-            }            
         }
+        
+        // Debugging/dumping data. 
+//        if (_nmeaOnUart0) LPC_UART0->RBR = c; 
+        
+        // Put the byte into the string.
+        buffer[active_buffer][rx_buffer_in] = c;
+        if (++rx_buffer_in >= GPS_BUFFER_LEN) rx_buffer_in = 0;
+        
+        // Save for next time an irq occurs. See strtok() above.
+        _lastByte = c;
+        
+        // If end of NMEA sentence flag for processing.
+        if (c == '\n') {
+            active_buffer = active_buffer == 0 ? 1 : 0;
+            process_required = true;
+            rx_buffer_in = 0;                
+        }            
     }
 }      
--- a/GPS.h	Thu Apr 21 14:06:17 2011 +0000
+++ b/GPS.h	Sat Sep 29 20:31:31 2018 +0000
@@ -1,16 +1,16 @@
 /*
     Copyright (c) 2010 Andy Kirkham
- 
+
     Permission is hereby granted, free of charge, to any person obtaining a copy
     of this software and associated documentation files (the "Software"), to deal
     in the Software without restriction, including without limitation the rights
     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     copies of the Software, and to permit persons to whom the Software is
     furnished to do so, subject to the following conditions:
- 
+
     The above copyright notice and this permission notice shall be included in
     all copies or substantial portions of the Software.
- 
+
     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -53,7 +53,7 @@
  * @see http://mbed.org/cookbook/MODGPS
  * @see example1.cpp
  * @see example2.cpp
- * @see API 
+ * @see API
  *
  * @image html /media/uploads/AjK/gps_interfaces.png "Wiring up the GPS module"
  *
@@ -64,7 +64,7 @@
  *
  * DigitalOut led1(LED1);
  * Serial pc(USBTX, USBRX);
- * GPS gps(NC, p10); 
+ * GPS gps(NC, p10);
  *
  * int main() {
  *     GPS_Time t;
@@ -86,35 +86,27 @@
  *       wait(1);
  *     }
  *
- *     pc.printf("Lat = %.4f Lon = %.4f Alt = %.1fkm\r\n", 
+ *     pc.printf("Lat = %.4f Lon = %.4f Alt = %.1fkm\r\n",
  *         gps.latitude(), gps.longitude, gps.altitude());
  *
  *     // Make the LED go steady to indicate we have finished.
  *     led1 = 1;
- * 
+ *
  *     while(1) {}
  * }
  * @endcode
  */
 
-class GPS : Serial {
+class GPS : RawSerial
+{
 public:
-    
+
     //! The PPS edge type to interrupt on.
-    enum ppsEdgeType { 
+    enum ppsEdgeType {
         ppsRise = 0,    /*!< Use the rising edge (default). */
         ppsFall         /*!< Use the falling edge. */
     };
-    
-    //! A copy of the Serial parity enum
-    enum Parity {
-        None = 0
-        , Odd
-        , Even
-        , Forced1   
-        , Forced0
-    };
-    
+
     //! GPS constructor.
     /**
      * The GPS constructor is used to initialise the GPS object.
@@ -131,7 +123,7 @@
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     if (gps.isTimeValid()) {
      *         // Time is valid :)
@@ -139,23 +131,25 @@
      *     else {
      *         // Doh, time is not valid :(
      *     )
-     *     
+     *
      * @endcode
      *
      * @ingroup API
      * @return bool true if valid, false otherwise
      */
-    bool isTimeValid(void) { return theTime.status == 'V' ? false : true; }
-    
+    bool isTimeValid(void) {
+        return theTime.status == 'V' ? false : true;
+    }
+
     //! Is the positional fix reported by the GPS valid.
     /**
      * Method used to check the validity of the positional data. This method
-     * returns the GGA field, 0 is "bad, 1 is "ok", etc. See the NMEA GGA 
+     * returns the GGA field, 0 is "bad, 1 is "ok", etc. See the NMEA GGA
      * description for more details.
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     if (gps.getGPSquality() == 0) {
      *         // The location fix is no good/not accurate :(
@@ -163,92 +157,96 @@
      *     else {
      *         // All good, can use last fix data.
      *     )
-     *     
+     *
      * @endcode
      *
      * @ingroup API
      * @return int 0 on no fix, 1... (see NMEA GGA for more details).
      */
-    int getGPSquality(void) { return thePlace.getGPSquality(); }
-    
+    int getGPSquality(void) {
+        return thePlace.getGPSquality();
+    }
+
     //! How many satellites were used in the last fix.
     /**
      * Method returns the number of GPS satellites used on the last fix.
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     int sats = gps.numOfSats();
-     *     
+     *
      * @endcode
      *
      * @ingroup API
      * @return int The number of satellites.
      */
-    int numOfSats(void) { return thePlace.numOfSats(); }
-    
+    int numOfSats(void) {
+        return thePlace.numOfSats();
+    }
+
     //! What was the last reported latitude (in degrees)
     /**
      * Method returns a double in degrees, positive being North, negative being South.
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     double latitude = gps.latitude();
-     *     
+     *
      * @endcode
      *
      * @ingroup API
      * @return double Degrees
      */
     double latitude(void);
-    
+
     //! What was the last reported longitude (in degrees)
     /**
      * Method returns a double in degrees, positive being East, negative being West.
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     double logitude = gps.logitude();
-     *     
+     *
      * @endcode
      *
      * @ingroup API
      * @return double Degrees
      */
     double longitude(void);
-    
+
     //! What was the last reported altitude (in kilometers)
     /**
      * Method returns a double in kilometers.
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     double altitude = gps.altitude();
-     *     
+     *
      * @endcode
      *
      * @ingroup API
      * @return double Kilometers
      */
     double altitude(void);
-    
+
     //! What was the last reported altitude/height (in kilometers)
     /**
      * @see altitude()
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     double height = gps.height();
-     *     
+     *
      * @endcode
      *
      * Note, this is identical to altitude()
@@ -257,8 +255,10 @@
      * @ingroup API
      * @return double Kilometers
      */
-    double height(void) { return altitude(); }
-    
+    double height(void) {
+        return altitude();
+    }
+
     //! Get all vector parameters together.
     /**
      * Pass a pointer to a GPS_VTG object and the current
@@ -266,7 +266,7 @@
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     // Then get the data...
      *     GPS_VTG p;
@@ -283,21 +283,21 @@
      * @return GPS_VTG * The pointer passed in.
      */
     GPS_VTG *vtg(GPS_VTG *g);
-    
+
     //! Get all vector parameters together.
     /**
      * Get all the vector data at once. For example:-
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     // Then get the data...
      *     GPS_VTG *p = gps.vtg();
      *     printf("Speed (knots)  = %.4f", p->velocity_knots);
      *     printf("Speed (kps)    = %.4f", p->velocity_kps);
      *     printf("Track (true)  = %.4f", p->track_true);
-     *     printf("Track (mag)    = %.4f", p->track_mag);     
+     *     printf("Track (mag)    = %.4f", p->track_mag);
      *     delete(p); // then remember to delete the object to prevent memory leaks.
      *
      * @endcode
@@ -305,8 +305,10 @@
      * @ingroup API
      * @return GPS_Geodetic * A pointer to the data.
      */
-    GPS_VTG *vtg(void) { return vtg(NULL); }
-    
+    GPS_VTG *vtg(void) {
+        return vtg(NULL);
+    }
+
     //! Get all three geodetic parameters together.
     /**
      * Pass a pointer to a GPS_Geodetic object and the current
@@ -314,7 +316,7 @@
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     // Then get the data...
      *     GPS_Geodetic p;
@@ -330,14 +332,14 @@
      * @return GPS_Geodetic * The pointer passed in.
      */
     GPS_Geodetic *geodetic(GPS_Geodetic *g);
-    
+
     //! Get all three geodetic parameters together.
     /**
      * Get all the geodetic data at once. For example:-
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     // Then get the data...
      *     GPS_Geodetic *p = gps.geodetic();
@@ -349,8 +351,10 @@
      * @ingroup API
      * @return GPS_Geodetic * A pointer to the data.
      */
-    GPS_Geodetic *geodetic(void) { return geodetic(NULL); }
-    
+    GPS_Geodetic *geodetic(void) {
+        return geodetic(NULL);
+    }
+
     //! Take a snap shot of the current time.
     /**
      * Pass a pointer to a GPS_Time object to get a copy of the current
@@ -358,7 +362,7 @@
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     // Then get the data...
      *     GPS_Time t;
@@ -371,8 +375,10 @@
      * @param n A GPS_Time * pointer to an existing GPS_Time object.
      * @return GPS_Time * The pointer passed in.
      */
-    GPS_Time * timeNow(GPS_Time *n) { return theTime.timeNow(n); }
-    
+    GPS_Time * timeNow(GPS_Time *n) {
+        return theTime.timeNow(n);
+    }
+
     //! Take a snap shot of the current time.
     /**
      * Pass a pointer to a GPS_Time object to get a copy of the current
@@ -380,7 +386,7 @@
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     // Then get the data...
      *     GPS_Time *t = gps.timeNow();
@@ -392,13 +398,16 @@
      * @ingroup API
      * @return GPS_Time * The pointer passed in.
      */
-    GPS_Time * timeNow(void) { GPS_Time *n = new GPS_Time; return theTime.timeNow(n); }
-    
+    GPS_Time * timeNow(void) {
+        GPS_Time *n = new GPS_Time;
+        return theTime.timeNow(n);
+    }
+
     //! Return the curent day.
     /**
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     // Then get the Julain Day Number.
      *     double julianDayNumber = gps.julianDayNumber();
@@ -408,13 +417,15 @@
      * @ingroup API
      * @return double The Julian Date as a double.
      */
-    double julianDayNumber(void) { return theTime.julian_day_number(); } 
-    
+    double julianDayNumber(void) {
+        return theTime.julian_day_number();
+    }
+
     //! Return the curent date/time as a Julian date
     /**
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
      *     // Then get the Julian Date.
      *     double julianDate = gps.julianDate();
@@ -424,13 +435,15 @@
      * @ingroup API
      * @return double The Julian Date as a double.
      */
-    double julianDate(void) { return theTime.julian_date(); }
+    double julianDate(void) {
+        return theTime.julian_date();
+    }
 
     //! Get the current sidereal degree angle.
     /**
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     double sidereal = gps.siderealDegrees();
      *
      * @endcode
@@ -438,13 +451,15 @@
      * @ingroup API
      * @return double Sidereal degree angle..
      */
-    double siderealDegrees(void) { return theTime.siderealDegrees(&theTime, longitude()); }
-    
+    double siderealDegrees(void) {
+        return theTime.siderealDegrees(&theTime, longitude());
+    }
+
     //! Get the current sidereal hour angle.
     /**
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     double sidereal = gps.siderealHA();
      *
      * @endcode
@@ -452,8 +467,10 @@
      * @ingroup API
      * @return double Sidereal degree angle..
      */
-    double siderealHA(void) { return theTime.siderealHA(&theTime, longitude()); }
-    
+    double siderealHA(void) {
+        return theTime.siderealHA(&theTime, longitude());
+    }
+
     //! Optionally, connect a 1PPS single to an Mbed pin.
     /**
      * Optional: If the GPS unit has a 1PPS output, use this to
@@ -462,9 +479,9 @@
      *
      * @code
      *     // Assuming we have a GPS object previously created...
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *
-     *     gps.ppsAttach(p29); // default to GPS::ppsRise, rising edge. 
+     *     gps.ppsAttach(p29); // default to GPS::ppsRise, rising edge.
      *
      *     // Or...
      *     gps.ppsAttach(p29, GPS::ppsRise); // The default.
@@ -484,37 +501,34 @@
      * @param type The type of edge, MAX7456::ppsRise OR MAX7456::ppsFall
      */
     void ppsAttach(PinName irq, ppsEdgeType type = ppsRise);
-    
+
     //! Remove any 1PPS signal previously attached.
     void ppsUnattach(void);
-    
+
     //! GPS serial receive interrupt handler.
-    void rx_irq(void);    
-    
+    void rx_irq(void);
+
     //! GPS pps interrupt handler.
     void pps_irq(void);
-    
-    //! A pointer to the UART peripheral base address being used.
-    void *_base;
-    
+
     //! The RX serial buffer.
     char buffer[2][GPS_BUFFER_LEN];
-    
+
     //! The current "active" buffer, i.e. the buffer the ISR is writing to.
     int  active_buffer;
-    
+
     //! The active buffer "in" pointer.
     int  rx_buffer_in;
-    
+
     //! Boolean flag set when the "passive" buffer is full and needs processing.
     bool process_required;
-    
+
     //! 10ms Ticker callback.
     void ticktock(void);
-    
+
     //! Attach a user object/method callback function to the PPS signal
     /**
-     * Attach a user callback object/method to call when the 1PPS signal activates. 
+     * Attach a user callback object/method to call when the 1PPS signal activates.
      *
      * @code
      *     class FOO {
@@ -522,11 +536,11 @@
      *         void myCallback(void);
      *     };
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_pps(foo, &FOO::myCallback);
-     * 
+     *
      * @endcode
      *
      * @ingroup API
@@ -534,33 +548,37 @@
      * @param mptr pointer to the member function to be called
      */
     template<typename T>
-    void attach_pps(T* tptr, void (T::*mptr)(void)) { cb_pps.attach(tptr, mptr); }
-    
+    void attach_pps(T* tptr, void (T::*mptr)(void)) {
+        cb_pps.attach(tptr, mptr);
+    }
+
     //! Attach a user callback function to the PPS signal
     /**
-     * Attach a user callback function pointer to call when the 1PPS signal activates. 
+     * Attach a user callback function pointer to call when the 1PPS signal activates.
      *
      * @code
      *     void myCallback(void) { ... }
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_pps(&myCallback);
-     * 
+     *
      * @endcode
      *
      * @ingroup API
      * @param fptr Callback function pointer
      */
-    void attach_pps(void (*fptr)(void)) { cb_pps.attach(fptr); } 
-    
+    void attach_pps(const Callback<void()> & func) {
+        cb_pps = func;
+    }
+
     //! A callback object for the 1PPS user API.
-    FunctionPointer cb_pps;
-    
+    Callback<void()> cb_pps;
+
     //! Attach a user callback function to the NMEA RMC message processed signal.
     /**
-     * Attach a user callback object/method to call when an NMEA RMC packet has been processed. 
+     * Attach a user callback object/method to call when an NMEA RMC packet has been processed.
      *
      * @code
      *     class FOO {
@@ -568,45 +586,49 @@
      *         void myCallback(void);
      *     };
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_rmc(foo, &FOO::myCallback);
-     * 
+     *
      * @endcode
      *
-     * @ingroup API 
+     * @ingroup API
      * @param tptr pointer to the object to call the member function on
      * @param mptr pointer to the member function to be called
      */
     template<typename T>
-    void attach_rmc(T* tptr, void (T::*mptr)(void)) { cb_rmc.attach(tptr, mptr); }
-    
+    void attach_rmc(T* tptr, void (T::*mptr)(void)) {
+        cb_rmc.attach(tptr, mptr);
+    }
+
     //! Attach a user callback function to the NMEA RMC message processed signal.
     /**
-     * Attach a user callback function pointer to call when an NMEA RMC packet has been processed. 
+     * Attach a user callback function pointer to call when an NMEA RMC packet has been processed.
      *
      * @code
      *     void myCallback(void) { ... }
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_rmc(&myCallback);
-     * 
+     *
      * @endcode
      *
-     * @ingroup API 
+     * @ingroup API
      * @param fptr Callback function pointer.
      */
-    void attach_rmc(void (*fptr)(void)) { cb_rmc.attach(fptr); } 
-    
+    void attach_rmc(const Callback<void()> & func) {
+        cb_rmc = func;
+    }
+
     //! A callback object for the NMEA RMS message processed signal user API.
-    FunctionPointer cb_rmc;
-    
+    Callback<void()> cb_rmc;
+
     //! Attach a user callback function to the NMEA GGA message processed signal.
     /**
-     * Attach a user callback object/method to call when an NMEA GGA packet has been processed. 
+     * Attach a user callback object/method to call when an NMEA GGA packet has been processed.
      *
      * @code
      *     class FOO {
@@ -614,46 +636,50 @@
      *         void myCallback(void);
      *     };
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_gga(foo, &FOO::myCallback);
-     * 
+     *
      * @endcode
      *
-     * @ingroup API 
+     * @ingroup API
      * @param tptr pointer to the object to call the member function on
      * @param mptr pointer to the member function to be called
      */
     template<typename T>
-    void attach_gga(T* tptr, void (T::*mptr)(void)) { cb_gga.attach(tptr, mptr); }
-    
+    void attach_gga(T* tptr, void (T::*mptr)(void)) {
+        cb_gga.attach(tptr, mptr);
+    }
+
     //! Attach a user callback function to the NMEA GGA message processed signal.
     /**
-     * Attach a user callback function pointer to call when an NMEA GGA packet has been processed. 
+     * Attach a user callback function pointer to call when an NMEA GGA packet has been processed.
      *
      * @code
      *     void myCallback(void) { ... }
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_gga(&myCallback);
-     * 
+     *
      * @endcode
      *
-     * @ingroup API 
+     * @ingroup API
      * @param fptr Callback function pointer.
      */
-    void attach_gga(void (*fptr)(void)) { cb_gga.attach(fptr); } 
-    
+    void attach_gga(const Callback<void()> & func) {
+        cb_gga = func;
+    }
+
     //! A callback object for the NMEA GGA message processed signal user API.
-    FunctionPointer cb_gga;
+    Callback<void()> cb_gga;
 
 
     //! Attach a user callback function to the NMEA VTG message processed signal.
     /**
-     * Attach a user callback object/method to call when an NMEA VTG packet has been processed. 
+     * Attach a user callback object/method to call when an NMEA VTG packet has been processed.
      *
      * @code
      *     class FOO {
@@ -661,45 +687,49 @@
      *         void myCallback(void);
      *     };
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_vtg(foo, &FOO::myCallback);
-     * 
+     *
      * @endcode
      *
-     * @ingroup API 
+     * @ingroup API
      * @param tptr pointer to the object to call the member function on
      * @param mptr pointer to the member function to be called
      */
     template<typename T>
-    void attach_vtg(T* tptr, void (T::*mptr)(void)) { cb_vtg.attach(tptr, mptr); }
-    
+    void attach_vtg(T* tptr, void (T::*mptr)(void)) {
+        cb_vtg.attach(tptr, mptr);
+    }
+
     //! Attach a user callback function to the NMEA VTG message processed signal.
     /**
-     * Attach a user callback function pointer to call when an NMEA VTG packet has been processed. 
+     * Attach a user callback function pointer to call when an NMEA VTG packet has been processed.
      *
      * @code
      *     void myCallback(void) { ... }
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_vtg(&myCallback);
-     * 
+     *
      * @endcode
      *
-     * @ingroup API 
+     * @ingroup API
      * @param fptr Callback function pointer.
      */
-    void attach_vtg(void (*fptr)(void)) { cb_vtg.attach(fptr); } 
-    
+    void attach_vtg(const Callback<void()> & func) {
+        cb_vtg = func;
+    }
+
     //! A callback object for the NMEA RMS message processed signal user API.
-    FunctionPointer cb_vtg;
-    
+    Callback<void()> cb_vtg;
+
     //! Attach a user callback function to the unknown NMEA message.
     /**
-     * Attach a user callback object/method to call when an unknown NMEA packet. 
+     * Attach a user callback object/method to call when an unknown NMEA packet.
      *
      * @code
      *     class FOO {
@@ -707,142 +737,164 @@
      *         void myCallback(void);
      *     };
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_ukn(foo, &FOO::myCallback);
-     * 
+     *
      * @endcode
      *
-     * @ingroup API 
+     * @ingroup API
      * @param tptr pointer to the object to call the member function on
      * @param mptr pointer to the member function to be called
      */
     template<typename T>
-    void attach_ukn(T* tptr, void (T::*mptr)(void)) { cb_ukn.attach(tptr, mptr); }
-    
+    void attach_ukn(T* tptr, void (T::*mptr)(void)) {
+        cb_ukn.attach(tptr, mptr);
+    }
+
     //! Attach a user callback function to the unknown NMEA message.
     /**
-     * Attach a user callback function pointer to call when an unknown NMEA. 
+     * Attach a user callback function pointer to call when an unknown NMEA.
      *
      * @code
      *     void myCallback(void) { ... }
      *
-     *     GPS gps(NC, p9); 
+     *     GPS gps(NC, p9);
      *     Foo foo;
      *
      *     gps.attach_ukn(&myCallback);
-     * 
+     *
      * @endcode
      *
-     * @ingroup API 
+     * @ingroup API
      * @param fptr Callback function pointer.
      */
-    void attach_ukn(void (*fptr)(void)) { cb_ukn.attach(fptr); } 
-    
+    void attach_ukn(const Callback<void()> & func) {
+        cb_ukn = func;
+    }
+
     //! A callback object for the NMEA RMS message processed signal user API.
-    FunctionPointer cb_ukn;
-    
+    Callback<void()> cb_ukn;
+
     /**
      * Set's the GGA string memory pointer.
      * @param s char pointer ti string.
      * @return char s passed in.
      */
-    char * setGga(char *s) { _gga = s; return s; }
-    
+    char * setGga(char *s) {
+        _gga = s;
+        return s;
+    }
+
     /**
      * Set's the RMC string memory pointer.
      * @param s char pointer ti string.
      * @return char s passed in.
      */
-    char * setRmc(char *s) { _rmc = s; return s; };
-    
+    char * setRmc(char *s) {
+        _rmc = s;
+        return s;
+    };
+
     /**
      * Set's the VTG string memory pointer.
      * @param s char pointer ti string.
      * @return char s passed in.
      */
-    char * setVtg(char *s) { _vtg = s; return s; };
-    
+    char * setVtg(char *s) {
+        _vtg = s;
+        return s;
+    };
+
     /**
      * Set's the UKN string memory pointer.
      * @param s char pointer ti string.
      * @return char s passed in.
      */
-    char * setUkn(char *s) { _ukn = s; return s; };
-    
+    char * setUkn(char *s) {
+        _ukn = s;
+        return s;
+    };
+
     //! Set the baud rate the GPS module is using.
-    /** 
+    /**
      * Set the baud rate of the serial port
-     * 
+     *
      * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.baud
      *
-     * @ingroup API 
+     * @ingroup API
      * @param baudrate The baudrate to set.
      */
-    void baud(int baudrate) { Serial::baud(baudrate); }
-    
-   //! Set the serial port format the GPS module is using. 
-   /**
-    * Set the transmission format used by the Serial port
-    *
-    * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format
-    *
-    * @ingroup API 
-    * @param bits - The number of bits in a word (5-8; default = 8)
-    * @param parity - The parity used (GPS::None, GPS::Odd, GPS::Even, GPS::Forced1, GPS::Forced0; default = GPS::None)
-    * @param stop_bits - The number of stop bits (1 or 2; default = 1)
-    */
-    void format(int bits, Parity parity, int stop_bits) { Serial::format(bits, (Serial::Parity)parity, stop_bits); }
-    
-   //! Send incoming GPS bytes to Uart0
-   /**
-    * Send incoming GPS bytes to Uart0
-    *
-    * This can be useful for printing out the bytes from the GPS onto
-    * a the common debug port Uart0. Note, Uart0 should have been setup
-    * and initialised before switching this on. Also, realistically,
-    * you should ensure Uart0 has a higher baud rate than that being
-    * used by the GPS. Sending of bytes to Uart0 is "raw" and should
-    * only be used to initially gather data and should NOT be used as
-    * part of the application design. If you need to forward on the 
-    * data you should come up with a proper strategy.
-    *
-    * @ingroup API 
-    * @param b - True to send to Uart0, false otherwise
-    */
-    void NmeaOnUart0(bool b) { _nmeaOnUart0 = b; }
-        
+    void baud(int baudrate) {
+        RawSerial::baud(baudrate);
+    }
+
+    //! Set the serial port format the GPS module is using.
+    /**
+     * Set the transmission format used by the Serial port
+     *
+     * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format
+     *
+     * @ingroup API
+     * @param bits - The number of bits in a word (5-8; default = 8)
+     * @param parity - The parity used (GPS::None, GPS::Odd, GPS::Even, GPS::Forced1, GPS::Forced0; default = GPS::None)
+     * @param stop_bits - The number of stop bits (1 or 2; default = 1)
+     */
+    void format(int bits, Parity parity, int stop_bits) {
+        RawSerial::format(bits, parity, stop_bits);
+    }
+
+    //! Send incoming GPS bytes to Uart0
+    /**
+     * Send incoming GPS bytes to Uart0
+     *
+     * This can be useful for printing out the bytes from the GPS onto
+     * a the common debug port Uart0. Note, Uart0 should have been setup
+     * and initialised before switching this on. Also, realistically,
+     * you should ensure Uart0 has a higher baud rate than that being
+     * used by the GPS. Sending of bytes to Uart0 is "raw" and should
+     * only be used to initially gather data and should NOT be used as
+     * part of the application design. If you need to forward on the
+     * data you should come up with a proper strategy.
+     *
+     * @ingroup API
+     * @param b - True to send to Uart0, false otherwise
+     */
+    void NmeaOnUart0(bool b) {
+        _nmeaOnUart0 = b;
+    }
+
 protected:
 
     //! Flag set true when a GPS PPS has been attached to a pin.
-    bool         _ppsInUse;
-    
+    bool _ppsInUse;
+
     //! An InterruptIn object to "trigger" on the PPS edge.
-    InterruptIn *_pps;
-    
+    InterruptIn * _pps;
+
     //! A Ticker object called every 10ms.
-    Ticker      *_second100;
-    
+    Ticker * _second100;
+
     //! A GPS_Time object used to hold the last parsed time/date data.
-    GPS_Time     theTime;
-    
+    GPS_Time theTime;
+
     //! A GPS_Geodetic object used to hold the last parsed positional data.
     GPS_Geodetic thePlace;
-    
+
     //! A GPS_VTG object used to hold vector data.
-    GPS_VTG      theVTG; 
-    
+    GPS_VTG theVTG;
+
     //! Used to record the previous byte received.
     char _lastByte;
-    
-    char *_gga;
-    char *_rmc;
-    char *_vtg;
-    char *_ukn;
-    
+
+    char * _gga;
+    char * _rmc;
+    char * _vtg;
+    char * _ukn;
+
     //! Used for debugging.
-    bool _nmeaOnUart0;      
+    bool _nmeaOnUart0;
 };
 
 #endif
--- a/GPS_Time.cpp	Thu Apr 21 14:06:17 2011 +0000
+++ b/GPS_Time.cpp	Sat Sep 29 20:31:31 2018 +0000
@@ -22,8 +22,7 @@
 
 #include "GPS_Time.h"
 
-GPS_Time::GPS_Time() 
-{
+GPS_Time::GPS_Time() {
     year = 2000;
     month = 1;
     day = 1;
@@ -39,9 +38,7 @@
     magvar = 0;
 }
 
-time_t
-GPS_Time::to_C_tm(bool set) 
-{
+time_t GPS_Time::to_C_tm(bool set) {
     GPS_Time t;
     tm       ct;
     time_t   q;
@@ -62,10 +59,9 @@
     return q;
 }
 
-GPS_Time *
-GPS_Time::timeNow(GPS_Time *n)
-{
-    if (n == NULL) n = new GPS_Time;
+GPS_Time * GPS_Time::timeNow(GPS_Time *n) {
+    if (n == NULL) 
+        n = new GPS_Time;
     
     do {
         memcpy(n, this, sizeof(GPS_Time));
@@ -74,9 +70,7 @@
     return n;    
 }
 
-void
-GPS_Time::operator++()
-{
+void GPS_Time::operator++() {
     hundreths++;
     if (hundreths == 10) {
         hundreths = 0;
@@ -87,9 +81,7 @@
     }
 }
 
-void
-GPS_Time::operator++(int)
-{
+void GPS_Time::operator++(int) {
     const int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
     bool dateInc = false;
     
@@ -126,9 +118,7 @@
 }
 
 // $GPRMC,112709.735,A,5611.5340,N,00302.0306,W,000.0,307.0,150411,,,A*70
-void 
-GPS_Time::nmea_rmc(char *s)
-{
+void GPS_Time::nmea_rmc(char *s) {
     char *token;
     int  token_counter = 0;
     char *time   = (char *)NULL;
@@ -169,14 +159,12 @@
     }    
 }
 
-double 
-GPS_Time::julian_day_number(GPS_Time *t) {
+double GPS_Time::julian_day_number(GPS_Time *t) {
     double wikipedia_jdn = (double)(1461 * ((int)t->year + 4800 + ((int)t->month - 14) / 12)) / 4 + (367 * ((int)t->month - 2 - 12 * (((int)t->month - 14) / 12))) / 12 - (3 * (((int)t->year + 4900 + ((int)t->month - 14) / 12 ) / 100)) / 4 + (int)t->day - 32075;    
     return wikipedia_jdn;
 }
 
-double 
-GPS_Time::julian_date(GPS_Time *t) {
+double GPS_Time::julian_date(GPS_Time *t) {
     double hour, minute, second, jd;
     hour   = (double)t->hour;
     minute = (double)t->minute;
@@ -190,8 +178,7 @@
     return jd;
 }
 
-double 
-GPS_Time::siderealDegrees(double jd, double longitude) {
+double GPS_Time::siderealDegrees(double jd, double longitude) {
     double sidereal, gmst, lmst;
     double T  = jd - 2451545.0;
     double T1 = T / 36525.0;
@@ -210,20 +197,17 @@
     return lmst;
 }
 
-double 
-GPS_Time::siderealDegrees(GPS_Time *t, double longitude) {
+double GPS_Time::siderealDegrees(GPS_Time *t, double longitude) {
     if (t == NULL) t = new GPS_Time;
     return siderealDegrees(julian_date(t), longitude);
 }
 
-double 
-GPS_Time::siderealHA(double jd, double longitude) {
+double GPS_Time::siderealHA(double jd, double longitude) {
     double lmst = siderealDegrees(jd, longitude);
     return lmst / 360.0 * 24.0;
 }
 
-double 
-GPS_Time::siderealHA(GPS_Time *t, double longitude) {
+double GPS_Time::siderealHA(GPS_Time *t, double longitude) {
     double lmst = siderealDegrees(t, longitude);
     return lmst / 360.0 * 24.0;
 }