Allows for a GPS module to be connected to a serial port and exposes an easy to use API to get the GPS data.

Fork of MODGPS by Andy K

Revision:
7:049436bc2225
Parent:
6:64771e31464e
--- 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;                
+        }            
     }
 }