Allows for a GPS module to be connected to a serial port and exposes an easy to use API to get the GPS data. New feature, added Mbed/LPC17xx RTC synchronisation

Dependents:   SatGPS AntiTheftGPS FLIGHT_CONTROL_AND_COMMUNICATIONS_SYSTEM GPS-Lora ... more

Files at this revision

API Documentation at this revision

Comitter:
AjK
Date:
Sat Apr 16 09:37:33 2011 +0000
Parent:
2:8aa059e7d8b1
Child:
4:1e3a53f150aa
Commit message:
1.13 See ChangeLog.c

Changed in this revision

ChangeLog.c Show annotated file Show diff for this revision Revisions of this file
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_VTG.cpp Show annotated file Show diff for this revision Revisions of this file
GPS_VTG.h Show annotated file Show diff for this revision Revisions of this file
info.h Show annotated file Show diff for this revision Revisions of this file
--- a/ChangeLog.c	Fri Apr 15 12:23:52 2011 +0000
+++ b/ChangeLog.c	Sat Apr 16 09:37:33 2011 +0000
@@ -64,5 +64,11 @@
 
     * Added VTG sentence (vectors speed and direction)
       See example3.cpp
-                                 
+
+1.13 - 16/04/2011
+
+    * Found that concat commas in NMEA sentences (indicating an empty field)
+      caused strtok() to return pointers in incorrect positions. 
+    * Found copying geodetic and vtg data structs to temp buffers actually
+      didn't work properly.                              
 */
