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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GPS.h Source File

GPS.h

00001 /*
00002     Copyright (c) 2010 Andy Kirkham
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021 */
00022 
00023 #ifndef GPS_H
00024 #define GPS_H
00025 
00026 #include "mbed.h"
00027 #include "GPS_VTG.h"
00028 #include "GPS_Time.h"
00029 #include "GPS_Geodetic.h"
00030 
00031 #define GPS_RBR  0x00
00032 #define GPS_THR  0x00
00033 #define GPS_DLL  0x00
00034 #define GPS_IER  0x04
00035 #define GPS_DML  0x04
00036 #define GPS_IIR  0x08
00037 #define GPS_FCR  0x08
00038 #define GPS_LCR  0x0C
00039 #define GPS_LSR  0x14
00040 #define GPS_SCR  0x1C
00041 #define GPS_ACR  0x20
00042 #define GPS_ICR  0x24
00043 #define GPS_FDR  0x28
00044 #define GPS_TER  0x30
00045 
00046 #define GPS_BUFFER_LEN  128
00047 #define GPS_TICKTOCK    10000
00048 
00049 /** @defgroup API The MODGPS API */
00050 
00051 /** GPS module
00052  * @author Andy Kirkham
00053  * @see http://mbed.org/cookbook/MODGPS
00054  * @see example1.cpp
00055  * @see example2.cpp
00056  * @see API 
00057  *
00058  * @image html /media/uploads/AjK/gps_interfaces.png "Wiring up the GPS module"
00059  *
00060  * Example:
00061  * @code
00062  * #include "mbed.h"
00063  * #include "GPS.h"
00064  *
00065  * DigitalOut led1(LED1);
00066  * Serial pc(USBTX, USBRX);
00067  * GPS gps(NC, p10); 
00068  *
00069  * int main() {
00070  *     GPS_Time t;
00071  *
00072  *     // Wait for the GPS NMEA data to become valid.
00073  *     while (!gps.isTimeValid()) {
00074  *       led1 = !led1;
00075  *       wait(1);
00076  *     }
00077  *
00078  *     gps.timeNow(&t);
00079  *
00080  *     pc.printf("The time/date is %02d:%02d:%02d %02d/%02d/%04d\r\n",
00081  *        t.hour, t.minute, t.second, t.day, t.month, t.year);
00082  *
00083  *     // Wait until at least four satellites produce a position fix and a valid quality.
00084  *     while (gps.numOfSats() < 4 && gps.getGPSquality != 0) {
00085  *       led1 = !led1;
00086  *       wait(1);
00087  *     }
00088  *
00089  *     pc.printf("Lat = %.4f Lon = %.4f Alt = %.1fkm\r\n", 
00090  *         gps.latitude(), gps.longitude, gps.altitude());
00091  *
00092  *     // Make the LED go steady to indicate we have finished.
00093  *     led1 = 1;
00094  * 
00095  *     while(1) {}
00096  * }
00097  * @endcode
00098  */
00099 
00100 class GPS : Serial {
00101 public:
00102     
00103     //! The PPS edge type to interrupt on.
00104     enum ppsEdgeType { 
00105         ppsRise  = 0,    /*!< Use the rising edge (default). */
00106         ppsFall          /*!< Use the falling edge. */
00107     };
00108     
00109     //! A copy of the Serial parity enum
00110     enum Parity {
00111         None = 0
00112         , Odd
00113         , Even
00114         , Forced1   
00115         , Forced0
00116     };
00117     
00118     //! GPS constructor.
00119     /**
00120      * The GPS constructor is used to initialise the GPS object.
00121      *
00122      * @param tx Usually unused and set to NC
00123      * @param rx The RX pin the GPS is connected to, p10, p14( OR p25), p27.
00124      * @param name An option name for RPC usage.
00125      */
00126     GPS(PinName tx, PinName rx, const char *name = NULL);
00127 
00128     //! Is the time reported by the GPS valid.
00129     /**
00130      * Method used to check the validity of the time the GPS module is reporting.
00131      *
00132      * @code
00133      *     // Assuming we have a GPS object previously created...
00134      *     GPS gps(NC, p9); 
00135      *
00136      *     if (gps.isTimeValid()) {
00137      *         // Time is valid :)
00138      *     }
00139      *     else {
00140      *         // Doh, time is not valid :(
00141      *     )
00142      *     
00143      * @endcode
00144      *
00145      * @ingroup API
00146      * @return bool true if valid, false otherwise
00147      */
00148     bool isTimeValid(void) { return theTime.status == 'V' ? false : true; }
00149     
00150     //! Is the positional fix reported by the GPS valid.
00151     /**
00152      * Method used to check the validity of the positional data. This method
00153      * returns the GGA field, 0 is "bad, 1 is "ok", etc. See the NMEA GGA 
00154      * description for more details.
00155      *
00156      * @code
00157      *     // Assuming we have a GPS object previously created...
00158      *     GPS gps(NC, p9); 
00159      *
00160      *     if (gps.getGPSquality() == 0) {
00161      *         // The location fix is no good/not accurate :(
00162      *     }
00163      *     else {
00164      *         // All good, can use last fix data.
00165      *     )
00166      *     
00167      * @endcode
00168      *
00169      * @ingroup API
00170      * @return int 0 on no fix, 1... (see NMEA GGA for more details).
00171      */
00172     int getGPSquality(void) { return thePlace.getGPSquality(); }
00173     
00174     //! How many satellites were used in the last fix.
00175     /**
00176      * Method returns the number of GPS satellites used on the last fix.
00177      *
00178      * @code
00179      *     // Assuming we have a GPS object previously created...
00180      *     GPS gps(NC, p9); 
00181      *
00182      *     int sats = gps.numOfSats();
00183      *     
00184      * @endcode
00185      *
00186      * @ingroup API
00187      * @return int The number of satellites.
00188      */
00189     int numOfSats(void) { return thePlace.numOfSats(); }
00190     
00191     //! What was the last reported latitude (in degrees)
00192     /**
00193      * Method returns a double in degrees, positive being North, negative being South.
00194      *
00195      * @code
00196      *     // Assuming we have a GPS object previously created...
00197      *     GPS gps(NC, p9); 
00198      *
00199      *     double latitude = gps.latitude();
00200      *     
00201      * @endcode
00202      *
00203      * @ingroup API
00204      * @return double Degrees
00205      */
00206     double latitude(void);
00207     
00208     //! What was the last reported longitude (in degrees)
00209     /**
00210      * Method returns a double in degrees, positive being East, negative being West.
00211      *
00212      * @code
00213      *     // Assuming we have a GPS object previously created...
00214      *     GPS gps(NC, p9); 
00215      *
00216      *     double logitude = gps.logitude();
00217      *     
00218      * @endcode
00219      *
00220      * @ingroup API
00221      * @return double Degrees
00222      */
00223     double longitude(void);
00224     
00225     //! What was the last reported altitude (in kilometers)
00226     /**
00227      * Method returns a double in kilometers.
00228      *
00229      * @code
00230      *     // Assuming we have a GPS object previously created...
00231      *     GPS gps(NC, p9); 
00232      *
00233      *     double altitude = gps.altitude();
00234      *     
00235      * @endcode
00236      *
00237      * @ingroup API
00238      * @return double Kilometers
00239      */
00240     double altitude(void);
00241     
00242     //! What was the last reported altitude/height (in kilometers)
00243     /**
00244      * @see altitude()
00245      *
00246      * @code
00247      *     // Assuming we have a GPS object previously created...
00248      *     GPS gps(NC, p9); 
00249      *
00250      *     double height = gps.height();
00251      *     
00252      * @endcode
00253      *
00254      * Note, this is identical to altitude()
00255      * @see altitude()
00256      *
00257      * @ingroup API
00258      * @return double Kilometers
00259      */
00260     double height(void) { return altitude(); }
00261     
00262     //! Get all vector parameters together.
00263     /**
00264      * Pass a pointer to a GPS_VTG object and the current
00265      * GPS data will be copied into it.
00266      *
00267      * @code
00268      *     // Assuming we have a GPS object previously created...
00269      *     GPS gps(NC, p9); 
00270      *
00271      *     // Then get the data...
00272      *     GPS_VTG p;
00273      *     gps.vtg(&p);
00274      *     printf("Speed (knots)  = %.4f", p.velocity_knots);
00275      *     printf("Speed (kps)    = %.4f", p.velocity_kps);
00276      *     printf("Track (true)  = %.4f", p.track_true);
00277      *     printf("Track (mag)    = %.4f", p.track_mag);
00278      *
00279      * @endcode
00280      *
00281      * @ingroup API
00282      * @param g A GSP_VTG pointer to an existing GPS_VTG object.
00283      * @return GPS_VTG * The pointer passed in.
00284      */
00285     GPS_VTG *vtg(GPS_VTG *g);
00286     
00287     //! Get all vector parameters together.
00288     /**
00289      * Get all the vector data at once. For example:-
00290      *
00291      * @code
00292      *     // Assuming we have a GPS object previously created...
00293      *     GPS gps(NC, p9); 
00294      *
00295      *     // Then get the data...
00296      *     GPS_VTG *p = gps.vtg();
00297      *     printf("Speed (knots)  = %.4f", p->velocity_knots);
00298      *     printf("Speed (kps)    = %.4f", p->velocity_kps);
00299      *     printf("Track (true)  = %.4f", p->track_true);
00300      *     printf("Track (mag)    = %.4f", p->track_mag);     
00301      *     delete(p); // then remember to delete the object to prevent memory leaks.
00302      *
00303      * @endcode
00304      *
00305      * @ingroup API
00306      * @return GPS_Geodetic * A pointer to the data.
00307      */
00308     GPS_VTG *vtg(void) { return vtg(NULL); }
00309     
00310     //! Get all three geodetic parameters together.
00311     /**
00312      * Pass a pointer to a GPS_Geodetic object and the current
00313      * GPS data will be copied into it.
00314      *
00315      * @code
00316      *     // Assuming we have a GPS object previously created...
00317      *     GPS gps(NC, p9); 
00318      *
00319      *     // Then get the data...
00320      *     GPS_Geodetic p;
00321      *     gps.geodetic(&p);
00322      *     printf("Latitude  = %.4f", p.lat);
00323      *     printf("Longitude = %.4f", p.lon);
00324      *     printf("Altitude  = %.4f", p.alt);
00325      *
00326      * @endcode
00327      *
00328      * @ingroup API
00329      * @param g A GSP_Geodetic pointer to an existing GPS_Geodetic object.
00330      * @return GPS_Geodetic * The pointer passed in.
00331      */
00332     GPS_Geodetic *geodetic(GPS_Geodetic *g);
00333     
00334     //! Get all three geodetic parameters together.
00335     /**
00336      * Get all the geodetic data at once. For example:-
00337      *
00338      * @code
00339      *     // Assuming we have a GPS object previously created...
00340      *     GPS gps(NC, p9); 
00341      *
00342      *     // Then get the data...
00343      *     GPS_Geodetic *p = gps.geodetic();
00344      *     printf("Latitude = %.4f", p->lat);
00345      *     delete(p); // then remember to delete the object to prevent memory leaks.
00346      *
00347      * @endcode
00348      *
00349      * @ingroup API
00350      * @return GPS_Geodetic * A pointer to the data.
00351      */
00352     GPS_Geodetic *geodetic(void) { return geodetic(NULL); }
00353     
00354     //! Take a snap shot of the current time.
00355     /**
00356      * Pass a pointer to a GPS_Time object to get a copy of the current
00357      * time and date as reported by the GPS.
00358      *
00359      * @code
00360      *     // Assuming we have a GPS object previously created...
00361      *     GPS gps(NC, p9); 
00362      *
00363      *     // Then get the data...
00364      *     GPS_Time t;
00365      *     gps.timeNow(&t);
00366      *     printf("Year = %d", t.year);
00367      *
00368      * @endcode
00369      *
00370      * @ingroup API
00371      * @param n A GPS_Time * pointer to an existing GPS_Time object.
00372      * @return GPS_Time * The pointer passed in.
00373      */
00374     GPS_Time * timeNow(GPS_Time *n) { return theTime.timeNow(n); }
00375     
00376     //! Take a snap shot of the current time.
00377     /**
00378      * Pass a pointer to a GPS_Time object to get a copy of the current
00379      * time and date as reported by the GPS.
00380      *
00381      * @code
00382      *     // Assuming we have a GPS object previously created...
00383      *     GPS gps(NC, p9); 
00384      *
00385      *     // Then get the data...
00386      *     GPS_Time *t = gps.timeNow();
00387      *     printf("Year = %d", t->year);
00388      *     delete(t); // Avoid memory leaks.
00389      *
00390      * @endcode
00391      *
00392      * @ingroup API
00393      * @return GPS_Time * The pointer passed in.
00394      */
00395     GPS_Time * timeNow(void) { GPS_Time *n = new GPS_Time; return theTime.timeNow(n); }
00396     
00397     //! Return the curent day.
00398     /**
00399      * @code
00400      *     // Assuming we have a GPS object previously created...
00401      *     GPS gps(NC, p9); 
00402      *
00403      *     // Then get the Julain Day Number.
00404      *     double julianDayNumber = gps.julianDayNumber();
00405      *
00406      * @endcode
00407      *
00408      * @ingroup API
00409      * @return double The Julian Date as a double.
00410      */
00411     double julianDayNumber(void) { return theTime.julian_day_number(); } 
00412     
00413     //! Return the curent date/time as a Julian date
00414     /**
00415      * @code
00416      *     // Assuming we have a GPS object previously created...
00417      *     GPS gps(NC, p9); 
00418      *
00419      *     // Then get the Julian Date.
00420      *     double julianDate = gps.julianDate();
00421      *
00422      * @endcode
00423      *
00424      * @ingroup API
00425      * @return double The Julian Date as a double.
00426      */
00427     double julianDate(void) { return theTime.julian_date(); }
00428 
00429     //! Get the current sidereal degree angle.
00430     /**
00431      * @code
00432      *     // Assuming we have a GPS object previously created...
00433      *     GPS gps(NC, p9); 
00434      *     double sidereal = gps.siderealDegrees();
00435      *
00436      * @endcode
00437      *
00438      * @ingroup API
00439      * @return double Sidereal degree angle..
00440      */
00441     double siderealDegrees(void) { return theTime.siderealDegrees(&theTime, longitude()); }
00442     
00443     //! Get the current sidereal hour angle.
00444     /**
00445      * @code
00446      *     // Assuming we have a GPS object previously created...
00447      *     GPS gps(NC, p9); 
00448      *     double sidereal = gps.siderealHA();
00449      *
00450      * @endcode
00451      *
00452      * @ingroup API
00453      * @return double Sidereal degree angle..
00454      */
00455     double siderealHA(void) { return theTime.siderealHA(&theTime, longitude()); }
00456     
00457     //! Optionally, connect a 1PPS single to an Mbed pin.
00458     /**
00459      * Optional: If the GPS unit has a 1PPS output, use this to
00460      * connect that to our internal ISR. Using the 1PPS increases
00461      * the GPS_Time time accuracy from +/-0.25s to +/-0.001s
00462      *
00463      * @code
00464      *     // Assuming we have a GPS object previously created...
00465      *     GPS gps(NC, p9); 
00466      *
00467      *     gps.ppsAttach(p29); // default to GPS::ppsRise, rising edge. 
00468      *
00469      *     // Or...
00470      *     gps.ppsAttach(p29, GPS::ppsRise); // The default.
00471      *
00472      *     // Or...
00473      *     gps.ppsAttach(p29, GPS::ppsFall); // If a falling edge.
00474      *
00475      * @endcode
00476      *
00477      * <b>Note</b>, before using this function you should attach an actual
00478      * callback function using attach_pps()
00479      *
00480      * @see attach_pps()
00481      *
00482      * @ingroup API
00483      * @param irq A PinName to attach
00484      * @param type The type of edge, MAX7456::ppsRise OR MAX7456::ppsFall
00485      */
00486     void ppsAttach(PinName irq, ppsEdgeType type = ppsRise );
00487     
00488     //! Remove any 1PPS signal previously attached.
00489     void ppsUnattach(void);
00490     
00491     //! GPS serial receive interrupt handler.
00492     void rx_irq(void);    
00493     
00494     //! GPS pps interrupt handler.
00495     void pps_irq(void);
00496     
00497     //! A pointer to the UART peripheral base address being used.
00498     void *_base;
00499     
00500     //! The RX serial buffer.
00501     char buffer[2][GPS_BUFFER_LEN];
00502     
00503     //! The current "active" buffer, i.e. the buffer the ISR is writing to.
00504     int  active_buffer;
00505     
00506     //! The active buffer "in" pointer.
00507     int  rx_buffer_in;
00508     
00509     //! Boolean flag set when the "passive" buffer is full and needs processing.
00510     bool process_required;
00511     
00512     //! 10ms Ticker callback.
00513     void ticktock(void);
00514     
00515     //! Attach a user object/method callback function to the PPS signal
00516     /**
00517      * Attach a user callback object/method to call when the 1PPS signal activates. 
00518      *
00519      * @code
00520      *     class FOO {
00521      *     public:
00522      *         void myCallback(void);
00523      *     };
00524      *
00525      *     GPS gps(NC, p9); 
00526      *     Foo foo;
00527      *
00528      *     gps.attach_pps(foo, &FOO::myCallback);
00529      * 
00530      * @endcode
00531      *
00532      * @ingroup API
00533      * @param tptr pointer to the object to call the member function on
00534      * @param mptr pointer to the member function to be called
00535      */
00536     template<typename T>
00537     void attach_pps(T* tptr, void (T::*mptr)(void)) { cb_pps.attach(tptr, mptr); }
00538     
00539     //! Attach a user callback function to the PPS signal
00540     /**
00541      * Attach a user callback function pointer to call when the 1PPS signal activates. 
00542      *
00543      * @code
00544      *     void myCallback(void) { ... }
00545      *
00546      *     GPS gps(NC, p9); 
00547      *     Foo foo;
00548      *
00549      *     gps.attach_pps(&myCallback);
00550      * 
00551      * @endcode
00552      *
00553      * @ingroup API
00554      * @param fptr Callback function pointer
00555      */
00556     void attach_pps(void (*fptr)(void)) { cb_pps.attach(fptr); } 
00557     
00558     //! A callback object for the 1PPS user API.
00559     FunctionPointer cb_pps;
00560     
00561     //! Attach a user callback function to the NMEA RMC message processed signal.
00562     /**
00563      * Attach a user callback object/method to call when an NMEA RMC packet has been processed. 
00564      *
00565      * @code
00566      *     class FOO {
00567      *     public:
00568      *         void myCallback(void);
00569      *     };
00570      *
00571      *     GPS gps(NC, p9); 
00572      *     Foo foo;
00573      *
00574      *     gps.attach_rmc(foo, &FOO::myCallback);
00575      * 
00576      * @endcode
00577      *
00578      * @ingroup API 
00579      * @param tptr pointer to the object to call the member function on
00580      * @param mptr pointer to the member function to be called
00581      */
00582     template<typename T>
00583     void attach_rmc(T* tptr, void (T::*mptr)(void)) { cb_rmc.attach(tptr, mptr); }
00584     
00585     //! Attach a user callback function to the NMEA RMC message processed signal.
00586     /**
00587      * Attach a user callback function pointer to call when an NMEA RMC packet has been processed. 
00588      *
00589      * @code
00590      *     void myCallback(void) { ... }
00591      *
00592      *     GPS gps(NC, p9); 
00593      *     Foo foo;
00594      *
00595      *     gps.attach_rmc(&myCallback);
00596      * 
00597      * @endcode
00598      *
00599      * @ingroup API 
00600      * @param fptr Callback function pointer.
00601      */
00602     void attach_rmc(void (*fptr)(void)) { cb_rmc.attach(fptr); } 
00603     
00604     //! A callback object for the NMEA RMS message processed signal user API.
00605     FunctionPointer cb_rmc;
00606     
00607     //! Attach a user callback function to the NMEA GGA message processed signal.
00608     /**
00609      * Attach a user callback object/method to call when an NMEA GGA packet has been processed. 
00610      *
00611      * @code
00612      *     class FOO {
00613      *     public:
00614      *         void myCallback(void);
00615      *     };
00616      *
00617      *     GPS gps(NC, p9); 
00618      *     Foo foo;
00619      *
00620      *     gps.attach_gga(foo, &FOO::myCallback);
00621      * 
00622      * @endcode
00623      *
00624      * @ingroup API 
00625      * @param tptr pointer to the object to call the member function on
00626      * @param mptr pointer to the member function to be called
00627      */
00628     template<typename T>
00629     void attach_gga(T* tptr, void (T::*mptr)(void)) { cb_gga.attach(tptr, mptr); }
00630     
00631     //! Attach a user callback function to the NMEA GGA message processed signal.
00632     /**
00633      * Attach a user callback function pointer to call when an NMEA GGA packet has been processed. 
00634      *
00635      * @code
00636      *     void myCallback(void) { ... }
00637      *
00638      *     GPS gps(NC, p9); 
00639      *     Foo foo;
00640      *
00641      *     gps.attach_gga(&myCallback);
00642      * 
00643      * @endcode
00644      *
00645      * @ingroup API 
00646      * @param fptr Callback function pointer.
00647      */
00648     void attach_gga(void (*fptr)(void)) { cb_gga.attach(fptr); } 
00649     
00650     //! A callback object for the NMEA GGA message processed signal user API.
00651     FunctionPointer cb_gga;
00652 
00653 
00654     //! Attach a user callback function to the NMEA VTG message processed signal.
00655     /**
00656      * Attach a user callback object/method to call when an NMEA VTG packet has been processed. 
00657      *
00658      * @code
00659      *     class FOO {
00660      *     public:
00661      *         void myCallback(void);
00662      *     };
00663      *
00664      *     GPS gps(NC, p9); 
00665      *     Foo foo;
00666      *
00667      *     gps.attach_vtg(foo, &FOO::myCallback);
00668      * 
00669      * @endcode
00670      *
00671      * @ingroup API 
00672      * @param tptr pointer to the object to call the member function on
00673      * @param mptr pointer to the member function to be called
00674      */
00675     template<typename T>
00676     void attach_vtg(T* tptr, void (T::*mptr)(void)) { cb_vtg.attach(tptr, mptr); }
00677     
00678     //! Attach a user callback function to the NMEA VTG message processed signal.
00679     /**
00680      * Attach a user callback function pointer to call when an NMEA VTG packet has been processed. 
00681      *
00682      * @code
00683      *     void myCallback(void) { ... }
00684      *
00685      *     GPS gps(NC, p9); 
00686      *     Foo foo;
00687      *
00688      *     gps.attach_vtg(&myCallback);
00689      * 
00690      * @endcode
00691      *
00692      * @ingroup API 
00693      * @param fptr Callback function pointer.
00694      */
00695     void attach_vtg(void (*fptr)(void)) { cb_vtg.attach(fptr); } 
00696     
00697     //! A callback object for the NMEA RMS message processed signal user API.
00698     FunctionPointer cb_vtg;
00699     
00700     //! Attach a user callback function to the unknown NMEA message.
00701     /**
00702      * Attach a user callback object/method to call when an unknown NMEA packet. 
00703      *
00704      * @code
00705      *     class FOO {
00706      *     public:
00707      *         void myCallback(void);
00708      *     };
00709      *
00710      *     GPS gps(NC, p9); 
00711      *     Foo foo;
00712      *
00713      *     gps.attach_ukn(foo, &FOO::myCallback);
00714      * 
00715      * @endcode
00716      *
00717      * @ingroup API 
00718      * @param tptr pointer to the object to call the member function on
00719      * @param mptr pointer to the member function to be called
00720      */
00721     template<typename T>
00722     void attach_ukn(T* tptr, void (T::*mptr)(void)) { cb_ukn.attach(tptr, mptr); }
00723     
00724     //! Attach a user callback function to the unknown NMEA message.
00725     /**
00726      * Attach a user callback function pointer to call when an unknown NMEA. 
00727      *
00728      * @code
00729      *     void myCallback(void) { ... }
00730      *
00731      *     GPS gps(NC, p9); 
00732      *     Foo foo;
00733      *
00734      *     gps.attach_ukn(&myCallback);
00735      * 
00736      * @endcode
00737      *
00738      * @ingroup API 
00739      * @param fptr Callback function pointer.
00740      */
00741     void attach_ukn(void (*fptr)(void)) { cb_ukn.attach(fptr); } 
00742     
00743     //! A callback object for the NMEA RMS message processed signal user API.
00744     FunctionPointer cb_ukn;
00745     
00746     /**
00747      * Set's the GGA string memory pointer.
00748      * @param s char pointer ti string.
00749      * @return char s passed in.
00750      */
00751     char * setGga(char *s) { _gga = s; return s; }
00752     
00753     /**
00754      * Set's the RMC string memory pointer.
00755      * @param s char pointer ti string.
00756      * @return char s passed in.
00757      */
00758     char * setRmc(char *s) { _rmc = s; return s; };
00759     
00760     /**
00761      * Set's the VTG string memory pointer.
00762      * @param s char pointer ti string.
00763      * @return char s passed in.
00764      */
00765     char * setVtg(char *s) { _vtg = s; return s; };
00766     
00767     /**
00768      * Set's the UKN string memory pointer.
00769      * @param s char pointer ti string.
00770      * @return char s passed in.
00771      */
00772     char * setUkn(char *s) { _ukn = s; return s; };
00773     
00774     //! Set the baud rate the GPS module is using.
00775     /** 
00776      * Set the baud rate of the serial port
00777      * 
00778      * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.baud
00779      *
00780      * @ingroup API 
00781      * @param baudrate The baudrate to set.
00782      */
00783     void baud(int baudrate) { Serial::baud(baudrate); }
00784     
00785    //! Set the serial port format the GPS module is using. 
00786    /**
00787     * Set the transmission format used by the Serial port
00788     *
00789     * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format
00790     *
00791     * @ingroup API 
00792     * @param bits - The number of bits in a word (5-8; default = 8)
00793     * @param parity - The parity used (GPS::None, GPS::Odd, GPS::Even, GPS::Forced1, GPS::Forced0; default = GPS::None)
00794     * @param stop_bits - The number of stop bits (1 or 2; default = 1)
00795     */
00796     void format(int bits, Parity parity, int stop_bits) { Serial::format(bits, (Serial::Parity)parity, stop_bits); }
00797     
00798    //! Send incoming GPS bytes to Uart0
00799    /**
00800     * Send incoming GPS bytes to Uart0
00801     *
00802     * This can be useful for printing out the bytes from the GPS onto
00803     * a the common debug port Uart0. Note, Uart0 should have been setup
00804     * and initialised before switching this on. Also, realistically,
00805     * you should ensure Uart0 has a higher baud rate than that being
00806     * used by the GPS. Sending of bytes to Uart0 is "raw" and should
00807     * only be used to initially gather data and should NOT be used as
00808     * part of the application design. If you need to forward on the 
00809     * data you should come up with a proper strategy.
00810     *
00811     * @ingroup API 
00812     * @param b - True to send to Uart0, false otherwise
00813     */
00814     void NmeaOnUart0(bool b) { _nmeaOnUart0 = b; }
00815         
00816 protected:
00817 
00818     //! Flag set true when a GPS PPS has been attached to a pin.
00819     bool         _ppsInUse;
00820     
00821     //! An InterruptIn object to "trigger" on the PPS edge.
00822     InterruptIn *_pps;
00823     
00824     //! A Ticker object called every 10ms.
00825     Ticker      *_second100;
00826     
00827     //! A GPS_Time object used to hold the last parsed time/date data.
00828     GPS_Time     theTime;
00829     
00830     //! A GPS_Geodetic object used to hold the last parsed positional data.
00831     GPS_Geodetic thePlace;
00832     
00833     //! A GPS_VTG object used to hold vector data.
00834     GPS_VTG      theVTG; 
00835     
00836     //! Used to record the previous byte received.
00837     char _lastByte;
00838     
00839     char *_gga;
00840     char *_rmc;
00841     char *_vtg;
00842     char *_ukn;
00843     
00844     //! Used for debugging.
00845     bool _nmeaOnUart0;      
00846 };
00847 
00848 #endif
00849