a NEMA gps library for mbed6 using UnbufferedSerial interrupt

Dependents:   GPS_sample_os6

Committer:
ericleal
Date:
Wed Sep 15 23:18:47 2021 +0000
Revision:
0:221c0a7e2bcc
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ericleal 0:221c0a7e2bcc 1 #include "mbed.h"
ericleal 0:221c0a7e2bcc 2 #include "GPS.h"
ericleal 0:221c0a7e2bcc 3
ericleal 0:221c0a7e2bcc 4 GPS::GPS(PinName serialTX, PinName serialRX) :
ericleal 0:221c0a7e2bcc 5 UnbufferedSerial(serialTX, serialRX)
ericleal 0:221c0a7e2bcc 6 {
ericleal 0:221c0a7e2bcc 7 attach(callback(this, &GPS::readData));
ericleal 0:221c0a7e2bcc 8 rxTimer.start();
ericleal 0:221c0a7e2bcc 9 }
ericleal 0:221c0a7e2bcc 10
ericleal 0:221c0a7e2bcc 11 void GPS::readData()
ericleal 0:221c0a7e2bcc 12 {
ericleal 0:221c0a7e2bcc 13 char gps_byte;
ericleal 0:221c0a7e2bcc 14 volatile int step;
ericleal 0:221c0a7e2bcc 15 volatile int array_title;
ericleal 0:221c0a7e2bcc 16 rxTimer.reset();
ericleal 0:221c0a7e2bcc 17 read(&gps_byte, 1);
ericleal 0:221c0a7e2bcc 18 if(gpsRxLen < PACKET_SIZE) {
ericleal 0:221c0a7e2bcc 19 if (gps_byte == '$') {
ericleal 0:221c0a7e2bcc 20 gpsRxLen = 0; //'$' begin packet symbol
ericleal 0:221c0a7e2bcc 21 step = 0;
ericleal 0:221c0a7e2bcc 22 parsed = false;
ericleal 0:221c0a7e2bcc 23 }
ericleal 0:221c0a7e2bcc 24 switch(step){
ericleal 0:221c0a7e2bcc 25 case 0 :
ericleal 0:221c0a7e2bcc 26 step++;
ericleal 0:221c0a7e2bcc 27 break;
ericleal 0:221c0a7e2bcc 28 case 1 :
ericleal 0:221c0a7e2bcc 29 if (gps_byte == 'G')
ericleal 0:221c0a7e2bcc 30 step++;
ericleal 0:221c0a7e2bcc 31 break;
ericleal 0:221c0a7e2bcc 32 case 2 :
ericleal 0:221c0a7e2bcc 33 if (gps_byte == 'P') {
ericleal 0:221c0a7e2bcc 34 step++;
ericleal 0:221c0a7e2bcc 35 }
ericleal 0:221c0a7e2bcc 36 break;
ericleal 0:221c0a7e2bcc 37 case 3 :
ericleal 0:221c0a7e2bcc 38 msg_type = gps_byte<<16;
ericleal 0:221c0a7e2bcc 39 step++;
ericleal 0:221c0a7e2bcc 40 break;
ericleal 0:221c0a7e2bcc 41 case 4 :
ericleal 0:221c0a7e2bcc 42 msg_type = msg_type + (gps_byte<<8);
ericleal 0:221c0a7e2bcc 43 step++;
ericleal 0:221c0a7e2bcc 44 break;
ericleal 0:221c0a7e2bcc 45 case 5 :
ericleal 0:221c0a7e2bcc 46 msg_type = msg_type + gps_byte;
ericleal 0:221c0a7e2bcc 47 if (msg_type == 4345668) { //BOD
ericleal 0:221c0a7e2bcc 48 array_title = 0;
ericleal 0:221c0a7e2bcc 49 updates += 0x01;
ericleal 0:221c0a7e2bcc 50 step++;
ericleal 0:221c0a7e2bcc 51 }
ericleal 0:221c0a7e2bcc 52 else if (msg_type == 4347715) { //BWC
ericleal 0:221c0a7e2bcc 53 array_title = 1;
ericleal 0:221c0a7e2bcc 54 updates += 0x02;
ericleal 0:221c0a7e2bcc 55 step++;
ericleal 0:221c0a7e2bcc 56 }
ericleal 0:221c0a7e2bcc 57 else if (msg_type == 4671297) { //GGA
ericleal 0:221c0a7e2bcc 58 array_title = 2;
ericleal 0:221c0a7e2bcc 59 updates += 0x04;
ericleal 0:221c0a7e2bcc 60 step++;
ericleal 0:221c0a7e2bcc 61 }
ericleal 0:221c0a7e2bcc 62 else if (msg_type == 4672588) { //GLL
ericleal 0:221c0a7e2bcc 63 array_title = 3;
ericleal 0:221c0a7e2bcc 64 updates += 0x08;
ericleal 0:221c0a7e2bcc 65 step++;
ericleal 0:221c0a7e2bcc 66 }
ericleal 0:221c0a7e2bcc 67 else if (msg_type == 4674369) { //GSA
ericleal 0:221c0a7e2bcc 68 array_title = 4;
ericleal 0:221c0a7e2bcc 69 updates += 0x10;
ericleal 0:221c0a7e2bcc 70 step++;
ericleal 0:221c0a7e2bcc 71 }
ericleal 0:221c0a7e2bcc 72 else if (msg_type == 4674390) { //GSV
ericleal 0:221c0a7e2bcc 73 array_title = 5;
ericleal 0:221c0a7e2bcc 74 updates += 0x20;
ericleal 0:221c0a7e2bcc 75 step++;
ericleal 0:221c0a7e2bcc 76 }
ericleal 0:221c0a7e2bcc 77 else if (msg_type == 4736084) { //HDT
ericleal 0:221c0a7e2bcc 78 array_title = 6;
ericleal 0:221c0a7e2bcc 79 updates += 0x40;
ericleal 0:221c0a7e2bcc 80 step++;
ericleal 0:221c0a7e2bcc 81 }
ericleal 0:221c0a7e2bcc 82 else if (msg_type == 5386288) { //R00
ericleal 0:221c0a7e2bcc 83 array_title = 7;
ericleal 0:221c0a7e2bcc 84 updates += 0x80;
ericleal 0:221c0a7e2bcc 85 step++;
ericleal 0:221c0a7e2bcc 86 }
ericleal 0:221c0a7e2bcc 87 else if (msg_type == 5393729) { //RMA
ericleal 0:221c0a7e2bcc 88 array_title = 8;
ericleal 0:221c0a7e2bcc 89 updates += 0x100;
ericleal 0:221c0a7e2bcc 90 step++;
ericleal 0:221c0a7e2bcc 91 }
ericleal 0:221c0a7e2bcc 92 else if (msg_type == 5393730) { //RMB
ericleal 0:221c0a7e2bcc 93 array_title = 9;
ericleal 0:221c0a7e2bcc 94 updates += 0x200;
ericleal 0:221c0a7e2bcc 95 step++;
ericleal 0:221c0a7e2bcc 96 }
ericleal 0:221c0a7e2bcc 97 else if (msg_type == 5393731) { //RMC
ericleal 0:221c0a7e2bcc 98 array_title = 10;
ericleal 0:221c0a7e2bcc 99 updates = updates | 0x400;
ericleal 0:221c0a7e2bcc 100 step++;
ericleal 0:221c0a7e2bcc 101 }
ericleal 0:221c0a7e2bcc 102 else if (msg_type == 5395525) { //RTE
ericleal 0:221c0a7e2bcc 103 array_title = 11;
ericleal 0:221c0a7e2bcc 104 updates += 0x800;
ericleal 0:221c0a7e2bcc 105 step++;
ericleal 0:221c0a7e2bcc 106 }
ericleal 0:221c0a7e2bcc 107 else if (msg_type == 5526086) { //RRF
ericleal 0:221c0a7e2bcc 108 array_title = 12;
ericleal 0:221c0a7e2bcc 109 updates += 0x1000;
ericleal 0:221c0a7e2bcc 110 step++;
ericleal 0:221c0a7e2bcc 111 }
ericleal 0:221c0a7e2bcc 112 else if (msg_type == 5461070) { //STN
ericleal 0:221c0a7e2bcc 113 array_title = 13;
ericleal 0:221c0a7e2bcc 114 updates += 0x2000;
ericleal 0:221c0a7e2bcc 115 step++;
ericleal 0:221c0a7e2bcc 116 }
ericleal 0:221c0a7e2bcc 117 else if (msg_type == 5653079) { //VBW
ericleal 0:221c0a7e2bcc 118 array_title = 14;
ericleal 0:221c0a7e2bcc 119 updates += 0x4000;
ericleal 0:221c0a7e2bcc 120 step++;
ericleal 0:221c0a7e2bcc 121 }
ericleal 0:221c0a7e2bcc 122 else if (msg_type == 5657671) { //VTG
ericleal 0:221c0a7e2bcc 123 array_title = 15;
ericleal 0:221c0a7e2bcc 124 updates += 0x8000;
ericleal 0:221c0a7e2bcc 125 step++;
ericleal 0:221c0a7e2bcc 126 }
ericleal 0:221c0a7e2bcc 127 else if (msg_type == 5722188) { //WPL
ericleal 0:221c0a7e2bcc 128 array_title = 16;
ericleal 0:221c0a7e2bcc 129 updates += 0x10000;
ericleal 0:221c0a7e2bcc 130 step++;
ericleal 0:221c0a7e2bcc 131 }
ericleal 0:221c0a7e2bcc 132 else if (msg_type == 5788741) { //XTE
ericleal 0:221c0a7e2bcc 133 array_title = 17;
ericleal 0:221c0a7e2bcc 134 updates += 0x20000;
ericleal 0:221c0a7e2bcc 135 step++;
ericleal 0:221c0a7e2bcc 136 }
ericleal 0:221c0a7e2bcc 137 else if (msg_type == 5915713) { //ZDA
ericleal 0:221c0a7e2bcc 138 array_title = 18;
ericleal 0:221c0a7e2bcc 139 updates += 0x40000;
ericleal 0:221c0a7e2bcc 140 step++;
ericleal 0:221c0a7e2bcc 141 }
ericleal 0:221c0a7e2bcc 142 else uart_error = true;
ericleal 0:221c0a7e2bcc 143 break;
ericleal 0:221c0a7e2bcc 144 case 6 :
ericleal 0:221c0a7e2bcc 145 switch (array_title) {
ericleal 0:221c0a7e2bcc 146 case 0 :
ericleal 0:221c0a7e2bcc 147 GPBOD[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 148 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 149 break;
ericleal 0:221c0a7e2bcc 150 case 1 :
ericleal 0:221c0a7e2bcc 151 GPBWC[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 152 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 153 break;
ericleal 0:221c0a7e2bcc 154 case 2 :
ericleal 0:221c0a7e2bcc 155 GPGGA[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 156 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 157 break;
ericleal 0:221c0a7e2bcc 158 case 3 :
ericleal 0:221c0a7e2bcc 159 GPGLL[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 160 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 161 break;
ericleal 0:221c0a7e2bcc 162 case 4 :
ericleal 0:221c0a7e2bcc 163 GPGSA[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 164 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 165 break;
ericleal 0:221c0a7e2bcc 166 case 5 :
ericleal 0:221c0a7e2bcc 167 GPGSV[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 168 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 169 break;
ericleal 0:221c0a7e2bcc 170 case 6 :
ericleal 0:221c0a7e2bcc 171 GPHDT[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 172 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 173 break;
ericleal 0:221c0a7e2bcc 174 case 7 :
ericleal 0:221c0a7e2bcc 175 GPR00[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 176 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 177 break;
ericleal 0:221c0a7e2bcc 178 case 8 :
ericleal 0:221c0a7e2bcc 179 GPRMA[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 180 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 181 break;
ericleal 0:221c0a7e2bcc 182 case 9 :
ericleal 0:221c0a7e2bcc 183 GPRMB[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 184 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 185 break;
ericleal 0:221c0a7e2bcc 186 case 10 :
ericleal 0:221c0a7e2bcc 187 GPRMC[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 188 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 189 break;
ericleal 0:221c0a7e2bcc 190 case 11 :
ericleal 0:221c0a7e2bcc 191 GPRTE[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 192 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 193 break;
ericleal 0:221c0a7e2bcc 194 case 12 :
ericleal 0:221c0a7e2bcc 195 GPTRF[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 196 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 197 break;
ericleal 0:221c0a7e2bcc 198 case 13 :
ericleal 0:221c0a7e2bcc 199 GPSTN[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 200 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 201 break;
ericleal 0:221c0a7e2bcc 202 case 14 :
ericleal 0:221c0a7e2bcc 203 GPVBW[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 204 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 205 break;
ericleal 0:221c0a7e2bcc 206 case 15 :
ericleal 0:221c0a7e2bcc 207 GPVTG[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 208 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 209 break;
ericleal 0:221c0a7e2bcc 210 case 16 :
ericleal 0:221c0a7e2bcc 211 GPWPL[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 212 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 213 break;
ericleal 0:221c0a7e2bcc 214 case 17 :
ericleal 0:221c0a7e2bcc 215 GPXTE[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 216 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 217 break;
ericleal 0:221c0a7e2bcc 218 case 18 :
ericleal 0:221c0a7e2bcc 219 GPZDA[gpsRxLen] = gps_byte;
ericleal 0:221c0a7e2bcc 220 gpsRxLen ++;
ericleal 0:221c0a7e2bcc 221 break;
ericleal 0:221c0a7e2bcc 222 }
ericleal 0:221c0a7e2bcc 223 break;
ericleal 0:221c0a7e2bcc 224 }
ericleal 0:221c0a7e2bcc 225
ericleal 0:221c0a7e2bcc 226 }
ericleal 0:221c0a7e2bcc 227 //parsed = false;
ericleal 0:221c0a7e2bcc 228 }
ericleal 0:221c0a7e2bcc 229
ericleal 0:221c0a7e2bcc 230 bool GPS::updateCheck()
ericleal 0:221c0a7e2bcc 231 {
ericleal 0:221c0a7e2bcc 232 if (!parsed) {
ericleal 0:221c0a7e2bcc 233 if (rxTimer.elapsed_time().count() > RX_MAXTIME) {
ericleal 0:221c0a7e2bcc 234 gpsRxLen = 0;
ericleal 0:221c0a7e2bcc 235 parsed = true;
ericleal 0:221c0a7e2bcc 236 if ((updates & 0x01) > 0) {
ericleal 0:221c0a7e2bcc 237 //printf("GPBOD ");
ericleal 0:221c0a7e2bcc 238 }
ericleal 0:221c0a7e2bcc 239 if ((updates & 0x02) > 0) {
ericleal 0:221c0a7e2bcc 240 //printf("GPBWC ");
ericleal 0:221c0a7e2bcc 241 }
ericleal 0:221c0a7e2bcc 242 if ((updates & 0x04) > 0) {
ericleal 0:221c0a7e2bcc 243 sscanf(GPGGA, ",%f,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f", &time, &latitude, &ns, &longitude, &ew, &lock, &sats, &hdop, &alt, &unit, &geoid);
ericleal 0:221c0a7e2bcc 244 int_time = static_cast<int>(time);
ericleal 0:221c0a7e2bcc 245 //printf("GPGGA ");
ericleal 0:221c0a7e2bcc 246 }
ericleal 0:221c0a7e2bcc 247 if ((updates & 0x08) > 0) {
ericleal 0:221c0a7e2bcc 248 //printf("GPGLL ");
ericleal 0:221c0a7e2bcc 249 }
ericleal 0:221c0a7e2bcc 250 if ((updates & 0x10) > 0) {
ericleal 0:221c0a7e2bcc 251 //printf("GPGSA ");
ericleal 0:221c0a7e2bcc 252 }
ericleal 0:221c0a7e2bcc 253 if ((updates & 0x20) > 0) {
ericleal 0:221c0a7e2bcc 254 //printf("GPGSV ");
ericleal 0:221c0a7e2bcc 255 }
ericleal 0:221c0a7e2bcc 256 if ((updates & 0x40) > 0) {
ericleal 0:221c0a7e2bcc 257 //printf("GPHDT ");
ericleal 0:221c0a7e2bcc 258 }
ericleal 0:221c0a7e2bcc 259 if ((updates & 0x80) > 0) {
ericleal 0:221c0a7e2bcc 260 //printf("GPR00 ");
ericleal 0:221c0a7e2bcc 261 }
ericleal 0:221c0a7e2bcc 262 if ((updates & 0x100) > 0) {
ericleal 0:221c0a7e2bcc 263 //printf("GPRMA ");
ericleal 0:221c0a7e2bcc 264 }
ericleal 0:221c0a7e2bcc 265 if ((updates & 0x200) > 0) {
ericleal 0:221c0a7e2bcc 266 //printf("GPRMB ");
ericleal 0:221c0a7e2bcc 267 }
ericleal 0:221c0a7e2bcc 268 if ((updates & 0x400) > 0) {
ericleal 0:221c0a7e2bcc 269 //printf("GPRMC ");
ericleal 0:221c0a7e2bcc 270 }
ericleal 0:221c0a7e2bcc 271 if ((updates & 0x800) > 0) {
ericleal 0:221c0a7e2bcc 272 //printf("GPRTE ");
ericleal 0:221c0a7e2bcc 273 }
ericleal 0:221c0a7e2bcc 274 if ((updates & 0x1000) > 0) {
ericleal 0:221c0a7e2bcc 275 //printf("GPRTF ");
ericleal 0:221c0a7e2bcc 276 }
ericleal 0:221c0a7e2bcc 277 if ((updates & 0x2000) > 0) {
ericleal 0:221c0a7e2bcc 278 //printf("GPSTN ");
ericleal 0:221c0a7e2bcc 279 }
ericleal 0:221c0a7e2bcc 280 if ((updates & 0x4000) > 0) {
ericleal 0:221c0a7e2bcc 281 //printf("GPVBW ");
ericleal 0:221c0a7e2bcc 282 }
ericleal 0:221c0a7e2bcc 283 if ((updates & 0x8000) > 0) {
ericleal 0:221c0a7e2bcc 284 //printf("GPVTG ");
ericleal 0:221c0a7e2bcc 285 sscanf(GPVTG, ",%f,%c,,%c,%f,%c,%f,%c,%c", &track, &T, &M, &speedN, &N, &speedM, &K, &mode);
ericleal 0:221c0a7e2bcc 286 }
ericleal 0:221c0a7e2bcc 287 if ((updates & 0x10000) > 0) {
ericleal 0:221c0a7e2bcc 288 //printf("GPWPL ");
ericleal 0:221c0a7e2bcc 289 }
ericleal 0:221c0a7e2bcc 290 if ((updates & 0x20000) > 0) {
ericleal 0:221c0a7e2bcc 291 //printf("GPXTE ");
ericleal 0:221c0a7e2bcc 292 }
ericleal 0:221c0a7e2bcc 293 if ((updates & 0x40000) > 0) {
ericleal 0:221c0a7e2bcc 294 //printf("GPZDA ");
ericleal 0:221c0a7e2bcc 295 }
ericleal 0:221c0a7e2bcc 296 updates = 0;
ericleal 0:221c0a7e2bcc 297 uart_error = false;
ericleal 0:221c0a7e2bcc 298 return true;
ericleal 0:221c0a7e2bcc 299 }
ericleal 0:221c0a7e2bcc 300 else {
ericleal 0:221c0a7e2bcc 301 return false;
ericleal 0:221c0a7e2bcc 302 }
ericleal 0:221c0a7e2bcc 303 }
ericleal 0:221c0a7e2bcc 304 else {
ericleal 0:221c0a7e2bcc 305 return false;
ericleal 0:221c0a7e2bcc 306 }
ericleal 0:221c0a7e2bcc 307
ericleal 0:221c0a7e2bcc 308 }
ericleal 0:221c0a7e2bcc 309
ericleal 0:221c0a7e2bcc 310 int GPS::getTime()
ericleal 0:221c0a7e2bcc 311 {
ericleal 0:221c0a7e2bcc 312 return int_time;
ericleal 0:221c0a7e2bcc 313 }
ericleal 0:221c0a7e2bcc 314
ericleal 0:221c0a7e2bcc 315 float GPS::getLat()
ericleal 0:221c0a7e2bcc 316 {
ericleal 0:221c0a7e2bcc 317 return latitude;
ericleal 0:221c0a7e2bcc 318 }
ericleal 0:221c0a7e2bcc 319
ericleal 0:221c0a7e2bcc 320 float GPS::getLong()
ericleal 0:221c0a7e2bcc 321 {
ericleal 0:221c0a7e2bcc 322 return longitude;
ericleal 0:221c0a7e2bcc 323 }
ericleal 0:221c0a7e2bcc 324
ericleal 0:221c0a7e2bcc 325 int GPS::getSats()
ericleal 0:221c0a7e2bcc 326 {
ericleal 0:221c0a7e2bcc 327 return sats;
ericleal 0:221c0a7e2bcc 328 }
ericleal 0:221c0a7e2bcc 329
ericleal 0:221c0a7e2bcc 330 float GPS::getHDOP()
ericleal 0:221c0a7e2bcc 331 {
ericleal 0:221c0a7e2bcc 332 return hdop;
ericleal 0:221c0a7e2bcc 333 }
ericleal 0:221c0a7e2bcc 334
ericleal 0:221c0a7e2bcc 335 float GPS::getSpeed()
ericleal 0:221c0a7e2bcc 336 {
ericleal 0:221c0a7e2bcc 337 return speedM;
ericleal 0:221c0a7e2bcc 338 }