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

Committer:
AjK
Date:
Mon Nov 15 20:11:16 2010 +0000
Revision:
0:db98027c0bbb
Child:
1:6aec92e77ad2
1.8

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 0:db98027c0bbb 1 /*
AjK 0:db98027c0bbb 2 Copyright (c) 2010 Andy Kirkham
AjK 0:db98027c0bbb 3
AjK 0:db98027c0bbb 4 Permission is hereby granted, free of charge, to any person obtaining a copy
AjK 0:db98027c0bbb 5 of this software and associated documentation files (the "Software"), to deal
AjK 0:db98027c0bbb 6 in the Software without restriction, including without limitation the rights
AjK 0:db98027c0bbb 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
AjK 0:db98027c0bbb 8 copies of the Software, and to permit persons to whom the Software is
AjK 0:db98027c0bbb 9 furnished to do so, subject to the following conditions:
AjK 0:db98027c0bbb 10
AjK 0:db98027c0bbb 11 The above copyright notice and this permission notice shall be included in
AjK 0:db98027c0bbb 12 all copies or substantial portions of the Software.
AjK 0:db98027c0bbb 13
AjK 0:db98027c0bbb 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
AjK 0:db98027c0bbb 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
AjK 0:db98027c0bbb 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AjK 0:db98027c0bbb 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
AjK 0:db98027c0bbb 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
AjK 0:db98027c0bbb 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
AjK 0:db98027c0bbb 20 THE SOFTWARE.
AjK 0:db98027c0bbb 21 */
AjK 0:db98027c0bbb 22
AjK 0:db98027c0bbb 23 #ifndef GPS_H
AjK 0:db98027c0bbb 24 #define GPS_H
AjK 0:db98027c0bbb 25
AjK 0:db98027c0bbb 26 #include "mbed.h"
AjK 0:db98027c0bbb 27 #include "GPS_Time.h"
AjK 0:db98027c0bbb 28 #include "GPS_Geodetic.h"
AjK 0:db98027c0bbb 29
AjK 0:db98027c0bbb 30 #define GPS_RBR 0x00
AjK 0:db98027c0bbb 31 #define GPS_THR 0x00
AjK 0:db98027c0bbb 32 #define GPS_DLL 0x00
AjK 0:db98027c0bbb 33 #define GPS_IER 0x04
AjK 0:db98027c0bbb 34 #define GPS_DML 0x04
AjK 0:db98027c0bbb 35 #define GPS_IIR 0x08
AjK 0:db98027c0bbb 36 #define GPS_FCR 0x08
AjK 0:db98027c0bbb 37 #define GPS_LCR 0x0C
AjK 0:db98027c0bbb 38 #define GPS_LSR 0x14
AjK 0:db98027c0bbb 39 #define GPS_SCR 0x1C
AjK 0:db98027c0bbb 40 #define GPS_ACR 0x20
AjK 0:db98027c0bbb 41 #define GPS_ICR 0x24
AjK 0:db98027c0bbb 42 #define GPS_FDR 0x28
AjK 0:db98027c0bbb 43 #define GPS_TER 0x30
AjK 0:db98027c0bbb 44
AjK 0:db98027c0bbb 45 #define GPS_BUFFER_LEN 128
AjK 0:db98027c0bbb 46 #define GPS_TICKTOCK 10000
AjK 0:db98027c0bbb 47
AjK 0:db98027c0bbb 48 /** @defgroup API */
AjK 0:db98027c0bbb 49
AjK 0:db98027c0bbb 50 /** GPS module
AjK 0:db98027c0bbb 51 *
AjK 0:db98027c0bbb 52 * @see http://mbed.org/cookbook/MODGPS
AjK 0:db98027c0bbb 53 * @see example1.cpp
AjK 0:db98027c0bbb 54 * @see example2.cpp
AjK 0:db98027c0bbb 55 *
AjK 0:db98027c0bbb 56 * Example:
AjK 0:db98027c0bbb 57 * @code
AjK 0:db98027c0bbb 58 * #include "mbed.h"
AjK 0:db98027c0bbb 59 * #include "GPS.h"
AjK 0:db98027c0bbb 60 *
AjK 0:db98027c0bbb 61 * DigitalOut led1(LED1);
AjK 0:db98027c0bbb 62 * Serial pc(USBTX, USBRX);
AjK 0:db98027c0bbb 63 * GPS gps(NC, p10);
AjK 0:db98027c0bbb 64 *
AjK 0:db98027c0bbb 65 * int main() {
AjK 0:db98027c0bbb 66 * GPS_Time t;
AjK 0:db98027c0bbb 67 *
AjK 0:db98027c0bbb 68 * // Wait for the GPS NMEA data to become valid.
AjK 0:db98027c0bbb 69 * while (!gps.isTimeValid()) {
AjK 0:db98027c0bbb 70 * led1 = !led1;
AjK 0:db98027c0bbb 71 * wait(1);
AjK 0:db98027c0bbb 72 * }
AjK 0:db98027c0bbb 73 *
AjK 0:db98027c0bbb 74 * gps.timeNow(&t);
AjK 0:db98027c0bbb 75 *
AjK 0:db98027c0bbb 76 * pc.printf("The time/date is %02d:%02d:%02d %02d/%02d/%04d\r\n",
AjK 0:db98027c0bbb 77 * t.hour, t.minute, t.second, t.day, t.month, t.year);
AjK 0:db98027c0bbb 78 *
AjK 0:db98027c0bbb 79 * // Wait until at least four satellites produce a position fix and a valid quality.
AjK 0:db98027c0bbb 80 * while (gps.numOfSats() < 4 && gps.getGPSquality != 0) {
AjK 0:db98027c0bbb 81 * led1 = !led1;
AjK 0:db98027c0bbb 82 * wait(1);
AjK 0:db98027c0bbb 83 * }
AjK 0:db98027c0bbb 84 *
AjK 0:db98027c0bbb 85 * pc.printf("Lat = %.4f Lon = %.4f Alt = %.1fkm\r\n",
AjK 0:db98027c0bbb 86 * gps.latitude(), gps.longitude, gps.altitude());
AjK 0:db98027c0bbb 87 *
AjK 0:db98027c0bbb 88 * // Make the LED go steady to indicate we have finished.
AjK 0:db98027c0bbb 89 * led1 = 1;
AjK 0:db98027c0bbb 90 *
AjK 0:db98027c0bbb 91 * while(1) {}
AjK 0:db98027c0bbb 92 * }
AjK 0:db98027c0bbb 93 * @endcode
AjK 0:db98027c0bbb 94 *
AjK 0:db98027c0bbb 95 */
AjK 0:db98027c0bbb 96
AjK 0:db98027c0bbb 97 class GPS : Serial {
AjK 0:db98027c0bbb 98 public:
AjK 0:db98027c0bbb 99
AjK 0:db98027c0bbb 100 //! The PPS edge type to interrupt on.
AjK 0:db98027c0bbb 101 enum ppsEdgeType {
AjK 0:db98027c0bbb 102 ppsRise = 0, /*!< Use the rising edge (default). */
AjK 0:db98027c0bbb 103 ppsFall /*!< Use the falling edge. */
AjK 0:db98027c0bbb 104 };
AjK 0:db98027c0bbb 105
AjK 0:db98027c0bbb 106 //! A copy of the Serial parity enum
AjK 0:db98027c0bbb 107 enum Parity {
AjK 0:db98027c0bbb 108 None = 0
AjK 0:db98027c0bbb 109 , Odd
AjK 0:db98027c0bbb 110 , Even
AjK 0:db98027c0bbb 111 , Forced1
AjK 0:db98027c0bbb 112 , Forced0
AjK 0:db98027c0bbb 113 };
AjK 0:db98027c0bbb 114
AjK 0:db98027c0bbb 115 //! GPS constructor.
AjK 0:db98027c0bbb 116 /**
AjK 0:db98027c0bbb 117 * The GPS constructor is used to initialise the GPS object.
AjK 0:db98027c0bbb 118 *
AjK 0:db98027c0bbb 119 * @param tx Usually unused and set to NC
AjK 0:db98027c0bbb 120 * @param rx The RX pin the GPS is connected to, p10, p14( OR p25), p27.
AjK 0:db98027c0bbb 121 * @param name An option name for RPC usage.
AjK 0:db98027c0bbb 122 */
AjK 0:db98027c0bbb 123 GPS(PinName tx, PinName rx, const char *name = NULL);
AjK 0:db98027c0bbb 124
AjK 0:db98027c0bbb 125 //! Is the time reported by the GPS valid.
AjK 0:db98027c0bbb 126 /**
AjK 0:db98027c0bbb 127 * Method used to check the validity of the time the GPS module is reporting.
AjK 0:db98027c0bbb 128 *
AjK 0:db98027c0bbb 129 * @code
AjK 0:db98027c0bbb 130 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 131 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 132 *
AjK 0:db98027c0bbb 133 * if (gps.isTimeValid()) {
AjK 0:db98027c0bbb 134 * // Time is valid :)
AjK 0:db98027c0bbb 135 * }
AjK 0:db98027c0bbb 136 * else {
AjK 0:db98027c0bbb 137 * // Doh, time is not valid :(
AjK 0:db98027c0bbb 138 * )
AjK 0:db98027c0bbb 139 *
AjK 0:db98027c0bbb 140 * @endcode
AjK 0:db98027c0bbb 141 *
AjK 0:db98027c0bbb 142 * @ingroup API
AjK 0:db98027c0bbb 143 * @return bool true if valid, false otherwise
AjK 0:db98027c0bbb 144 */
AjK 0:db98027c0bbb 145 bool isTimeValid(void) { return theTime.status == 'V' ? false : true; }
AjK 0:db98027c0bbb 146
AjK 0:db98027c0bbb 147 //! Is the positional fix reported by the GPS valid.
AjK 0:db98027c0bbb 148 /**
AjK 0:db98027c0bbb 149 * Method used to check the validity of the positional data. This method
AjK 0:db98027c0bbb 150 * returns the GGA field, 0 is "bad, 1 is "ok", etc. See the NMEA GGA
AjK 0:db98027c0bbb 151 * description for more details
AjK 0:db98027c0bbb 152 *
AjK 0:db98027c0bbb 153 * @return int 0 on no fix, 1... (see NMEA GGA for more details).
AjK 0:db98027c0bbb 154 */
AjK 0:db98027c0bbb 155 int getGPSquality(void) { return thePlace.getGPSquality(); }
AjK 0:db98027c0bbb 156
AjK 0:db98027c0bbb 157 //! How many satellites were used in the last fix.
AjK 0:db98027c0bbb 158 /**
AjK 0:db98027c0bbb 159 * Method returns the number of GPS satellites used on the last fix.
AjK 0:db98027c0bbb 160 *
AjK 0:db98027c0bbb 161 * @code
AjK 0:db98027c0bbb 162 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 163 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 164 *
AjK 0:db98027c0bbb 165 * int sats = gps.numOfSats();
AjK 0:db98027c0bbb 166 *
AjK 0:db98027c0bbb 167 * @endcode
AjK 0:db98027c0bbb 168 *
AjK 0:db98027c0bbb 169 * @ingroup API
AjK 0:db98027c0bbb 170 * @return int The number of satellites.
AjK 0:db98027c0bbb 171 */
AjK 0:db98027c0bbb 172 int numOfSats(void) { return thePlace.numOfSats(); }
AjK 0:db98027c0bbb 173
AjK 0:db98027c0bbb 174 //! What was the last reported latitude (in degrees)
AjK 0:db98027c0bbb 175 /**
AjK 0:db98027c0bbb 176 * Method returns a double in degrees, positive being North, negative being South.
AjK 0:db98027c0bbb 177 *
AjK 0:db98027c0bbb 178 * @code
AjK 0:db98027c0bbb 179 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 180 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 181 *
AjK 0:db98027c0bbb 182 * double latitude = gps.latitude();
AjK 0:db98027c0bbb 183 *
AjK 0:db98027c0bbb 184 * @endcode
AjK 0:db98027c0bbb 185 *
AjK 0:db98027c0bbb 186 * @ingroup API
AjK 0:db98027c0bbb 187 * @return double Degrees
AjK 0:db98027c0bbb 188 */
AjK 0:db98027c0bbb 189 double latitude(void);
AjK 0:db98027c0bbb 190
AjK 0:db98027c0bbb 191 //! What was the last reported longitude (in degrees)
AjK 0:db98027c0bbb 192 /**
AjK 0:db98027c0bbb 193 * Method returns a double in degrees, positive being East, negative being West.
AjK 0:db98027c0bbb 194 *
AjK 0:db98027c0bbb 195 * @code
AjK 0:db98027c0bbb 196 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 197 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 198 *
AjK 0:db98027c0bbb 199 * double logitude = gps.logitude();
AjK 0:db98027c0bbb 200 *
AjK 0:db98027c0bbb 201 * @endcode
AjK 0:db98027c0bbb 202 *
AjK 0:db98027c0bbb 203 * @ingroup API
AjK 0:db98027c0bbb 204 * @return double Degrees
AjK 0:db98027c0bbb 205 */
AjK 0:db98027c0bbb 206 double longitude(void);
AjK 0:db98027c0bbb 207
AjK 0:db98027c0bbb 208 //! What was the last reported altitude (in kilometers)
AjK 0:db98027c0bbb 209 /**
AjK 0:db98027c0bbb 210 * Method returns a double in kilometers.
AjK 0:db98027c0bbb 211 *
AjK 0:db98027c0bbb 212 * @code
AjK 0:db98027c0bbb 213 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 214 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 215 *
AjK 0:db98027c0bbb 216 * double altitude = gps.altitude();
AjK 0:db98027c0bbb 217 *
AjK 0:db98027c0bbb 218 * @endcode
AjK 0:db98027c0bbb 219 *
AjK 0:db98027c0bbb 220 * @ingroup API
AjK 0:db98027c0bbb 221 * @return double Kilometers
AjK 0:db98027c0bbb 222 */
AjK 0:db98027c0bbb 223 double altitude(void);
AjK 0:db98027c0bbb 224
AjK 0:db98027c0bbb 225 //! What was the last reported altitude/height (in kilometers)
AjK 0:db98027c0bbb 226 /**
AjK 0:db98027c0bbb 227 * @see altitude()
AjK 0:db98027c0bbb 228 *
AjK 0:db98027c0bbb 229 * @code
AjK 0:db98027c0bbb 230 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 231 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 232 *
AjK 0:db98027c0bbb 233 * double height = gps.height();
AjK 0:db98027c0bbb 234 *
AjK 0:db98027c0bbb 235 * @endcode
AjK 0:db98027c0bbb 236 *
AjK 0:db98027c0bbb 237 * Note, this is identical to altitude()
AjK 0:db98027c0bbb 238 * @see altitude()
AjK 0:db98027c0bbb 239 *
AjK 0:db98027c0bbb 240 * @ingroup API
AjK 0:db98027c0bbb 241 * @return double Kilometers
AjK 0:db98027c0bbb 242 */
AjK 0:db98027c0bbb 243 double height(void) { return altitude(); }
AjK 0:db98027c0bbb 244
AjK 0:db98027c0bbb 245 //! Get all three geodetic parameters together.
AjK 0:db98027c0bbb 246 /**
AjK 0:db98027c0bbb 247 * Pass a pointer to a GPS_Geodetic object and the current
AjK 0:db98027c0bbb 248 * GPS data will be copied into it.
AjK 0:db98027c0bbb 249 *
AjK 0:db98027c0bbb 250 * @code
AjK 0:db98027c0bbb 251 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 252 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 253 *
AjK 0:db98027c0bbb 254 * // Then get the data...
AjK 0:db98027c0bbb 255 * GPS_Geodetic p;
AjK 0:db98027c0bbb 256 * gps.geodetic(&p);
AjK 0:db98027c0bbb 257 * printf("Latitude = %.4f", p.lat);
AjK 0:db98027c0bbb 258 * printf("Longitude = %.4f", p.lon);
AjK 0:db98027c0bbb 259 * printf("Altitude = %.4f", p.alt);
AjK 0:db98027c0bbb 260 *
AjK 0:db98027c0bbb 261 * @endcode
AjK 0:db98027c0bbb 262 *
AjK 0:db98027c0bbb 263 * @ingroup API
AjK 0:db98027c0bbb 264 * @param g A GSP_Geodetic pointer to an existing GPS_Geodetic object.
AjK 0:db98027c0bbb 265 * @return GPS_Geodetic * The pointer passed in.
AjK 0:db98027c0bbb 266 */
AjK 0:db98027c0bbb 267 GPS_Geodetic *geodetic(GPS_Geodetic *g);
AjK 0:db98027c0bbb 268
AjK 0:db98027c0bbb 269 //! Get all three geodetic parameters together.
AjK 0:db98027c0bbb 270 /**
AjK 0:db98027c0bbb 271 * Get all the geodetic data at once. For example:-
AjK 0:db98027c0bbb 272 *
AjK 0:db98027c0bbb 273 * @code
AjK 0:db98027c0bbb 274 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 275 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 276 *
AjK 0:db98027c0bbb 277 * // Then get the data...
AjK 0:db98027c0bbb 278 * GPS_Geodetic *p = gps.geodetic();
AjK 0:db98027c0bbb 279 * printf("Latitude = %.4f", p->lat);
AjK 0:db98027c0bbb 280 * delete(p); // then remember to delete the object to prevent memory leaks.
AjK 0:db98027c0bbb 281 *
AjK 0:db98027c0bbb 282 * @endcode
AjK 0:db98027c0bbb 283 *
AjK 0:db98027c0bbb 284 * @ingroup API
AjK 0:db98027c0bbb 285 * @return GPS_Geodetic * A pointer to the data.
AjK 0:db98027c0bbb 286 */
AjK 0:db98027c0bbb 287 GPS_Geodetic *geodetic(void) { return geodetic(NULL); }
AjK 0:db98027c0bbb 288
AjK 0:db98027c0bbb 289 //! Take a snap shot of the current time.
AjK 0:db98027c0bbb 290 /**
AjK 0:db98027c0bbb 291 * Pass a pointer to a GPS_Time object to get a copy of the current
AjK 0:db98027c0bbb 292 * time and date as reported by the GPS.
AjK 0:db98027c0bbb 293 *
AjK 0:db98027c0bbb 294 * @code
AjK 0:db98027c0bbb 295 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 296 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 297 *
AjK 0:db98027c0bbb 298 * // Then get the data...
AjK 0:db98027c0bbb 299 * GPS_Time t;
AjK 0:db98027c0bbb 300 * gps.timeNow(&t);
AjK 0:db98027c0bbb 301 * printf("Year = %d", t.year);
AjK 0:db98027c0bbb 302 *
AjK 0:db98027c0bbb 303 * @endcode
AjK 0:db98027c0bbb 304 *
AjK 0:db98027c0bbb 305 * @ingroup API
AjK 0:db98027c0bbb 306 * @param n A GPS_Time * pointer to an existing GPS_Time object.
AjK 0:db98027c0bbb 307 * @return GPS_Time * The pointer passed in.
AjK 0:db98027c0bbb 308 */
AjK 0:db98027c0bbb 309 GPS_Time * timeNow(GPS_Time *n) { return theTime.timeNow(n); }
AjK 0:db98027c0bbb 310
AjK 0:db98027c0bbb 311 //! Take a snap shot of the current time.
AjK 0:db98027c0bbb 312 /**
AjK 0:db98027c0bbb 313 * Pass a pointer to a GPS_Time object to get a copy of the current
AjK 0:db98027c0bbb 314 * time and date as reported by the GPS.
AjK 0:db98027c0bbb 315 *
AjK 0:db98027c0bbb 316 * @code
AjK 0:db98027c0bbb 317 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 318 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 319 *
AjK 0:db98027c0bbb 320 * // Then get the data...
AjK 0:db98027c0bbb 321 * GPS_Time *t = gps.timeNow();
AjK 0:db98027c0bbb 322 * printf("Year = %d", t->year);
AjK 0:db98027c0bbb 323 * delete(t); // Avoid memory leaks.
AjK 0:db98027c0bbb 324 *
AjK 0:db98027c0bbb 325 * @endcode
AjK 0:db98027c0bbb 326 *
AjK 0:db98027c0bbb 327 * @ingroup API
AjK 0:db98027c0bbb 328 * @return GPS_Time * The pointer passed in.
AjK 0:db98027c0bbb 329 */
AjK 0:db98027c0bbb 330 GPS_Time * timeNow(void) { GPS_Time *n = new GPS_Time; return theTime.timeNow(n); }
AjK 0:db98027c0bbb 331
AjK 0:db98027c0bbb 332 //! Return the curent day.
AjK 0:db98027c0bbb 333 /**
AjK 0:db98027c0bbb 334 * @code
AjK 0:db98027c0bbb 335 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 336 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 337 *
AjK 0:db98027c0bbb 338 * // Then get the Julain Day Number.
AjK 0:db98027c0bbb 339 * double julianDayNumber = gps.julianDayNumber();
AjK 0:db98027c0bbb 340 *
AjK 0:db98027c0bbb 341 * @endcode
AjK 0:db98027c0bbb 342 *
AjK 0:db98027c0bbb 343 * @ingroup API
AjK 0:db98027c0bbb 344 * @return double The Julian Date as a double.
AjK 0:db98027c0bbb 345 */
AjK 0:db98027c0bbb 346 double julianDayNumber(void) { return theTime.julian_day_number(); }
AjK 0:db98027c0bbb 347
AjK 0:db98027c0bbb 348 //! Return the curent date/time as a Julian date
AjK 0:db98027c0bbb 349 /**
AjK 0:db98027c0bbb 350 * @code
AjK 0:db98027c0bbb 351 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 352 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 353 *
AjK 0:db98027c0bbb 354 * // Then get the Julian Date.
AjK 0:db98027c0bbb 355 * double julianDate = gps.julianDate();
AjK 0:db98027c0bbb 356 *
AjK 0:db98027c0bbb 357 * @endcode
AjK 0:db98027c0bbb 358 *
AjK 0:db98027c0bbb 359 * @ingroup API
AjK 0:db98027c0bbb 360 * @return double The Julian Date as a double.
AjK 0:db98027c0bbb 361 */
AjK 0:db98027c0bbb 362 double julianDate(void) { return theTime.julian_date(); }
AjK 0:db98027c0bbb 363
AjK 0:db98027c0bbb 364 //! Get the current sidereal degree angle.
AjK 0:db98027c0bbb 365 /**
AjK 0:db98027c0bbb 366 * @code
AjK 0:db98027c0bbb 367 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 368 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 369 * double sidereal = gps.siderealDegrees();
AjK 0:db98027c0bbb 370 *
AjK 0:db98027c0bbb 371 * @endcode
AjK 0:db98027c0bbb 372 *
AjK 0:db98027c0bbb 373 * @ingroup API
AjK 0:db98027c0bbb 374 * @return double Sidereal degree angle..
AjK 0:db98027c0bbb 375 */
AjK 0:db98027c0bbb 376 double siderealDegrees(void) { return theTime.siderealDegrees(&theTime, longitude()); }
AjK 0:db98027c0bbb 377
AjK 0:db98027c0bbb 378 //! Get the current sidereal hour angle.
AjK 0:db98027c0bbb 379 /**
AjK 0:db98027c0bbb 380 * @code
AjK 0:db98027c0bbb 381 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 382 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 383 * double sidereal = gps.siderealHA();
AjK 0:db98027c0bbb 384 *
AjK 0:db98027c0bbb 385 * @endcode
AjK 0:db98027c0bbb 386 *
AjK 0:db98027c0bbb 387 * @ingroup API
AjK 0:db98027c0bbb 388 * @return double Sidereal degree angle..
AjK 0:db98027c0bbb 389 */
AjK 0:db98027c0bbb 390 double siderealHA(void) { return theTime.siderealHA(&theTime, longitude()); }
AjK 0:db98027c0bbb 391
AjK 0:db98027c0bbb 392 //! Optionally, connect a 1PPS single to an Mbed pin.
AjK 0:db98027c0bbb 393 /**
AjK 0:db98027c0bbb 394 * Optional: If the GPS unit has a 1PPS output, use this to
AjK 0:db98027c0bbb 395 * connect that to our internal ISR. Using the 1PPS increases
AjK 0:db98027c0bbb 396 * the GPS_Time time accuracy from +/-0.25s to +/-0.001s
AjK 0:db98027c0bbb 397 *
AjK 0:db98027c0bbb 398 * @code
AjK 0:db98027c0bbb 399 * // Assuming we have a GPS object previously created...
AjK 0:db98027c0bbb 400 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 401 *
AjK 0:db98027c0bbb 402 * gps.ppsAttach(p29); // default to GPS::ppsRise, rising edge.
AjK 0:db98027c0bbb 403 *
AjK 0:db98027c0bbb 404 * // Or...
AjK 0:db98027c0bbb 405 * gps.ppsAttach(p29, GPS::ppsRise); // The default.
AjK 0:db98027c0bbb 406 *
AjK 0:db98027c0bbb 407 * // Or...
AjK 0:db98027c0bbb 408 * gps.ppsAttach(p29, GPS::ppsFall); // If a falling edge.
AjK 0:db98027c0bbb 409 *
AjK 0:db98027c0bbb 410 * @endcode
AjK 0:db98027c0bbb 411 *
AjK 0:db98027c0bbb 412 * <b>Note</b>, before using this function you should attach an actual
AjK 0:db98027c0bbb 413 * callback function using attach_pps()
AjK 0:db98027c0bbb 414 *
AjK 0:db98027c0bbb 415 * @see attach_pps()
AjK 0:db98027c0bbb 416 *
AjK 0:db98027c0bbb 417 * @ingroup API
AjK 0:db98027c0bbb 418 * @param irq A PinName to attach
AjK 0:db98027c0bbb 419 * @param type The type of edge, MAX7456::ppsRise OR MAX7456::ppsFall
AjK 0:db98027c0bbb 420 */
AjK 0:db98027c0bbb 421 void ppsAttach(PinName irq, ppsEdgeType type = ppsRise);
AjK 0:db98027c0bbb 422
AjK 0:db98027c0bbb 423 //! Remove any 1PPS signal previously attached.
AjK 0:db98027c0bbb 424 void ppsUnattach(void);
AjK 0:db98027c0bbb 425
AjK 0:db98027c0bbb 426 //! GPS serial receive interrupt handler.
AjK 0:db98027c0bbb 427 void rx_irq(void);
AjK 0:db98027c0bbb 428
AjK 0:db98027c0bbb 429 //! GPS pps interrupt handler.
AjK 0:db98027c0bbb 430 void pps_irq(void);
AjK 0:db98027c0bbb 431
AjK 0:db98027c0bbb 432 //! A pointer to the UART peripheral base address being used.
AjK 0:db98027c0bbb 433 void *_base;
AjK 0:db98027c0bbb 434
AjK 0:db98027c0bbb 435 //! The RX serial buffer.
AjK 0:db98027c0bbb 436 char buffer[2][GPS_BUFFER_LEN];
AjK 0:db98027c0bbb 437
AjK 0:db98027c0bbb 438 //! The current "active" buffer, i.e. the buffer the ISR is writing to.
AjK 0:db98027c0bbb 439 int active_buffer;
AjK 0:db98027c0bbb 440
AjK 0:db98027c0bbb 441 //! The active buffer "in" pointer.
AjK 0:db98027c0bbb 442 int rx_buffer_in;
AjK 0:db98027c0bbb 443
AjK 0:db98027c0bbb 444 //! Boolean flag set when the "passive" buffer is full and needs processing.
AjK 0:db98027c0bbb 445 bool process_required;
AjK 0:db98027c0bbb 446
AjK 0:db98027c0bbb 447 //! 10ms Ticker callback.
AjK 0:db98027c0bbb 448 void ticktock(void);
AjK 0:db98027c0bbb 449
AjK 0:db98027c0bbb 450 //! Attach a user object/method callback function to the PPS signal
AjK 0:db98027c0bbb 451 /**
AjK 0:db98027c0bbb 452 * Attach a user callback object/method to call when the 1PPS signal activates.
AjK 0:db98027c0bbb 453 *
AjK 0:db98027c0bbb 454 * @code
AjK 0:db98027c0bbb 455 * class FOO {
AjK 0:db98027c0bbb 456 * public:
AjK 0:db98027c0bbb 457 * void myCallback(void);
AjK 0:db98027c0bbb 458 * };
AjK 0:db98027c0bbb 459 *
AjK 0:db98027c0bbb 460 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 461 * Foo foo;
AjK 0:db98027c0bbb 462 *
AjK 0:db98027c0bbb 463 * gps.attach_pps(foo, &FOO::myCallback);
AjK 0:db98027c0bbb 464 *
AjK 0:db98027c0bbb 465 * @endcode
AjK 0:db98027c0bbb 466 *
AjK 0:db98027c0bbb 467 * @ingroup API
AjK 0:db98027c0bbb 468 * @param tptr pointer to the object to call the member function on
AjK 0:db98027c0bbb 469 * @param mptr pointer to the member function to be called
AjK 0:db98027c0bbb 470 */
AjK 0:db98027c0bbb 471 template<typename T>
AjK 0:db98027c0bbb 472 void attach_pps(T* tptr, void (T::*mptr)(void)) { cb_pps.attach(tptr, mptr); }
AjK 0:db98027c0bbb 473
AjK 0:db98027c0bbb 474 //! Attach a user callback function to the PPS signal
AjK 0:db98027c0bbb 475 /**
AjK 0:db98027c0bbb 476 * Attach a user callback function pointer to call when the 1PPS signal activates.
AjK 0:db98027c0bbb 477 *
AjK 0:db98027c0bbb 478 * @code
AjK 0:db98027c0bbb 479 * void myCallback(void) { ... }
AjK 0:db98027c0bbb 480 *
AjK 0:db98027c0bbb 481 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 482 * Foo foo;
AjK 0:db98027c0bbb 483 *
AjK 0:db98027c0bbb 484 * gps.attach_pps(&myCallback);
AjK 0:db98027c0bbb 485 *
AjK 0:db98027c0bbb 486 * @endcode
AjK 0:db98027c0bbb 487 *
AjK 0:db98027c0bbb 488 * @ingroup API
AjK 0:db98027c0bbb 489 * @param fptr Callback function pointer
AjK 0:db98027c0bbb 490 */
AjK 0:db98027c0bbb 491 void attach_pps(void (*fptr)(void)) { cb_pps.attach(fptr); }
AjK 0:db98027c0bbb 492
AjK 0:db98027c0bbb 493 //! A callback object for the 1PPS user API.
AjK 0:db98027c0bbb 494 FunctionPointer cb_pps;
AjK 0:db98027c0bbb 495
AjK 0:db98027c0bbb 496 //! Attach a user callback function to the NMEA RMC message processed signal.
AjK 0:db98027c0bbb 497 /**
AjK 0:db98027c0bbb 498 * Attach a user callback object/method to call when an NMEA RMC packet has been processed.
AjK 0:db98027c0bbb 499 *
AjK 0:db98027c0bbb 500 * @code
AjK 0:db98027c0bbb 501 * class FOO {
AjK 0:db98027c0bbb 502 * public:
AjK 0:db98027c0bbb 503 * void myCallback(void);
AjK 0:db98027c0bbb 504 * };
AjK 0:db98027c0bbb 505 *
AjK 0:db98027c0bbb 506 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 507 * Foo foo;
AjK 0:db98027c0bbb 508 *
AjK 0:db98027c0bbb 509 * gps.attach_rmc(foo, &FOO::myCallback);
AjK 0:db98027c0bbb 510 *
AjK 0:db98027c0bbb 511 * @endcode
AjK 0:db98027c0bbb 512 *
AjK 0:db98027c0bbb 513 * @ingroup API
AjK 0:db98027c0bbb 514 * @param tptr pointer to the object to call the member function on
AjK 0:db98027c0bbb 515 * @param mptr pointer to the member function to be called
AjK 0:db98027c0bbb 516 */
AjK 0:db98027c0bbb 517 template<typename T>
AjK 0:db98027c0bbb 518 void attach_rmc(T* tptr, void (T::*mptr)(void)) { cb_rmc.attach(tptr, mptr); }
AjK 0:db98027c0bbb 519
AjK 0:db98027c0bbb 520 //! Attach a user callback function to the NMEA RMC message processed signal.
AjK 0:db98027c0bbb 521 /**
AjK 0:db98027c0bbb 522 * Attach a user callback function pointer to call when an NMEA RMC packet has been processed.
AjK 0:db98027c0bbb 523 *
AjK 0:db98027c0bbb 524 * @code
AjK 0:db98027c0bbb 525 * void myCallback(void) { ... }
AjK 0:db98027c0bbb 526 *
AjK 0:db98027c0bbb 527 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 528 * Foo foo;
AjK 0:db98027c0bbb 529 *
AjK 0:db98027c0bbb 530 * gps.attach_rmc(&myCallback);
AjK 0:db98027c0bbb 531 *
AjK 0:db98027c0bbb 532 * @endcode
AjK 0:db98027c0bbb 533 *
AjK 0:db98027c0bbb 534 * @ingroup API
AjK 0:db98027c0bbb 535 * @param fptr Callback function pointer.
AjK 0:db98027c0bbb 536 */
AjK 0:db98027c0bbb 537 void attach_rmc(void (*fptr)(void)) { cb_rmc.attach(fptr); }
AjK 0:db98027c0bbb 538
AjK 0:db98027c0bbb 539 //! A callback object for the NMEA RMS message processed signal user API.
AjK 0:db98027c0bbb 540 FunctionPointer cb_rmc;
AjK 0:db98027c0bbb 541
AjK 0:db98027c0bbb 542 //! Attach a user callback function to the NMEA GGA message processed signal.
AjK 0:db98027c0bbb 543 /**
AjK 0:db98027c0bbb 544 * Attach a user callback object/method to call when an NMEA GGA packet has been processed.
AjK 0:db98027c0bbb 545 *
AjK 0:db98027c0bbb 546 * @code
AjK 0:db98027c0bbb 547 * class FOO {
AjK 0:db98027c0bbb 548 * public:
AjK 0:db98027c0bbb 549 * void myCallback(void);
AjK 0:db98027c0bbb 550 * };
AjK 0:db98027c0bbb 551 *
AjK 0:db98027c0bbb 552 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 553 * Foo foo;
AjK 0:db98027c0bbb 554 *
AjK 0:db98027c0bbb 555 * gps.attach_gga(foo, &FOO::myCallback);
AjK 0:db98027c0bbb 556 *
AjK 0:db98027c0bbb 557 * @endcode
AjK 0:db98027c0bbb 558 *
AjK 0:db98027c0bbb 559 * @ingroup API
AjK 0:db98027c0bbb 560 * @param tptr pointer to the object to call the member function on
AjK 0:db98027c0bbb 561 * @param mptr pointer to the member function to be called
AjK 0:db98027c0bbb 562 */
AjK 0:db98027c0bbb 563 template<typename T>
AjK 0:db98027c0bbb 564 void attach_gga(T* tptr, void (T::*mptr)(void)) { cb_gga.attach(tptr, mptr); }
AjK 0:db98027c0bbb 565
AjK 0:db98027c0bbb 566 //! Attach a user callback function to the NMEA GGA message processed signal.
AjK 0:db98027c0bbb 567 /**
AjK 0:db98027c0bbb 568 * Attach a user callback function pointer to call when an NMEA GGA packet has been processed.
AjK 0:db98027c0bbb 569 *
AjK 0:db98027c0bbb 570 * @code
AjK 0:db98027c0bbb 571 * void myCallback(void) { ... }
AjK 0:db98027c0bbb 572 *
AjK 0:db98027c0bbb 573 * GPS gps(NC, p9);
AjK 0:db98027c0bbb 574 * Foo foo;
AjK 0:db98027c0bbb 575 *
AjK 0:db98027c0bbb 576 * gps.attach_gga(&myCallback);
AjK 0:db98027c0bbb 577 *
AjK 0:db98027c0bbb 578 * @endcode
AjK 0:db98027c0bbb 579 *
AjK 0:db98027c0bbb 580 * @ingroup API
AjK 0:db98027c0bbb 581 * @param fptr Callback function pointer.
AjK 0:db98027c0bbb 582 */
AjK 0:db98027c0bbb 583 void attach_gga(void (*fptr)(void)) { cb_gga.attach(fptr); }
AjK 0:db98027c0bbb 584
AjK 0:db98027c0bbb 585 //! A callback object for the NMEA GGA message processed signal user API.
AjK 0:db98027c0bbb 586 FunctionPointer cb_gga;
AjK 0:db98027c0bbb 587
AjK 0:db98027c0bbb 588 //! Set the baud rate the GPS module is using.
AjK 0:db98027c0bbb 589 /**
AjK 0:db98027c0bbb 590 * Set the baud rate of the serial port
AjK 0:db98027c0bbb 591 *
AjK 0:db98027c0bbb 592 * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.baud
AjK 0:db98027c0bbb 593 *
AjK 0:db98027c0bbb 594 * @ingroup API
AjK 0:db98027c0bbb 595 * @param baudrate The baudrate to set.
AjK 0:db98027c0bbb 596 */
AjK 0:db98027c0bbb 597 void baud(int baudrate) { Serial::baud(baudrate); }
AjK 0:db98027c0bbb 598
AjK 0:db98027c0bbb 599 //! Set the serial port format the GPS module is using.
AjK 0:db98027c0bbb 600 /**
AjK 0:db98027c0bbb 601 * Set the transmission format used by the Serial port
AjK 0:db98027c0bbb 602 *
AjK 0:db98027c0bbb 603 * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format
AjK 0:db98027c0bbb 604 *
AjK 0:db98027c0bbb 605 * @ingroup API
AjK 0:db98027c0bbb 606 * @param bits - The number of bits in a word (5-8; default = 8)
AjK 0:db98027c0bbb 607 * @param parity - The parity used (GPS::None, GPS::Odd, GPS::Even, GPS::Forced1, GPS::Forced0; default = GPS::None)
AjK 0:db98027c0bbb 608 * @param stop_bits - The number of stop bits (1 or 2; default = 1)
AjK 0:db98027c0bbb 609 */
AjK 0:db98027c0bbb 610 void format(int bits, Parity parity, int stop_bits) { Serial::format(bits, (Serial::Parity)parity, stop_bits); }
AjK 0:db98027c0bbb 611
AjK 0:db98027c0bbb 612 protected:
AjK 0:db98027c0bbb 613
AjK 0:db98027c0bbb 614 //! Flag set true when a GPS PPS has been attached to a pin.
AjK 0:db98027c0bbb 615 bool _ppsInUse;
AjK 0:db98027c0bbb 616
AjK 0:db98027c0bbb 617 //! An InterruptIn object to "trigger" on the PPS edge.
AjK 0:db98027c0bbb 618 InterruptIn *_pps;
AjK 0:db98027c0bbb 619
AjK 0:db98027c0bbb 620 //! A Ticker object called every 10ms.
AjK 0:db98027c0bbb 621 Ticker *_second100;
AjK 0:db98027c0bbb 622
AjK 0:db98027c0bbb 623 //! A GPS_Time object used to hold the last parsed time/date data.
AjK 0:db98027c0bbb 624 GPS_Time theTime;
AjK 0:db98027c0bbb 625
AjK 0:db98027c0bbb 626 //! A GPS_Geodetic object used to hold the last parsed positional data.
AjK 0:db98027c0bbb 627 GPS_Geodetic thePlace;
AjK 0:db98027c0bbb 628 };
AjK 0:db98027c0bbb 629
AjK 0:db98027c0bbb 630 #endif
AjK 0:db98027c0bbb 631