Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: GPSDevice LogData_UM6-to-SDcard UM6withGPS mbed-cansat-test-GPS ... more
Fork of MODGPS by
GPS.cpp
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 #include "GPS.h" 00024 00025 GPS::GPS(PinName tx, PinName rx, const char *name) : Serial(tx, rx, name) 00026 { 00027 _nmeaOnUart0 = false; 00028 00029 _lastByte = 0; 00030 00031 _gga = (char *)NULL; 00032 00033 _rmc = (char *)NULL; 00034 00035 _vtg = (char *)NULL; 00036 00037 switch (rx) { 00038 case p14: 00039 _uidx = 1; 00040 break; 00041 00042 case p27: 00043 _uidx = 2; 00044 break; 00045 00046 case p10: 00047 _uidx = 3; 00048 break; 00049 00050 default: 00051 _uidx = 0; 00052 } 00053 00054 switch(_uidx) { 00055 case 1: _base = LPC_UART1; break; 00056 case 2: _base = LPC_UART2; break; 00057 case 3: _base = LPC_UART3; break; 00058 default : _base = NULL; break; 00059 } 00060 00061 _pps = NULL; 00062 _ppsInUse = false; 00063 00064 if (_base != NULL) attach(this, &GPS::rx_irq); 00065 00066 _second100 = new Ticker; 00067 _second100->attach_us(this, &GPS::ticktock, GPS_TICKTOCK); 00068 } 00069 00070 void 00071 GPS::ppsAttach(PinName irq, ppsEdgeType type) 00072 { 00073 if (_pps != NULL) delete(_pps); 00074 _pps = new InterruptIn(irq); 00075 if (type == ppsRise ) _pps->rise(this, &GPS::pps_irq); 00076 else _pps->fall(this, &GPS::pps_irq); 00077 _ppsInUse = true; 00078 } 00079 00080 void 00081 GPS::ppsUnattach(void) 00082 { 00083 if (_pps != NULL) delete(_pps); 00084 _ppsInUse = false; 00085 } 00086 00087 double 00088 GPS::latitude(void) 00089 { 00090 double a, b; 00091 do { a = thePlace.lat; b = thePlace.lat; } while (a != b); 00092 return a; 00093 } 00094 00095 double 00096 GPS::longitude(void) 00097 { 00098 double a, b; 00099 do { a = thePlace.lon; b = thePlace.lon; } while (a != b); 00100 return a; 00101 } 00102 00103 double 00104 GPS::altitude(void) 00105 { 00106 double a, b; 00107 do { a = thePlace.alt; b = thePlace.alt; } while (a != b); 00108 return a; 00109 } 00110 00111 GPS_Geodetic * 00112 GPS::geodetic(GPS_Geodetic *q) 00113 { 00114 GPS_Geodetic a; 00115 00116 if (q == NULL) q = new GPS_Geodetic; 00117 00118 do { 00119 memcpy(&a, &thePlace, sizeof(GPS_Geodetic)); 00120 memcpy(q, &thePlace, sizeof(GPS_Geodetic)); 00121 } 00122 while (memcmp(&a, q, sizeof(GPS_Geodetic)) != 0); 00123 00124 return q; 00125 } 00126 00127 GPS_VTG * 00128 GPS::vtg(GPS_VTG *q) 00129 { 00130 GPS_VTG a; 00131 00132 if (q == NULL) q = new GPS_VTG; 00133 00134 do { 00135 memcpy(&a, &theVTG, sizeof(GPS_VTG)); 00136 memcpy(q, &theVTG, sizeof(GPS_VTG)); 00137 } 00138 while (memcmp(&a, q, sizeof(GPS_VTG)) != 0); 00139 00140 return q; 00141 } 00142 00143 void 00144 GPS::ticktock(void) 00145 { 00146 // Increment the time structure by 1/100th of a second. 00147 ++theTime; 00148 00149 // Test the serial queue. 00150 if (process_required) { 00151 00152 char *s = buffer[active_buffer == 0 ? 1 : 0]; 00153 if (!strncmp(s, "$GPRMC", 6)) { 00154 if (_rmc) { 00155 int i; 00156 for(i = 0; s[i] != '\n'; i++) { 00157 _rmc[i] = s[i]; 00158 } 00159 _rmc[i++] = '\n'; _rmc[i] = '\0'; 00160 } 00161 theTime.nmea_rmc(s); 00162 cb_rmc.call(); 00163 if (!_ppsInUse) theTime.fractionalReset(); 00164 } 00165 else if (!strncmp(s, "$GPGGA", 6)) { 00166 if (_gga) { 00167 int i; 00168 for(i = 0; s[i] != '\n'; i++) { 00169 _gga[i] = s[i]; 00170 } 00171 _gga[i++] = '\n'; _gga[i] = '\0'; 00172 } 00173 thePlace.nmea_gga(s); 00174 cb_gga.call(); 00175 } 00176 else if (!strncmp(s, "$GPVTG", 6)) { 00177 if (_vtg) { 00178 int i; 00179 for(i = 0; s[i] != '\n'; i++) { 00180 _vtg[i] = s[i]; 00181 } 00182 _vtg[i++] = '\n'; _vtg[i] = '\0'; 00183 } 00184 theVTG.nmea_vtg(s); 00185 cb_vtg.call(); 00186 } 00187 else { 00188 if (_ukn) { 00189 int i; 00190 for(i = 0; s[i] != '\n'; i++) { 00191 _ukn[i] = s[i]; 00192 } 00193 _ukn[i++] = '\n'; _ukn[i] = '\0'; 00194 cb_ukn.call(); 00195 } 00196 } 00197 process_required = false; 00198 } 00199 00200 // If we have a valid GPS time then, once per minute, set the RTC. 00201 if (theTime.status == 'A' && theTime.second == 0 && theTime.tenths == 0 && theTime.hundreths == 0) { 00202 // set_time() is defined in rtc_time.h 00203 // http://mbed.org/projects/libraries/svn/mbed/trunk/rtc_time.h 00204 set_time(theTime.to_C_tm()); 00205 } 00206 00207 } 00208 00209 void 00210 GPS::pps_irq(void) 00211 { 00212 theTime.fractionalReset(); 00213 theTime++; // Increment the time/date by one second. 00214 cb_pps.call(); 00215 } 00216 00217 void 00218 GPS::rx_irq(void) 00219 { 00220 uint32_t iir __attribute__((unused)); 00221 char c; 00222 00223 if (_base) { 00224 iir = (uint32_t)*((char *)_base + GPS_IIR); 00225 while((int)(*((char *)_base + GPS_LSR) & 0x1)) { 00226 c = (char)(*((char *)_base + GPS_RBR) & 0xFF); 00227 00228 // strtok workaround. 00229 // Found that ,, together (which some NMEA sentences 00230 // contain for a null/empty field) confuses strtok() 00231 // function. Solution:- Push a "zero" into the string 00232 // for missing/empty fields. 00233 if (c == ',' && _lastByte == ',') { 00234 buffer[active_buffer][rx_buffer_in] = '0'; 00235 if (++rx_buffer_in >= GPS_BUFFER_LEN) rx_buffer_in = 0; 00236 } 00237 00238 // Debugging/dumping data. 00239 if (_nmeaOnUart0) LPC_UART0->RBR = c; 00240 00241 // Put the byte into the string. 00242 buffer[active_buffer][rx_buffer_in] = c; 00243 if (++rx_buffer_in >= GPS_BUFFER_LEN) rx_buffer_in = 0; 00244 00245 // Save for next time an irq occurs. See strtok() above. 00246 _lastByte = c; 00247 00248 // If end of NMEA sentence flag for processing. 00249 if (c == '\n') { 00250 active_buffer = active_buffer == 0 ? 1 : 0; 00251 process_required = true; 00252 rx_buffer_in = 0; 00253 } 00254 } 00255 } 00256 }
Generated on Wed Jul 13 2022 14:12:03 by
1.7.2
