Sergey S / MODGPS

Fork of MODGPS by Andy K

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 : RawSerial
00101 {
00102 public:
00103 
00104     //! The PPS edge type to interrupt on.
00105     enum ppsEdgeType {
00106         ppsRise  = 0,    /*!< Use the rising edge (default). */
00107         ppsFall          /*!< Use the falling edge. */
00108     };
00109 
00110     //! GPS constructor.
00111     /**
00112      * The GPS constructor is used to initialise the GPS object.
00113      *
00114      * @param tx Usually unused and set to NC
00115      * @param rx The RX pin the GPS is connected to, p10, p14( OR p25), p27.
00116      * @param name An option name for RPC usage.
00117      */
00118     GPS(PinName tx, PinName rx, const char *name = NULL);
00119 
00120     //! Is the time reported by the GPS valid.
00121     /**
00122      * Method used to check the validity of the time the GPS module is reporting.
00123      *
00124      * @code
00125      *     // Assuming we have a GPS object previously created...
00126      *     GPS gps(NC, p9);
00127      *
00128      *     if (gps.isTimeValid()) {
00129      *         // Time is valid :)
00130      *     }
00131      *     else {
00132      *         // Doh, time is not valid :(
00133      *     )
00134      *
00135      * @endcode
00136      *
00137      * @ingroup API
00138      * @return bool true if valid, false otherwise
00139      */
00140     bool isTimeValid(void) {
00141         return theTime.status == 'V' ? false : true;
00142     }
00143 
00144     //! Is the positional fix reported by the GPS valid.
00145     /**
00146      * Method used to check the validity of the positional data. This method
00147      * returns the GGA field, 0 is "bad, 1 is "ok", etc. See the NMEA GGA
00148      * description for more details.
00149      *
00150      * @code
00151      *     // Assuming we have a GPS object previously created...
00152      *     GPS gps(NC, p9);
00153      *
00154      *     if (gps.getGPSquality() == 0) {
00155      *         // The location fix is no good/not accurate :(
00156      *     }
00157      *     else {
00158      *         // All good, can use last fix data.
00159      *     )
00160      *
00161      * @endcode
00162      *
00163      * @ingroup API
00164      * @return int 0 on no fix, 1... (see NMEA GGA for more details).
00165      */
00166     int getGPSquality(void) {
00167         return thePlace.getGPSquality();
00168     }
00169 
00170     //! How many satellites were used in the last fix.
00171     /**
00172      * Method returns the number of GPS satellites used on the last fix.
00173      *
00174      * @code
00175      *     // Assuming we have a GPS object previously created...
00176      *     GPS gps(NC, p9);
00177      *
00178      *     int sats = gps.numOfSats();
00179      *
00180      * @endcode
00181      *
00182      * @ingroup API
00183      * @return int The number of satellites.
00184      */
00185     int numOfSats(void) {
00186         return thePlace.numOfSats();
00187     }
00188 
00189     //! What was the last reported latitude (in degrees)
00190     /**
00191      * Method returns a double in degrees, positive being North, negative being South.
00192      *
00193      * @code
00194      *     // Assuming we have a GPS object previously created...
00195      *     GPS gps(NC, p9);
00196      *
00197      *     double latitude = gps.latitude();
00198      *
00199      * @endcode
00200      *
00201      * @ingroup API
00202      * @return double Degrees
00203      */
00204     double latitude(void);
00205 
00206     //! What was the last reported longitude (in degrees)
00207     /**
00208      * Method returns a double in degrees, positive being East, negative being West.
00209      *
00210      * @code
00211      *     // Assuming we have a GPS object previously created...
00212      *     GPS gps(NC, p9);
00213      *
00214      *     double logitude = gps.logitude();
00215      *
00216      * @endcode
00217      *
00218      * @ingroup API
00219      * @return double Degrees
00220      */
00221     double longitude(void);
00222 
00223     //! What was the last reported altitude (in kilometers)
00224     /**
00225      * Method returns a double in kilometers.
00226      *
00227      * @code
00228      *     // Assuming we have a GPS object previously created...
00229      *     GPS gps(NC, p9);
00230      *
00231      *     double altitude = gps.altitude();
00232      *
00233      * @endcode
00234      *
00235      * @ingroup API
00236      * @return double Kilometers
00237      */
00238     double altitude(void);
00239 
00240     //! What was the last reported altitude/height (in kilometers)
00241     /**
00242      * @see altitude()
00243      *
00244      * @code
00245      *     // Assuming we have a GPS object previously created...
00246      *     GPS gps(NC, p9);
00247      *
00248      *     double height = gps.height();
00249      *
00250      * @endcode
00251      *
00252      * Note, this is identical to altitude()
00253      * @see altitude()
00254      *
00255      * @ingroup API
00256      * @return double Kilometers
00257      */
00258     double height(void) {
00259         return altitude();
00260     }
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) {
00309         return vtg(NULL);
00310     }
00311 
00312     //! Get all three geodetic parameters together.
00313     /**
00314      * Pass a pointer to a GPS_Geodetic object and the current
00315      * GPS data will be copied into it.
00316      *
00317      * @code
00318      *     // Assuming we have a GPS object previously created...
00319      *     GPS gps(NC, p9);
00320      *
00321      *     // Then get the data...
00322      *     GPS_Geodetic p;
00323      *     gps.geodetic(&p);
00324      *     printf("Latitude  = %.4f", p.lat);
00325      *     printf("Longitude = %.4f", p.lon);
00326      *     printf("Altitude  = %.4f", p.alt);
00327      *
00328      * @endcode
00329      *
00330      * @ingroup API
00331      * @param g A GSP_Geodetic pointer to an existing GPS_Geodetic object.
00332      * @return GPS_Geodetic * The pointer passed in.
00333      */
00334     GPS_Geodetic *geodetic(GPS_Geodetic *g);
00335 
00336     //! Get all three geodetic parameters together.
00337     /**
00338      * Get all the geodetic data at once. For example:-
00339      *
00340      * @code
00341      *     // Assuming we have a GPS object previously created...
00342      *     GPS gps(NC, p9);
00343      *
00344      *     // Then get the data...
00345      *     GPS_Geodetic *p = gps.geodetic();
00346      *     printf("Latitude = %.4f", p->lat);
00347      *     delete(p); // then remember to delete the object to prevent memory leaks.
00348      *
00349      * @endcode
00350      *
00351      * @ingroup API
00352      * @return GPS_Geodetic * A pointer to the data.
00353      */
00354     GPS_Geodetic *geodetic(void) {
00355         return geodetic(NULL);
00356     }
00357 
00358     //! Take a snap shot of the current time.
00359     /**
00360      * Pass a pointer to a GPS_Time object to get a copy of the current
00361      * time and date as reported by the GPS.
00362      *
00363      * @code
00364      *     // Assuming we have a GPS object previously created...
00365      *     GPS gps(NC, p9);
00366      *
00367      *     // Then get the data...
00368      *     GPS_Time t;
00369      *     gps.timeNow(&t);
00370      *     printf("Year = %d", t.year);
00371      *
00372      * @endcode
00373      *
00374      * @ingroup API
00375      * @param n A GPS_Time * pointer to an existing GPS_Time object.
00376      * @return GPS_Time * The pointer passed in.
00377      */
00378     GPS_Time * timeNow(GPS_Time *n) {
00379         return theTime.timeNow(n);
00380     }
00381 
00382     //! Take a snap shot of the current time.
00383     /**
00384      * Pass a pointer to a GPS_Time object to get a copy of the current
00385      * time and date as reported by the GPS.
00386      *
00387      * @code
00388      *     // Assuming we have a GPS object previously created...
00389      *     GPS gps(NC, p9);
00390      *
00391      *     // Then get the data...
00392      *     GPS_Time *t = gps.timeNow();
00393      *     printf("Year = %d", t->year);
00394      *     delete(t); // Avoid memory leaks.
00395      *
00396      * @endcode
00397      *
00398      * @ingroup API
00399      * @return GPS_Time * The pointer passed in.
00400      */
00401     GPS_Time * timeNow(void) {
00402         GPS_Time *n = new GPS_Time;
00403         return theTime.timeNow(n);
00404     }
00405 
00406     //! Return the curent day.
00407     /**
00408      * @code
00409      *     // Assuming we have a GPS object previously created...
00410      *     GPS gps(NC, p9);
00411      *
00412      *     // Then get the Julain Day Number.
00413      *     double julianDayNumber = gps.julianDayNumber();
00414      *
00415      * @endcode
00416      *
00417      * @ingroup API
00418      * @return double The Julian Date as a double.
00419      */
00420     double julianDayNumber(void) {
00421         return theTime.julian_day_number();
00422     }
00423 
00424     //! Return the curent date/time as a Julian date
00425     /**
00426      * @code
00427      *     // Assuming we have a GPS object previously created...
00428      *     GPS gps(NC, p9);
00429      *
00430      *     // Then get the Julian Date.
00431      *     double julianDate = gps.julianDate();
00432      *
00433      * @endcode
00434      *
00435      * @ingroup API
00436      * @return double The Julian Date as a double.
00437      */
00438     double julianDate(void) {
00439         return theTime.julian_date();
00440     }
00441 
00442     //! Get the current sidereal degree angle.
00443     /**
00444      * @code
00445      *     // Assuming we have a GPS object previously created...
00446      *     GPS gps(NC, p9);
00447      *     double sidereal = gps.siderealDegrees();
00448      *
00449      * @endcode
00450      *
00451      * @ingroup API
00452      * @return double Sidereal degree angle..
00453      */
00454     double siderealDegrees(void) {
00455         return theTime.siderealDegrees(&theTime, longitude());
00456     }
00457 
00458     //! Get the current sidereal hour angle.
00459     /**
00460      * @code
00461      *     // Assuming we have a GPS object previously created...
00462      *     GPS gps(NC, p9);
00463      *     double sidereal = gps.siderealHA();
00464      *
00465      * @endcode
00466      *
00467      * @ingroup API
00468      * @return double Sidereal degree angle..
00469      */
00470     double siderealHA(void) {
00471         return theTime.siderealHA(&theTime, longitude());
00472     }
00473 
00474     //! Optionally, connect a 1PPS single to an Mbed pin.
00475     /**
00476      * Optional: If the GPS unit has a 1PPS output, use this to
00477      * connect that to our internal ISR. Using the 1PPS increases
00478      * the GPS_Time time accuracy from +/-0.25s to +/-0.001s
00479      *
00480      * @code
00481      *     // Assuming we have a GPS object previously created...
00482      *     GPS gps(NC, p9);
00483      *
00484      *     gps.ppsAttach(p29); // default to GPS::ppsRise, rising edge.
00485      *
00486      *     // Or...
00487      *     gps.ppsAttach(p29, GPS::ppsRise); // The default.
00488      *
00489      *     // Or...
00490      *     gps.ppsAttach(p29, GPS::ppsFall); // If a falling edge.
00491      *
00492      * @endcode
00493      *
00494      * <b>Note</b>, before using this function you should attach an actual
00495      * callback function using attach_pps()
00496      *
00497      * @see attach_pps()
00498      *
00499      * @ingroup API
00500      * @param irq A PinName to attach
00501      * @param type The type of edge, MAX7456::ppsRise OR MAX7456::ppsFall
00502      */
00503     void ppsAttach(PinName irq, ppsEdgeType type = ppsRise );
00504 
00505     //! Remove any 1PPS signal previously attached.
00506     void ppsUnattach(void);
00507 
00508     //! GPS serial receive interrupt handler.
00509     void rx_irq(void);
00510 
00511     //! GPS pps interrupt handler.
00512     void pps_irq(void);
00513 
00514     //! The RX serial buffer.
00515     char buffer[2][GPS_BUFFER_LEN];
00516 
00517     //! The current "active" buffer, i.e. the buffer the ISR is writing to.
00518     int  active_buffer;
00519 
00520     //! The active buffer "in" pointer.
00521     int  rx_buffer_in;
00522 
00523     //! Boolean flag set when the "passive" buffer is full and needs processing.
00524     bool process_required;
00525 
00526     //! 10ms Ticker callback.
00527     void ticktock(void);
00528 
00529     //! Attach a user object/method callback function to the PPS signal
00530     /**
00531      * Attach a user callback object/method to call when the 1PPS signal activates.
00532      *
00533      * @code
00534      *     class FOO {
00535      *     public:
00536      *         void myCallback(void);
00537      *     };
00538      *
00539      *     GPS gps(NC, p9);
00540      *     Foo foo;
00541      *
00542      *     gps.attach_pps(foo, &FOO::myCallback);
00543      *
00544      * @endcode
00545      *
00546      * @ingroup API
00547      * @param tptr pointer to the object to call the member function on
00548      * @param mptr pointer to the member function to be called
00549      */
00550     template<typename T>
00551     void attach_pps(T* tptr, void (T::*mptr)(void)) {
00552         cb_pps.attach(tptr, mptr);
00553     }
00554 
00555     //! Attach a user callback function to the PPS signal
00556     /**
00557      * Attach a user callback function pointer to call when the 1PPS signal activates.
00558      *
00559      * @code
00560      *     void myCallback(void) { ... }
00561      *
00562      *     GPS gps(NC, p9);
00563      *     Foo foo;
00564      *
00565      *     gps.attach_pps(&myCallback);
00566      *
00567      * @endcode
00568      *
00569      * @ingroup API
00570      * @param fptr Callback function pointer
00571      */
00572     void attach_pps(const Callback<void()> & func) {
00573         cb_pps = func;
00574     }
00575 
00576     //! A callback object for the 1PPS user API.
00577     Callback<void()> cb_pps;
00578 
00579     //! Attach a user callback function to the NMEA RMC message processed signal.
00580     /**
00581      * Attach a user callback object/method to call when an NMEA RMC packet has been processed.
00582      *
00583      * @code
00584      *     class FOO {
00585      *     public:
00586      *         void myCallback(void);
00587      *     };
00588      *
00589      *     GPS gps(NC, p9);
00590      *     Foo foo;
00591      *
00592      *     gps.attach_rmc(foo, &FOO::myCallback);
00593      *
00594      * @endcode
00595      *
00596      * @ingroup API
00597      * @param tptr pointer to the object to call the member function on
00598      * @param mptr pointer to the member function to be called
00599      */
00600     template<typename T>
00601     void attach_rmc(T* tptr, void (T::*mptr)(void)) {
00602         cb_rmc.attach(tptr, mptr);
00603     }
00604 
00605     //! Attach a user callback function to the NMEA RMC message processed signal.
00606     /**
00607      * Attach a user callback function pointer to call when an NMEA RMC packet has been processed.
00608      *
00609      * @code
00610      *     void myCallback(void) { ... }
00611      *
00612      *     GPS gps(NC, p9);
00613      *     Foo foo;
00614      *
00615      *     gps.attach_rmc(&myCallback);
00616      *
00617      * @endcode
00618      *
00619      * @ingroup API
00620      * @param fptr Callback function pointer.
00621      */
00622     void attach_rmc(const Callback<void()> & func) {
00623         cb_rmc = func;
00624     }
00625 
00626     //! A callback object for the NMEA RMS message processed signal user API.
00627     Callback<void()> cb_rmc;
00628 
00629     //! Attach a user callback function to the NMEA GGA message processed signal.
00630     /**
00631      * Attach a user callback object/method to call when an NMEA GGA packet has been processed.
00632      *
00633      * @code
00634      *     class FOO {
00635      *     public:
00636      *         void myCallback(void);
00637      *     };
00638      *
00639      *     GPS gps(NC, p9);
00640      *     Foo foo;
00641      *
00642      *     gps.attach_gga(foo, &FOO::myCallback);
00643      *
00644      * @endcode
00645      *
00646      * @ingroup API
00647      * @param tptr pointer to the object to call the member function on
00648      * @param mptr pointer to the member function to be called
00649      */
00650     template<typename T>
00651     void attach_gga(T* tptr, void (T::*mptr)(void)) {
00652         cb_gga.attach(tptr, mptr);
00653     }
00654 
00655     //! Attach a user callback function to the NMEA GGA message processed signal.
00656     /**
00657      * Attach a user callback function pointer to call when an NMEA GGA packet has been processed.
00658      *
00659      * @code
00660      *     void myCallback(void) { ... }
00661      *
00662      *     GPS gps(NC, p9);
00663      *     Foo foo;
00664      *
00665      *     gps.attach_gga(&myCallback);
00666      *
00667      * @endcode
00668      *
00669      * @ingroup API
00670      * @param fptr Callback function pointer.
00671      */
00672     void attach_gga(const Callback<void()> & func) {
00673         cb_gga = func;
00674     }
00675 
00676     //! A callback object for the NMEA GGA message processed signal user API.
00677     Callback<void()> cb_gga;
00678 
00679 
00680     //! Attach a user callback function to the NMEA VTG message processed signal.
00681     /**
00682      * Attach a user callback object/method to call when an NMEA VTG packet has been processed.
00683      *
00684      * @code
00685      *     class FOO {
00686      *     public:
00687      *         void myCallback(void);
00688      *     };
00689      *
00690      *     GPS gps(NC, p9);
00691      *     Foo foo;
00692      *
00693      *     gps.attach_vtg(foo, &FOO::myCallback);
00694      *
00695      * @endcode
00696      *
00697      * @ingroup API
00698      * @param tptr pointer to the object to call the member function on
00699      * @param mptr pointer to the member function to be called
00700      */
00701     template<typename T>
00702     void attach_vtg(T* tptr, void (T::*mptr)(void)) {
00703         cb_vtg.attach(tptr, mptr);
00704     }
00705 
00706     //! Attach a user callback function to the NMEA VTG message processed signal.
00707     /**
00708      * Attach a user callback function pointer to call when an NMEA VTG packet has been processed.
00709      *
00710      * @code
00711      *     void myCallback(void) { ... }
00712      *
00713      *     GPS gps(NC, p9);
00714      *     Foo foo;
00715      *
00716      *     gps.attach_vtg(&myCallback);
00717      *
00718      * @endcode
00719      *
00720      * @ingroup API
00721      * @param fptr Callback function pointer.
00722      */
00723     void attach_vtg(const Callback<void()> & func) {
00724         cb_vtg = func;
00725     }
00726 
00727     //! A callback object for the NMEA RMS message processed signal user API.
00728     Callback<void()> cb_vtg;
00729 
00730     //! Attach a user callback function to the unknown NMEA message.
00731     /**
00732      * Attach a user callback object/method to call when an unknown NMEA packet.
00733      *
00734      * @code
00735      *     class FOO {
00736      *     public:
00737      *         void myCallback(void);
00738      *     };
00739      *
00740      *     GPS gps(NC, p9);
00741      *     Foo foo;
00742      *
00743      *     gps.attach_ukn(foo, &FOO::myCallback);
00744      *
00745      * @endcode
00746      *
00747      * @ingroup API
00748      * @param tptr pointer to the object to call the member function on
00749      * @param mptr pointer to the member function to be called
00750      */
00751     template<typename T>
00752     void attach_ukn(T* tptr, void (T::*mptr)(void)) {
00753         cb_ukn.attach(tptr, mptr);
00754     }
00755 
00756     //! Attach a user callback function to the unknown NMEA message.
00757     /**
00758      * Attach a user callback function pointer to call when an unknown NMEA.
00759      *
00760      * @code
00761      *     void myCallback(void) { ... }
00762      *
00763      *     GPS gps(NC, p9);
00764      *     Foo foo;
00765      *
00766      *     gps.attach_ukn(&myCallback);
00767      *
00768      * @endcode
00769      *
00770      * @ingroup API
00771      * @param fptr Callback function pointer.
00772      */
00773     void attach_ukn(const Callback<void()> & func) {
00774         cb_ukn = func;
00775     }
00776 
00777     //! A callback object for the NMEA RMS message processed signal user API.
00778     Callback<void()> cb_ukn;
00779 
00780     /**
00781      * Set's the GGA string memory pointer.
00782      * @param s char pointer ti string.
00783      * @return char s passed in.
00784      */
00785     char * setGga(char *s) {
00786         _gga = s;
00787         return s;
00788     }
00789 
00790     /**
00791      * Set's the RMC string memory pointer.
00792      * @param s char pointer ti string.
00793      * @return char s passed in.
00794      */
00795     char * setRmc(char *s) {
00796         _rmc = s;
00797         return s;
00798     };
00799 
00800     /**
00801      * Set's the VTG string memory pointer.
00802      * @param s char pointer ti string.
00803      * @return char s passed in.
00804      */
00805     char * setVtg(char *s) {
00806         _vtg = s;
00807         return s;
00808     };
00809 
00810     /**
00811      * Set's the UKN string memory pointer.
00812      * @param s char pointer ti string.
00813      * @return char s passed in.
00814      */
00815     char * setUkn(char *s) {
00816         _ukn = s;
00817         return s;
00818     };
00819 
00820     //! Set the baud rate the GPS module is using.
00821     /**
00822      * Set the baud rate of the serial port
00823      *
00824      * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.baud
00825      *
00826      * @ingroup API
00827      * @param baudrate The baudrate to set.
00828      */
00829     void baud(int baudrate) {
00830         RawSerial::baud(baudrate);
00831     }
00832 
00833     //! Set the serial port format the GPS module is using.
00834     /**
00835      * Set the transmission format used by the Serial port
00836      *
00837      * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format
00838      *
00839      * @ingroup API
00840      * @param bits - The number of bits in a word (5-8; default = 8)
00841      * @param parity - The parity used (GPS::None, GPS::Odd, GPS::Even, GPS::Forced1, GPS::Forced0; default = GPS::None)
00842      * @param stop_bits - The number of stop bits (1 or 2; default = 1)
00843      */
00844     void format(int bits, Parity parity, int stop_bits) {
00845         RawSerial::format(bits, parity, stop_bits);
00846     }
00847 
00848     //! Send incoming GPS bytes to Uart0
00849     /**
00850      * Send incoming GPS bytes to Uart0
00851      *
00852      * This can be useful for printing out the bytes from the GPS onto
00853      * a the common debug port Uart0. Note, Uart0 should have been setup
00854      * and initialised before switching this on. Also, realistically,
00855      * you should ensure Uart0 has a higher baud rate than that being
00856      * used by the GPS. Sending of bytes to Uart0 is "raw" and should
00857      * only be used to initially gather data and should NOT be used as
00858      * part of the application design. If you need to forward on the
00859      * data you should come up with a proper strategy.
00860      *
00861      * @ingroup API
00862      * @param b - True to send to Uart0, false otherwise
00863      */
00864     void NmeaOnUart0(bool b) {
00865         _nmeaOnUart0 = b;
00866     }
00867 
00868 protected:
00869 
00870     //! Flag set true when a GPS PPS has been attached to a pin.
00871     bool _ppsInUse;
00872 
00873     //! An InterruptIn object to "trigger" on the PPS edge.
00874     InterruptIn * _pps;
00875 
00876     //! A Ticker object called every 10ms.
00877     Ticker * _second100;
00878 
00879     //! A GPS_Time object used to hold the last parsed time/date data.
00880     GPS_Time theTime;
00881 
00882     //! A GPS_Geodetic object used to hold the last parsed positional data.
00883     GPS_Geodetic thePlace;
00884 
00885     //! A GPS_VTG object used to hold vector data.
00886     GPS_VTG theVTG;
00887 
00888     //! Used to record the previous byte received.
00889     char _lastByte;
00890 
00891     char * _gga;
00892     char * _rmc;
00893     char * _vtg;
00894     char * _ukn;
00895 
00896     //! Used for debugging.
00897     bool _nmeaOnUart0;
00898 };
00899 
00900 #endif
00901