--- a/GPS.cpp	Fri Apr 15 12:23:52 2011 +0000
+++ b/GPS.cpp	Sat Apr 16 09:37:33 2011 +0000
@@ -24,6 +24,10 @@
 
 GPS::GPS(PinName tx, PinName rx, const char *name) : Serial(tx, rx, name) 
 {
+    _nmeaOnUart0 = false;
+    
+    _lastByte = 0;
+    
     switch(_uidx) {
         case 1:   _base = LPC_UART1; break;
         case 2:   _base = LPC_UART2; break;
@@ -84,15 +88,15 @@
 GPS_Geodetic *
 GPS::geodetic(GPS_Geodetic *q)
 {
-    GPS_Geodetic a, b;
+    GPS_Geodetic a;
     
     if (q == NULL) q = new GPS_Geodetic;
     
     do {
         memcpy(&a, &thePlace, sizeof(GPS_Geodetic));
-        memcpy(&b, &thePlace, sizeof(GPS_Geodetic));
+        memcpy(q,  &thePlace, sizeof(GPS_Geodetic));
     }
-    while (memcmp(&a, &b, sizeof(GPS_Geodetic)) != 0);
+    while (memcmp(&a, q, sizeof(GPS_Geodetic)) != 0);
     
     return q;
 }
@@ -100,15 +104,15 @@
 GPS_VTG *
 GPS::vtg(GPS_VTG *q)
 {
-    GPS_VTG a, b;
+    GPS_VTG a;
     
     if (q == NULL) q = new GPS_VTG;
     
     do {
         memcpy(&a, &theVTG, sizeof(GPS_VTG));
-        memcpy(&b, &theVTG, sizeof(GPS_VTG));
+        memcpy(q,  &theVTG, sizeof(GPS_VTG));
     }
-    while (memcmp(&a, &b, sizeof(GPS_VTG)) != 0);
+    while (memcmp(&a, q, sizeof(GPS_VTG)) != 0);
     
     return q;
 }
@@ -156,15 +160,34 @@
     if (_base) {
         iir = (uint32_t)*((char *)_base + GPS_IIR); 
         while((int)(*((char *)_base + GPS_LSR) & 0x1)) {
-            c = (char)(*((char *)_base + GPS_RBR) & 0xFF); 
-            // debugging LPC_UART0->RBR = c;
-            buffer[active_buffer][rx_buffer_in++] = c;
-            rx_buffer_in &= (GPS_BUFFER_LEN - 1);
+            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;
+            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	Fri Apr 15 12:23:52 2011 +0000
+++ b/GPS.h	Sat Apr 16 09:37:33 2011 +0000
@@ -696,6 +696,7 @@
     
     //! A callback object for the NMEA RMS message processed signal user API.
     FunctionPointer cb_vtg;
+    
     //! Set the baud rate the GPS module is using.
     /** 
      * Set the baud rate of the serial port
@@ -707,7 +708,7 @@
      */
     void baud(int baudrate) { Serial::baud(baudrate); }
     
-    //! Set the serial port format the GPS module is using. 
+   //! Set the serial port format the GPS module is using. 
    /**
     * Set the transmission format used by the Serial port
     *
@@ -720,6 +721,24 @@
     */
     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; }
+        
 protected:
 
     //! Flag set true when a GPS PPS has been attached to a pin.
@@ -738,7 +757,13 @@
     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;
+    
+    //! Used for debugging.
+    bool _nmeaOnUart0;      
 };
 
 #endif
--- a/GPS_VTG.cpp	Fri Apr 15 12:23:52 2011 +0000
+++ b/GPS_VTG.cpp	Sat Apr 16 09:37:33 2011 +0000
@@ -21,6 +21,7 @@
 */
 
 #include "GPS_VTG.h"
+#include <math.h>
 
 GPS_VTG::GPS_VTG() 
 {
@@ -35,10 +36,11 @@
 {
     if (n == NULL) n = new GPS_VTG;
     
-    do {
-        memcpy(n, this, sizeof(GPS_VTG));
-    }
-    while (memcmp(n, this, sizeof(GPS_VTG)));
+    n->_velocity_knots = _velocity_knots;
+    n->_velocity_kph   = _velocity_kph;
+    n->_track_true     = _track_true;
+    n->_track_mag      = _track_mag;
+    
     return n;    
 }
 
@@ -64,9 +66,9 @@
         token_counter++;
     }
     
+    if (trk_t)     { _track_true     = atof(trk_t);     }
+    if (trk_m)     { _track_mag      = atof(trk_m);     }    
     if (vel_knots) { _velocity_knots = atof(vel_knots); }
-    if (vel_kph)   { _velocity_kph   = atof(vel_kph); }
-    if (trk_t)     { _track_true     = atof(trk_t); }
-    if (trk_m)     { _track_mag      = atof(trk_m); }    
+    if (vel_kph)   { _velocity_kph   = atof(vel_kph);   }    
 }
 
--- a/GPS_VTG.h	Fri Apr 15 12:23:52 2011 +0000
+++ b/GPS_VTG.h	Sat Apr 16 09:37:33 2011 +0000
@@ -24,6 +24,7 @@
 #define GPS_VTG_H
 
 #include "mbed.h"
+#include "iomacros.h"
 
 /** GPS_Time definition.
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/info.h	Sat Apr 16 09:37:33 2011 +0000
@@ -0,0 +1,13 @@
+/*
+
+Typical NMEA sentences from my GPS module.
+
+$GPGGA,075851.891,5611.5305,N,00302.0369,W,0,00,4.8,44.0,M,52.0,M,,0000*77
+$GPGSA,A,1,,,,,,,,,,,,,4.8,4.8,0.7*37
+$GPGSV,3,1,12,20,82,116,,01,79,246,,32,54,077,,17,48,254,*70
+$GPGSV,3,2,12,23,46,168,,24,40,128,,04,25,295,,11,24,143,*73
+$GPGSV,3,3,12,31,22,065,,13,15,190,,12,11,343,,25,00,019,*7D
+$GPRMC,075851.891,V,5611.5305,N,00302.0369,W,002.2,252.9,160411,,,N*68
+$GPVTG,252.9,T,,M,002.2,N,004.1,K,N*0B
+
+*/
\ No newline at end of file