Fixed compiler errors/warnings (declaration of _uidx, scope of index variables i)

Dependents:   GPSDevice LogData_UM6-to-SDcard UM6withGPS mbed-cansat-test-GPS ... more

Fork of MODGPS by Andy K

Revision:
0:db98027c0bbb
Child:
1:6aec92e77ad2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS.h	Mon Nov 15 20:11:16 2010 +0000
@@ -0,0 +1,631 @@
+/*
+    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
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+#ifndef GPS_H
+#define GPS_H
+
+#include "mbed.h"
+#include "GPS_Time.h"
+#include "GPS_Geodetic.h"
+
+#define GPS_RBR  0x00
+#define GPS_THR  0x00
+#define GPS_DLL  0x00
+#define GPS_IER  0x04
+#define GPS_DML  0x04
+#define GPS_IIR  0x08
+#define GPS_FCR  0x08
+#define GPS_LCR  0x0C
+#define GPS_LSR  0x14
+#define GPS_SCR  0x1C
+#define GPS_ACR  0x20
+#define GPS_ICR  0x24
+#define GPS_FDR  0x28
+#define GPS_TER  0x30
+
+#define GPS_BUFFER_LEN  128
+#define GPS_TICKTOCK    10000
+
+/** @defgroup API */
+
+/** GPS module
+ *
+ * @see http://mbed.org/cookbook/MODGPS
+ * @see example1.cpp
+ * @see example2.cpp
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "GPS.h"
+ *
+ * DigitalOut led1(LED1);
+ * Serial pc(USBTX, USBRX);
+ * GPS gps(NC, p10); 
+ *
+ * int main() {
+ *     GPS_Time t;
+ *
+ *     // Wait for the GPS NMEA data to become valid.
+ *     while (!gps.isTimeValid()) {
+ *       led1 = !led1;
+ *       wait(1);
+ *     }
+ *
+ *     gps.timeNow(&t);
+ *
+ *     pc.printf("The time/date is %02d:%02d:%02d %02d/%02d/%04d\r\n",
+ *        t.hour, t.minute, t.second, t.day, t.month, t.year);
+ *
+ *     // Wait until at least four satellites produce a position fix and a valid quality.
+ *     while (gps.numOfSats() < 4 && gps.getGPSquality != 0) {
+ *       led1 = !led1;
+ *       wait(1);
+ *     }
+ *
+ *     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 {
+public:
+    
+    //! The PPS edge type to interrupt on.
+    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.
+     *
+     * @param tx Usually unused and set to NC
+     * @param rx The RX pin the GPS is connected to, p10, p14( OR p25), p27.
+     * @param name An option name for RPC usage.
+     */
+    GPS(PinName tx, PinName rx, const char *name = NULL);
+
+    //! Is the time reported by the GPS valid.
+    /**
+     * Method used to check the validity of the time the GPS module is reporting.
+     *
+     * @code
+     *     // Assuming we have a GPS object previously created...
+     *     GPS gps(NC, p9); 
+     *
+     *     if (gps.isTimeValid()) {
+     *         // Time is valid :)
+     *     }
+     *     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; }
+    
+    //! 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 
+     * description for more details
+     *
+     * @return int 0 on no fix, 1... (see NMEA GGA for more details).
+     */
+    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); 
+     *
+     *     int sats = gps.numOfSats();
+     *     
+     * @endcode
+     *
+     * @ingroup API
+     * @return int The number of satellites.
+     */
+    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); 
+     *
+     *     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); 
+     *
+     *     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); 
+     *
+     *     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); 
+     *
+     *     double height = gps.height();
+     *     
+     * @endcode
+     *
+     * Note, this is identical to altitude()
+     * @see altitude()
+     *
+     * @ingroup API
+     * @return double Kilometers
+     */
+    double height(void) { return altitude(); }
+    
+    //! Get all three geodetic parameters together.
+    /**
+     * Pass a pointer to a GPS_Geodetic object and the current
+     * GPS data will be copied into it.
+     *
+     * @code
+     *     // Assuming we have a GPS object previously created...
+     *     GPS gps(NC, p9); 
+     *
+     *     // Then get the data...
+     *     GPS_Geodetic p;
+     *     gps.geodetic(&p);
+     *     printf("Latitude  = %.4f", p.lat);
+     *     printf("Longitude = %.4f", p.lon);
+     *     printf("Altitude  = %.4f", p.alt);
+     *
+     * @endcode
+     *
+     * @ingroup API
+     * @param g A GSP_Geodetic pointer to an existing GPS_Geodetic object.
+     * @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); 
+     *
+     *     // Then get the data...
+     *     GPS_Geodetic *p = gps.geodetic();
+     *     printf("Latitude = %.4f", p->lat);
+     *     delete(p); // then remember to delete the object to prevent memory leaks.
+     *
+     * @endcode
+     *
+     * @ingroup API
+     * @return GPS_Geodetic * A pointer to the data.
+     */
+    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
+     * time and date as reported by the GPS.
+     *
+     * @code
+     *     // Assuming we have a GPS object previously created...
+     *     GPS gps(NC, p9); 
+     *
+     *     // Then get the data...
+     *     GPS_Time t;
+     *     gps.timeNow(&t);
+     *     printf("Year = %d", t.year);
+     *
+     * @endcode
+     *
+     * @ingroup API
+     * @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); }
+    
+    //! Take a snap shot of the current time.
+    /**
+     * Pass a pointer to a GPS_Time object to get a copy of the current
+     * time and date as reported by the GPS.
+     *
+     * @code
+     *     // Assuming we have a GPS object previously created...
+     *     GPS gps(NC, p9); 
+     *
+     *     // Then get the data...
+     *     GPS_Time *t = gps.timeNow();
+     *     printf("Year = %d", t->year);
+     *     delete(t); // Avoid memory leaks.
+     *
+     * @endcode
+     *
+     * @ingroup API
+     * @return GPS_Time * The pointer passed in.
+     */
+    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); 
+     *
+     *     // Then get the Julain Day Number.
+     *     double julianDayNumber = gps.julianDayNumber();
+     *
+     * @endcode
+     *
+     * @ingroup API
+     * @return double The Julian Date as a double.
+     */
+    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); 
+     *
+     *     // Then get the Julian Date.
+     *     double julianDate = gps.julianDate();
+     *
+     * @endcode
+     *
+     * @ingroup API
+     * @return double The Julian Date as a double.
+     */
+    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); 
+     *     double sidereal = gps.siderealDegrees();
+     *
+     * @endcode
+     *
+     * @ingroup API
+     * @return double Sidereal degree angle..
+     */
+    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); 
+     *     double sidereal = gps.siderealHA();
+     *
+     * @endcode
+     *
+     * @ingroup API
+     * @return double Sidereal degree angle..
+     */
+    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
+     * connect that to our internal ISR. Using the 1PPS increases
+     * the GPS_Time time accuracy from +/-0.25s to +/-0.001s
+     *
+     * @code
+     *     // Assuming we have a GPS object previously created...
+     *     GPS gps(NC, p9); 
+     *
+     *     gps.ppsAttach(p29); // default to GPS::ppsRise, rising edge. 
+     *
+     *     // Or...
+     *     gps.ppsAttach(p29, GPS::ppsRise); // The default.
+     *
+     *     // Or...
+     *     gps.ppsAttach(p29, GPS::ppsFall); // If a falling edge.
+     *
+     * @endcode
+     *
+     * <b>Note</b>, before using this function you should attach an actual
+     * callback function using attach_pps()
+     *
+     * @see attach_pps()
+     *
+     * @ingroup API
+     * @param irq A PinName to attach
+     * @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);    
+    
+    //! 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. 
+     *
+     * @code
+     *     class FOO {
+     *     public:
+     *         void myCallback(void);
+     *     };
+     *
+     *     GPS gps(NC, p9); 
+     *     Foo foo;
+     *
+     *     gps.attach_pps(foo, &FOO::myCallback);
+     * 
+     * @endcode
+     *
+     * @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_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. 
+     *
+     * @code
+     *     void myCallback(void) { ... }
+     *
+     *     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); } 
+    
+    //! A callback object for the 1PPS user API.
+    FunctionPointer 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. 
+     *
+     * @code
+     *     class FOO {
+     *     public:
+     *         void myCallback(void);
+     *     };
+     *
+     *     GPS gps(NC, p9); 
+     *     Foo foo;
+     *
+     *     gps.attach_rmc(foo, &FOO::myCallback);
+     * 
+     * @endcode
+     *
+     * @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); }
+    
+    //! 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. 
+     *
+     * @code
+     *     void myCallback(void) { ... }
+     *
+     *     GPS gps(NC, p9); 
+     *     Foo foo;
+     *
+     *     gps.attach_rmc(&myCallback);
+     * 
+     * @endcode
+     *
+     * @ingroup API 
+     * @param fptr Callback function pointer.
+     */
+    void attach_rmc(void (*fptr)(void)) { cb_rmc.attach(fptr); } 
+    
+    //! A callback object for the NMEA RMS message processed signal user API.
+    FunctionPointer 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. 
+     *
+     * @code
+     *     class FOO {
+     *     public:
+     *         void myCallback(void);
+     *     };
+     *
+     *     GPS gps(NC, p9); 
+     *     Foo foo;
+     *
+     *     gps.attach_gga(foo, &FOO::myCallback);
+     * 
+     * @endcode
+     *
+     * @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); }
+    
+    //! 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. 
+     *
+     * @code
+     *     void myCallback(void) { ... }
+     *
+     *     GPS gps(NC, p9); 
+     *     Foo foo;
+     *
+     *     gps.attach_gga(&myCallback);
+     * 
+     * @endcode
+     *
+     * @ingroup API 
+     * @param fptr Callback function pointer.
+     */
+    void attach_gga(void (*fptr)(void)) { cb_gga.attach(fptr); } 
+    
+    //! A callback object for the NMEA GGA message processed signal user API.
+    FunctionPointer cb_gga;
+
+    //! 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 
+     * @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); }
+    
+protected:
+
+    //! Flag set true when a GPS PPS has been attached to a pin.
+    bool         _ppsInUse;
+    
+    //! An InterruptIn object to "trigger" on the PPS edge.
+    InterruptIn *_pps;
+    
+    //! A Ticker object called every 10ms.
+    Ticker      *_second100;
+    
+    //! A GPS_Time object used to hold the last parsed time/date data.
+    GPS_Time     theTime;
+    
+    //! A GPS_Geodetic object used to hold the last parsed positional data.
+    GPS_Geodetic thePlace;        
+};
+
+#endif
+