Revised Embedded Artists' MTK3339 library to save all raw GPS messages and enable optional decoding of RMC message.

Fork of MTK3339 by EmbeddedArtists AB

Committer:
tbronez
Date:
Fri Jul 31 21:20:55 2015 +0000
Revision:
1:3057ad6a5d4b
Parent:
0:bd0fe2412980
Child:
2:2391d165df47
Highly modified GPS interface based on original EA interface

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tbronez 1:3057ad6a5d4b 1 // Class to represent serial interface to MTK3339 GPS chip
tbronez 1:3057ad6a5d4b 2 // Original author: Embedded Artists
tbronez 1:3057ad6a5d4b 3 // Revised by T. Bronez, 2015-05-28
embeddedartists 0:bd0fe2412980 4
embeddedartists 0:bd0fe2412980 5 #include "mbed.h"
embeddedartists 0:bd0fe2412980 6 #include "MTK3339.h"
tbronez 1:3057ad6a5d4b 7 #define min(a,b) a>b?a:b
embeddedartists 0:bd0fe2412980 8
tbronez 1:3057ad6a5d4b 9 DigitalOut led2(LED2);
tbronez 1:3057ad6a5d4b 10 Timeout timeout2;
tbronez 1:3057ad6a5d4b 11 void led2Off() {
tbronez 1:3057ad6a5d4b 12 led2 = 1;
tbronez 1:3057ad6a5d4b 13 }
tbronez 1:3057ad6a5d4b 14 void flashLED2() {
tbronez 1:3057ad6a5d4b 15 led2 = 0;
tbronez 1:3057ad6a5d4b 16 timeout2.attach(&led2Off, 0.1);
tbronez 1:3057ad6a5d4b 17 }
embeddedartists 0:bd0fe2412980 18
embeddedartists 0:bd0fe2412980 19 MTK3339::MTK3339(PinName tx, PinName rx) : _serial(tx, rx) {
embeddedartists 0:bd0fe2412980 20 _serial.baud(9600);
embeddedartists 0:bd0fe2412980 21 _state = StateStart;
embeddedartists 0:bd0fe2412980 22 _sentenceMask = 0;
tbronez 1:3057ad6a5d4b 23 _availDataType = NMEA_NONE;
tbronez 1:3057ad6a5d4b 24 memset(&rmc, 0, sizeof(RmcType));
tbronez 1:3057ad6a5d4b 25
tbronez 1:3057ad6a5d4b 26 memset(&ggaMsg, 0, MSG_BUF_SZ);
tbronez 1:3057ad6a5d4b 27 memset(&gsaMsg, 0, MSG_BUF_SZ);
tbronez 1:3057ad6a5d4b 28 memset(&gsvMsg, 0, MSG_BUF_SZ);
tbronez 1:3057ad6a5d4b 29 memset(&rmcMsg, 0, MSG_BUF_SZ);
tbronez 1:3057ad6a5d4b 30 memset(&vtgMsg, 0, MSG_BUF_SZ);
embeddedartists 0:bd0fe2412980 31 }
embeddedartists 0:bd0fe2412980 32
embeddedartists 0:bd0fe2412980 33 void MTK3339::start(void (*fptr)(void), int mask) {
embeddedartists 0:bd0fe2412980 34 if (fptr && mask) {
embeddedartists 0:bd0fe2412980 35 _dataCallback.attach(fptr);
embeddedartists 0:bd0fe2412980 36 _sentenceMask = mask;
embeddedartists 0:bd0fe2412980 37 _serial.attach(this, &MTK3339::uartIrq, Serial::RxIrq);
tbronez 1:3057ad6a5d4b 38 }
embeddedartists 0:bd0fe2412980 39 }
embeddedartists 0:bd0fe2412980 40
embeddedartists 0:bd0fe2412980 41 void MTK3339::stop() {
embeddedartists 0:bd0fe2412980 42 _dataCallback.attach(NULL);
embeddedartists 0:bd0fe2412980 43 _sentenceMask = 0;
embeddedartists 0:bd0fe2412980 44 _serial.attach(NULL);
embeddedartists 0:bd0fe2412980 45 }
embeddedartists 0:bd0fe2412980 46
embeddedartists 0:bd0fe2412980 47 MTK3339::NmeaSentence MTK3339::getAvailableDataType() {
embeddedartists 0:bd0fe2412980 48 return _availDataType;
embeddedartists 0:bd0fe2412980 49 }
embeddedartists 0:bd0fe2412980 50
tbronez 1:3057ad6a5d4b 51 void MTK3339::decodeRMC() {
tbronez 1:3057ad6a5d4b 52 // See http://aprs.gids.nl/nmea/#rmc for RMC sentence definition
tbronez 1:3057ad6a5d4b 53 const double sixtieth = 1.0/60.0;
tbronez 1:3057ad6a5d4b 54 int n = 0; // scratch int for conversions
tbronez 1:3057ad6a5d4b 55 double d = 0; // scratch double for conversions
tbronez 1:3057ad6a5d4b 56 char* q = NULL; // scratch pointer for conversions
tbronez 1:3057ad6a5d4b 57
tbronez 1:3057ad6a5d4b 58 memset(&rmc, 0, sizeof(RmcType));
tbronez 1:3057ad6a5d4b 59 char* p = rmcMsg;
tbronez 1:3057ad6a5d4b 60
tbronez 1:3057ad6a5d4b 61 /**
tbronez 1:3057ad6a5d4b 62 * Find and decode field 0, UTC time, as hhmmss.sss
tbronez 1:3057ad6a5d4b 63 */
tbronez 1:3057ad6a5d4b 64 p = strchr(p, ','); // First comma
tbronez 1:3057ad6a5d4b 65 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 66 p++; // Start of field
tbronez 1:3057ad6a5d4b 67
tbronez 1:3057ad6a5d4b 68 q = p;
tbronez 1:3057ad6a5d4b 69 // Decode time hours
tbronez 1:3057ad6a5d4b 70 n = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 71 n += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 72 rmc.gps_tm.tm_hour = n;
tbronez 1:3057ad6a5d4b 73 // Decode time minutes
tbronez 1:3057ad6a5d4b 74 n = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 75 n += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 76 rmc.gps_tm.tm_min = n;
tbronez 1:3057ad6a5d4b 77 // Decode time seconds
tbronez 1:3057ad6a5d4b 78 n = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 79 n += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 80 rmc.gps_tm.tm_sec = n;
tbronez 1:3057ad6a5d4b 81 // Decode time milliseconds
tbronez 1:3057ad6a5d4b 82 q++; // decimal point
tbronez 1:3057ad6a5d4b 83 n = ((*q++) - 48)*100; // hundreds of msec = tenths of second
tbronez 1:3057ad6a5d4b 84 n += ((*q++) - 48)*10; // tens of msec = hundredths of second
tbronez 1:3057ad6a5d4b 85 n += ((*q++) - 48); // ones of msec = thousandths of second
tbronez 1:3057ad6a5d4b 86 rmc.msec = n;
tbronez 1:3057ad6a5d4b 87
tbronez 1:3057ad6a5d4b 88 /**
tbronez 1:3057ad6a5d4b 89 * Find and decode field 1, GPS status, as single
tbronez 1:3057ad6a5d4b 90 * character 'A' for valid or 'V' for invalid
tbronez 1:3057ad6a5d4b 91 */
tbronez 1:3057ad6a5d4b 92 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 93 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 94 p++; // Start of field
tbronez 1:3057ad6a5d4b 95
tbronez 1:3057ad6a5d4b 96 if (*p == 'A' || *p == 'V')
tbronez 1:3057ad6a5d4b 97 rmc.status = *p;
tbronez 1:3057ad6a5d4b 98 else
tbronez 1:3057ad6a5d4b 99 rmc.status = ' ';
tbronez 1:3057ad6a5d4b 100
tbronez 1:3057ad6a5d4b 101 /**
tbronez 1:3057ad6a5d4b 102 * Find and decode field 2, latitude, formatted as ddmm.mmmm
tbronez 1:3057ad6a5d4b 103 */
tbronez 1:3057ad6a5d4b 104 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 105 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 106 p++; // Start of field
tbronez 1:3057ad6a5d4b 107
tbronez 1:3057ad6a5d4b 108 q = p;
tbronez 1:3057ad6a5d4b 109 d = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 110 d += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 111 rmc.lat_dd = d; // whole degrees
embeddedartists 0:bd0fe2412980 112
tbronez 1:3057ad6a5d4b 113 d = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 114 d += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 115 q++; // decimal point
tbronez 1:3057ad6a5d4b 116 d += ((*q++) - 48)*0.1000; // tenths
tbronez 1:3057ad6a5d4b 117 d += ((*q++) - 48)*0.0100; // hundredths
tbronez 1:3057ad6a5d4b 118 d += ((*q++) - 48)*0.0010; // thousandths
tbronez 1:3057ad6a5d4b 119 d += ((*q++) - 48)*0.0001; // ten-thousandths
tbronez 1:3057ad6a5d4b 120 if (*q == ',')
tbronez 1:3057ad6a5d4b 121 rmc.lat_dd += sixtieth*d; // decimal degrees
tbronez 1:3057ad6a5d4b 122 else
tbronez 1:3057ad6a5d4b 123 rmc.lat_dd = NAN; // Unexpected
tbronez 1:3057ad6a5d4b 124
tbronez 1:3057ad6a5d4b 125 /**
tbronez 1:3057ad6a5d4b 126 * Find and decode field 3, latitude sense, as single
tbronez 1:3057ad6a5d4b 127 * character 'N' for north or 'S' for south
tbronez 1:3057ad6a5d4b 128 */
tbronez 1:3057ad6a5d4b 129 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 130 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 131 p++; // Start of field
embeddedartists 0:bd0fe2412980 132
tbronez 1:3057ad6a5d4b 133 if (*p == 'S') rmc.lat_dd = -rmc.lat_dd;
tbronez 1:3057ad6a5d4b 134
tbronez 1:3057ad6a5d4b 135 /**
tbronez 1:3057ad6a5d4b 136 * Find and decode field 4, longitude, formatted as dddmm.mmmm
tbronez 1:3057ad6a5d4b 137 */
tbronez 1:3057ad6a5d4b 138 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 139 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 140 p++; // Start of field
tbronez 1:3057ad6a5d4b 141
tbronez 1:3057ad6a5d4b 142 q = p;
tbronez 1:3057ad6a5d4b 143 d = ((*q++) - 48)*100; // hundreds
tbronez 1:3057ad6a5d4b 144 d += ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 145 d += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 146 rmc.lon_dd = d; // whole degrees
embeddedartists 0:bd0fe2412980 147
tbronez 1:3057ad6a5d4b 148 d = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 149 d += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 150 q++; // decimal point
tbronez 1:3057ad6a5d4b 151 d += ((*q++) - 48)*0.1000; // tenths
tbronez 1:3057ad6a5d4b 152 d += ((*q++) - 48)*0.0100; // hundredths
tbronez 1:3057ad6a5d4b 153 d += ((*q++) - 48)*0.0010; // thousandths
tbronez 1:3057ad6a5d4b 154 d += ((*q++) - 48)*0.0001; // ten-thousandths
tbronez 1:3057ad6a5d4b 155 if (*q == ',')
tbronez 1:3057ad6a5d4b 156 rmc.lon_dd += sixtieth*d; // decimal degrees
tbronez 1:3057ad6a5d4b 157 else
tbronez 1:3057ad6a5d4b 158 rmc.lon_dd = NAN; // Unexpected
tbronez 1:3057ad6a5d4b 159
tbronez 1:3057ad6a5d4b 160 /**
tbronez 1:3057ad6a5d4b 161 * Find and decode field 5, longitude sense, as single
tbronez 1:3057ad6a5d4b 162 * character 'E' for east or 'W' for west
tbronez 1:3057ad6a5d4b 163 */
tbronez 1:3057ad6a5d4b 164 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 165 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 166 p++; // Start of field
tbronez 1:3057ad6a5d4b 167
tbronez 1:3057ad6a5d4b 168 if (*p == 'W') rmc.lon_dd = -rmc.lon_dd;
embeddedartists 0:bd0fe2412980 169
tbronez 1:3057ad6a5d4b 170 /**
tbronez 1:3057ad6a5d4b 171 * Find and skip field 6, speed in knots
tbronez 1:3057ad6a5d4b 172 */
tbronez 1:3057ad6a5d4b 173 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 174 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 175 p++; // Start of field
tbronez 1:3057ad6a5d4b 176
tbronez 1:3057ad6a5d4b 177 /**
tbronez 1:3057ad6a5d4b 178 * Find and skip field 7, course in degrees
tbronez 1:3057ad6a5d4b 179 */
tbronez 1:3057ad6a5d4b 180 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 181 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 182 p++; // Start of field
tbronez 1:3057ad6a5d4b 183
tbronez 1:3057ad6a5d4b 184 /**
tbronez 1:3057ad6a5d4b 185 * Find and decode field 8, UTC date, formatted as ddmmyy
tbronez 1:3057ad6a5d4b 186 * where 1<=dd<=31, 1<=mm<=12, and yy is offset from 2000
tbronez 1:3057ad6a5d4b 187 */
tbronez 1:3057ad6a5d4b 188 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 189 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 190 p++; // Start of field
tbronez 1:3057ad6a5d4b 191
tbronez 1:3057ad6a5d4b 192 q = p;
tbronez 1:3057ad6a5d4b 193 // Decode date day
tbronez 1:3057ad6a5d4b 194 n = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 195 n += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 196 rmc.gps_tm.tm_mday = n;
tbronez 1:3057ad6a5d4b 197 // Decode date month
tbronez 1:3057ad6a5d4b 198 n = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 199 n += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 200 rmc.gps_tm.tm_mon = n-1; // tm_mon runs 0-11, not 1-12
tbronez 1:3057ad6a5d4b 201 // Decode date year
tbronez 1:3057ad6a5d4b 202 n = ((*q++) - 48)*10; // tens
tbronez 1:3057ad6a5d4b 203 n += ((*q++) - 48); // ones
tbronez 1:3057ad6a5d4b 204 rmc.gps_tm.tm_year = n+100; // tm_year is offset from year 1900, not 2000
tbronez 1:3057ad6a5d4b 205
tbronez 1:3057ad6a5d4b 206 /**
tbronez 1:3057ad6a5d4b 207 * Find and skip field 9, magnetic variation
tbronez 1:3057ad6a5d4b 208 * (not implemented in GPS firmware)
tbronez 1:3057ad6a5d4b 209 */
tbronez 1:3057ad6a5d4b 210 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 211 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 212 p++; // Start of field
tbronez 1:3057ad6a5d4b 213
tbronez 1:3057ad6a5d4b 214 /**
tbronez 1:3057ad6a5d4b 215 * Find and skip field 10, magnetic variation direction
tbronez 1:3057ad6a5d4b 216 * (not implemented in GPS firmware)
tbronez 1:3057ad6a5d4b 217 */
tbronez 1:3057ad6a5d4b 218 p = strchr(p, ','); // Next comma
tbronez 1:3057ad6a5d4b 219 if (p == NULL || *p == 0) return; // Unexpected
tbronez 1:3057ad6a5d4b 220 p++; // Start of field
embeddedartists 0:bd0fe2412980 221 }
embeddedartists 0:bd0fe2412980 222
tbronez 1:3057ad6a5d4b 223 void MTK3339::saveGGA(char* data, int dataLen) {
tbronez 1:3057ad6a5d4b 224 // See http://aprs.gids.nl/nmea/#gga for GGA sentence definition
tbronez 1:3057ad6a5d4b 225 memcpy (ggaMsg, data, min(dataLen, MSG_BUF_SZ));
tbronez 1:3057ad6a5d4b 226 }
tbronez 1:3057ad6a5d4b 227
tbronez 1:3057ad6a5d4b 228 void MTK3339::saveGSA(char* data, int dataLen) {
tbronez 1:3057ad6a5d4b 229 // See http://aprs.gids.nl/nmea/#gsa for GSA sentence definition
tbronez 1:3057ad6a5d4b 230 memcpy (gsaMsg, data, min(dataLen, MSG_BUF_SZ));
embeddedartists 0:bd0fe2412980 231 }
embeddedartists 0:bd0fe2412980 232
tbronez 1:3057ad6a5d4b 233 void MTK3339::saveGSV(char* data, int dataLen) {
tbronez 1:3057ad6a5d4b 234 // See http://aprs.gids.nl/nmea/#gsv for GSV sentence definition
tbronez 1:3057ad6a5d4b 235 memcpy (gsvMsg, data, min(dataLen, MSG_BUF_SZ));
embeddedartists 0:bd0fe2412980 236 }
embeddedartists 0:bd0fe2412980 237
tbronez 1:3057ad6a5d4b 238 void MTK3339::saveRMC(char* data, int dataLen) {
tbronez 1:3057ad6a5d4b 239 // See http://aprs.gids.nl/nmea/#rmc for RMC sentence definition
tbronez 1:3057ad6a5d4b 240 memcpy (rmcMsg, data, min(dataLen, MSG_BUF_SZ));
tbronez 1:3057ad6a5d4b 241 }
embeddedartists 0:bd0fe2412980 242
tbronez 1:3057ad6a5d4b 243 void MTK3339::saveVTG(char* data, int dataLen) {
tbronez 1:3057ad6a5d4b 244 // See http://aprs.gids.nl/nmea/#vtg for VTG sentence definition
tbronez 1:3057ad6a5d4b 245 memcpy (vtgMsg, data, min(dataLen, MSG_BUF_SZ));
tbronez 1:3057ad6a5d4b 246 }
tbronez 1:3057ad6a5d4b 247
tbronez 1:3057ad6a5d4b 248 void MTK3339::saveData(char* data, int len) {
embeddedartists 0:bd0fe2412980 249 do {
tbronez 1:3057ad6a5d4b 250 // Verify checksum
embeddedartists 0:bd0fe2412980 251 if (len < 3 || (len > 3 && data[len-3] != '*')) {
embeddedartists 0:bd0fe2412980 252 // invalid data
embeddedartists 0:bd0fe2412980 253 break;
embeddedartists 0:bd0fe2412980 254 }
embeddedartists 0:bd0fe2412980 255 int sum = strtol(&data[len-2], NULL, 16);
embeddedartists 0:bd0fe2412980 256 for(int i = 1; i < len-3; i++) {
embeddedartists 0:bd0fe2412980 257 sum ^= data[i];
embeddedartists 0:bd0fe2412980 258 }
embeddedartists 0:bd0fe2412980 259 if (sum != 0) {
embeddedartists 0:bd0fe2412980 260 // invalid checksum
embeddedartists 0:bd0fe2412980 261 break;
tbronez 1:3057ad6a5d4b 262 }
tbronez 1:3057ad6a5d4b 263
tbronez 1:3057ad6a5d4b 264 // Save appropriate sentence for later decoding
tbronez 1:3057ad6a5d4b 265 if (strncmp("$GPRMC", data, 6) == 0 && (_sentenceMask & NMEA_RMC) != 0) {
tbronez 1:3057ad6a5d4b 266 flashLED2();
tbronez 1:3057ad6a5d4b 267 saveRMC(data, len);
tbronez 1:3057ad6a5d4b 268 _availDataType = NMEA_RMC;
embeddedartists 0:bd0fe2412980 269 _dataCallback.call();
tbronez 1:3057ad6a5d4b 270 _availDataType = NMEA_NONE;
tbronez 1:3057ad6a5d4b 271 }
tbronez 1:3057ad6a5d4b 272 else if (strncmp("$GPGGA", data, 6) == 0 && (_sentenceMask & NMEA_GGA) != 0) {
tbronez 1:3057ad6a5d4b 273 saveGGA(data, len);
tbronez 1:3057ad6a5d4b 274 _availDataType = NMEA_GGA;
tbronez 1:3057ad6a5d4b 275 _dataCallback.call();
tbronez 1:3057ad6a5d4b 276 _availDataType = NMEA_NONE;
embeddedartists 0:bd0fe2412980 277 }
tbronez 1:3057ad6a5d4b 278 else if (strncmp("$GPGSA", data, 6) == 0 && (_sentenceMask & NMEA_GSA) != 0) {
tbronez 1:3057ad6a5d4b 279 saveGSA(data, len);
tbronez 1:3057ad6a5d4b 280 _availDataType = NMEA_GSA;
embeddedartists 0:bd0fe2412980 281 _dataCallback.call();
tbronez 1:3057ad6a5d4b 282 _availDataType = NMEA_NONE;
tbronez 1:3057ad6a5d4b 283 }
tbronez 1:3057ad6a5d4b 284 else if (strncmp("$GPGSV", data, 6) == 0 && (_sentenceMask & NMEA_GSV) != 0) {
tbronez 1:3057ad6a5d4b 285 saveGSV(data, len);
tbronez 1:3057ad6a5d4b 286 _availDataType = NMEA_GSV;
tbronez 1:3057ad6a5d4b 287 _dataCallback.call();
tbronez 1:3057ad6a5d4b 288 _availDataType = NMEA_NONE;
tbronez 1:3057ad6a5d4b 289 }
tbronez 1:3057ad6a5d4b 290 else if (strncmp("$GPVTG", data, 6) == 0 && (_sentenceMask & NMEA_VTG) != 0) {
tbronez 1:3057ad6a5d4b 291 saveVTG(data, len);
tbronez 1:3057ad6a5d4b 292 _availDataType = NMEA_VTG;
tbronez 1:3057ad6a5d4b 293 _dataCallback.call();
tbronez 1:3057ad6a5d4b 294 _availDataType = NMEA_NONE;
tbronez 1:3057ad6a5d4b 295 }
embeddedartists 0:bd0fe2412980 296 } while(0);
embeddedartists 0:bd0fe2412980 297 }
embeddedartists 0:bd0fe2412980 298
embeddedartists 0:bd0fe2412980 299 void MTK3339::uartIrq() {
embeddedartists 0:bd0fe2412980 300 char d = 0;
embeddedartists 0:bd0fe2412980 301 while(_serial.readable()) {
embeddedartists 0:bd0fe2412980 302 d = _serial.getc();
embeddedartists 0:bd0fe2412980 303 switch(_state) {
embeddedartists 0:bd0fe2412980 304 case StateStart:
embeddedartists 0:bd0fe2412980 305 if (d == '$') {
embeddedartists 0:bd0fe2412980 306 _buf[0] = '$';
embeddedartists 0:bd0fe2412980 307 _bufPos = 1;
embeddedartists 0:bd0fe2412980 308 _state = StateData;
embeddedartists 0:bd0fe2412980 309 }
embeddedartists 0:bd0fe2412980 310 break;
embeddedartists 0:bd0fe2412980 311 case StateData:
embeddedartists 0:bd0fe2412980 312 if (_bufPos >= MTK3339_BUF_SZ) {
embeddedartists 0:bd0fe2412980 313 // error
embeddedartists 0:bd0fe2412980 314 _state = StateStart;
embeddedartists 0:bd0fe2412980 315 }
embeddedartists 0:bd0fe2412980 316 else if (d == '\r') {
embeddedartists 0:bd0fe2412980 317 _buf[_bufPos] = 0;
tbronez 1:3057ad6a5d4b 318 saveData(_buf, _bufPos);
embeddedartists 0:bd0fe2412980 319 _state = StateStart;
embeddedartists 0:bd0fe2412980 320 }
embeddedartists 0:bd0fe2412980 321 else {
embeddedartists 0:bd0fe2412980 322 _buf[_bufPos++] = d;
embeddedartists 0:bd0fe2412980 323 }
embeddedartists 0:bd0fe2412980 324 break;
embeddedartists 0:bd0fe2412980 325 }
embeddedartists 0:bd0fe2412980 326 }
embeddedartists 0:bd0fe2412980 327 }
tbronez 1:3057ad6a5d4b 328