NMEA GPS receiver

Dependents:   lmic_NAmote_GPS_tjm lmic_NAmote_GPS_tjm LoRaWAN-NAMote72-Application-Demo_IoTium LoRaWAN-NAMote72-BVS-confirmed-tester-0-7v1_copy ... more

Committer:
Wayne Roberts
Date:
Thu Jan 03 16:10:58 2019 -0800
Revision:
6:65fdafeb57e0
Parent:
5:d3a60fb94d0e
make serial port public and change to raw to get rx bytes in ISR unlocked

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:0bd73064b7f6 1 #include "mbed.h"
dudmuck 0:0bd73064b7f6 2 #include "gps.h"
dudmuck 0:0bd73064b7f6 3
dudmuck 1:2f5fbb33ae8b 4 #define LAT_UNFIXED 0xaaaaa9
dudmuck 1:2f5fbb33ae8b 5 #define LONG_UNFIXED 0x355554e
dudmuck 1:2f5fbb33ae8b 6
dudmuck 0:0bd73064b7f6 7 const char NmeaDataTypeGPGGA[] = "GPGGA";
dudmuck 0:0bd73064b7f6 8 //const char NmeaDataTypeGPGSA[] = "GPGSA";
dudmuck 0:0bd73064b7f6 9 //const char NmeaDataTypeGPGSV[] = "GPGSV";
dudmuck 0:0bd73064b7f6 10 const char NmeaDataTypeGPRMC[] = "GPRMC";
dudmuck 0:0bd73064b7f6 11
dudmuck 0:0bd73064b7f6 12 /* Value used for the conversion of the position from DMS to decimal */
dudmuck 0:0bd73064b7f6 13 const int32_t MaxNorthPosition = 8388607; // 2^23 - 1
dudmuck 0:0bd73064b7f6 14 const int32_t MaxSouthPosition = 8388608; // -2^23
dudmuck 0:0bd73064b7f6 15 const int32_t MaxEastPosition = 8388607; // 2^23 - 1
dudmuck 0:0bd73064b7f6 16 const int32_t MaxWestPosition = 8388608; // -2^23
dudmuck 0:0bd73064b7f6 17
dudmuck 2:b531881123bf 18 //InterruptIn pps_pin(PC_5);
dudmuck 0:0bd73064b7f6 19
dudmuck 2:b531881123bf 20
dudmuck 2:b531881123bf 21 GPS::GPS(PinName uart_tx, PinName uart_rx, PinName en) : m_uart(uart_tx, uart_rx), m_en_pin(en)
dudmuck 0:0bd73064b7f6 22 {
dudmuck 1:2f5fbb33ae8b 23 have_fix = false;
dudmuck 1:2f5fbb33ae8b 24 }
dudmuck 0:0bd73064b7f6 25
dudmuck 0:0bd73064b7f6 26 GPS::~GPS()
dudmuck 0:0bd73064b7f6 27 {
dudmuck 0:0bd73064b7f6 28 }
dudmuck 0:0bd73064b7f6 29
dudmuck 2:b531881123bf 30 /*void GPS::pps()
dudmuck 0:0bd73064b7f6 31 {
dudmuck 0:0bd73064b7f6 32 pps_occurred = true;
dudmuck 2:b531881123bf 33 }*/
dudmuck 0:0bd73064b7f6 34
dudmuck 0:0bd73064b7f6 35 void GPS::on_uart_rx()
dudmuck 0:0bd73064b7f6 36 {
dudmuck 0:0bd73064b7f6 37 //uint8_t *len = &rx_buf_lens[rx_bufs_in_idx];
dudmuck 0:0bd73064b7f6 38 uint8_t len = rx_buf_lens[rx_bufs_in_idx];
dudmuck 0:0bd73064b7f6 39 char ch;
dudmuck 0:0bd73064b7f6 40
dudmuck 0:0bd73064b7f6 41 do {
dudmuck 2:b531881123bf 42 ch = m_uart.getc();
dudmuck 0:0bd73064b7f6 43
dudmuck 0:0bd73064b7f6 44 if (ch != '$') {
dudmuck 0:0bd73064b7f6 45 if (len < RX_BUF_SIZE) {
dudmuck 0:0bd73064b7f6 46 rx_bufs[rx_bufs_in_idx][len] = ch;
dudmuck 0:0bd73064b7f6 47 rx_buf_lens[rx_bufs_in_idx]++;
dudmuck 4:b8c049fa7db2 48 } /*else
dudmuck 4:b8c049fa7db2 49 printf("S");*/
dudmuck 4:b8c049fa7db2 50 } /*else if (len != 0) {
dudmuck 0:0bd73064b7f6 51 printf("$ at %d\r\n", len);
dudmuck 4:b8c049fa7db2 52 }*/
dudmuck 0:0bd73064b7f6 53
dudmuck 0:0bd73064b7f6 54 if (ch == '\n') {
dudmuck 0:0bd73064b7f6 55 rx_bufs[rx_bufs_in_idx][len] = 0; // null terminate
dudmuck 0:0bd73064b7f6 56 if (++rx_bufs_in_idx == NUM_RX_BUFS)
dudmuck 0:0bd73064b7f6 57 rx_bufs_in_idx = 0;
dudmuck 0:0bd73064b7f6 58 /* just let it overflow -- if (rx_bufs_in_idx == rx_bufs_out_idx)
dudmuck 0:0bd73064b7f6 59 printf("gps overflow\r\n");*/
dudmuck 0:0bd73064b7f6 60 rx_buf_lens[rx_bufs_in_idx] = 0;
dudmuck 0:0bd73064b7f6 61 }
dudmuck 2:b531881123bf 62 } while (m_uart.readable());
dudmuck 0:0bd73064b7f6 63 }
dudmuck 0:0bd73064b7f6 64
dudmuck 0:0bd73064b7f6 65 void GPS::init()
dudmuck 0:0bd73064b7f6 66 {
dudmuck 0:0bd73064b7f6 67 rx_bufs_in_idx = 0;
dudmuck 0:0bd73064b7f6 68 rx_buf_lens[rx_bufs_in_idx] = 0;
dudmuck 0:0bd73064b7f6 69 rx_bufs_out_idx = 0;
dudmuck 0:0bd73064b7f6 70
Wayne Roberts 5:d3a60fb94d0e 71 m_uart.attach(callback(this, &GPS::on_uart_rx));
dudmuck 0:0bd73064b7f6 72
dudmuck 2:b531881123bf 73 //pps_pin.rise(this, &GPS::pps);
dudmuck 0:0bd73064b7f6 74 }
dudmuck 0:0bd73064b7f6 75
dudmuck 0:0bd73064b7f6 76 void GPS::enable(bool en)
dudmuck 0:0bd73064b7f6 77 {
dudmuck 0:0bd73064b7f6 78 if (en) {
dudmuck 3:03d7275dc4fd 79 if (en_invert)
dudmuck 3:03d7275dc4fd 80 m_en_pin = 0;
dudmuck 3:03d7275dc4fd 81 else
dudmuck 3:03d7275dc4fd 82 m_en_pin = 1;
dudmuck 0:0bd73064b7f6 83 } else {
dudmuck 3:03d7275dc4fd 84 if (en_invert)
dudmuck 3:03d7275dc4fd 85 m_en_pin = 1;
dudmuck 3:03d7275dc4fd 86 else
dudmuck 3:03d7275dc4fd 87 m_en_pin = 0;
dudmuck 0:0bd73064b7f6 88 }
dudmuck 1:2f5fbb33ae8b 89
dudmuck 1:2f5fbb33ae8b 90 // reset current string index
dudmuck 1:2f5fbb33ae8b 91 rx_buf_lens[rx_bufs_in_idx] = 0;
dudmuck 0:0bd73064b7f6 92 }
dudmuck 0:0bd73064b7f6 93
dudmuck 0:0bd73064b7f6 94 bool GPS::enabled()
dudmuck 0:0bd73064b7f6 95 {
dudmuck 3:03d7275dc4fd 96 if (en_invert)
dudmuck 3:03d7275dc4fd 97 return !m_en_pin.read();
dudmuck 3:03d7275dc4fd 98 else
dudmuck 3:03d7275dc4fd 99 return m_en_pin.read();
dudmuck 0:0bd73064b7f6 100 }
dudmuck 0:0bd73064b7f6 101
dudmuck 0:0bd73064b7f6 102 /*char GPS::Nibble2HexChar( char a );
dudmuck 0:0bd73064b7f6 103 {
dudmuck 0:0bd73064b7f6 104 if( a < 10 )
dudmuck 0:0bd73064b7f6 105 {
dudmuck 0:0bd73064b7f6 106 return '0' + a;
dudmuck 0:0bd73064b7f6 107 }
dudmuck 0:0bd73064b7f6 108 else if( a < 16 )
dudmuck 0:0bd73064b7f6 109 {
dudmuck 0:0bd73064b7f6 110 return 'A' + ( a - 10 );
dudmuck 0:0bd73064b7f6 111 }
dudmuck 0:0bd73064b7f6 112 else
dudmuck 0:0bd73064b7f6 113 {
dudmuck 0:0bd73064b7f6 114 return '?';
dudmuck 0:0bd73064b7f6 115 }
dudmuck 0:0bd73064b7f6 116 }*/
dudmuck 0:0bd73064b7f6 117
dudmuck 0:0bd73064b7f6 118 int GPS::NmeaChecksum( char *nmeaStr, uint8_t nmeaStrSize, char * checksum )
dudmuck 0:0bd73064b7f6 119 {
dudmuck 0:0bd73064b7f6 120 int i = 0;
dudmuck 0:0bd73064b7f6 121 uint8_t checkNum = 0;
dudmuck 0:0bd73064b7f6 122
dudmuck 0:0bd73064b7f6 123 // Check input parameters
dudmuck 0:0bd73064b7f6 124 if( ( nmeaStr == NULL ) || ( checksum == NULL ) || ( nmeaStrSize <= 1 ) )
dudmuck 0:0bd73064b7f6 125 {
dudmuck 0:0bd73064b7f6 126 return -1;
dudmuck 0:0bd73064b7f6 127 }
dudmuck 0:0bd73064b7f6 128
dudmuck 0:0bd73064b7f6 129 // Skip the first '$' if necessary
dudmuck 0:0bd73064b7f6 130 if( nmeaStr[i] == '$' )
dudmuck 0:0bd73064b7f6 131 {
dudmuck 0:0bd73064b7f6 132 i += 1;
dudmuck 0:0bd73064b7f6 133 }
dudmuck 0:0bd73064b7f6 134
dudmuck 0:0bd73064b7f6 135 // XOR until '*' or max length is reached
dudmuck 0:0bd73064b7f6 136 while( nmeaStr[i] != '*' )
dudmuck 0:0bd73064b7f6 137 {
dudmuck 0:0bd73064b7f6 138 checkNum ^= nmeaStr[i];
dudmuck 0:0bd73064b7f6 139 i += 1;
dudmuck 0:0bd73064b7f6 140 if( i >= nmeaStrSize )
dudmuck 0:0bd73064b7f6 141 {
dudmuck 0:0bd73064b7f6 142 return -1;
dudmuck 0:0bd73064b7f6 143 }
dudmuck 0:0bd73064b7f6 144 }
dudmuck 0:0bd73064b7f6 145
dudmuck 0:0bd73064b7f6 146 // Convert checksum value to 2 hexadecimal characters
dudmuck 0:0bd73064b7f6 147 /*checksum[0] = Nibble2HexChar( checkNum / 16 ); // upper nibble
dudmuck 0:0bd73064b7f6 148 checksum[1] = Nibble2HexChar( checkNum % 16 ); // lower nibble
dudmuck 0:0bd73064b7f6 149 */
dudmuck 0:0bd73064b7f6 150 sprintf(checksum, "%02X", checkNum);
dudmuck 0:0bd73064b7f6 151
dudmuck 0:0bd73064b7f6 152 return i + 1;
dudmuck 0:0bd73064b7f6 153 }
dudmuck 0:0bd73064b7f6 154
dudmuck 0:0bd73064b7f6 155 bool GPS::NmeaValidateChecksum(int idx)
dudmuck 0:0bd73064b7f6 156 {
dudmuck 0:0bd73064b7f6 157 int checksumIndex;
dudmuck 0:0bd73064b7f6 158 char checksum[4];
dudmuck 0:0bd73064b7f6 159 char *NmeaString = rx_bufs[idx];
dudmuck 0:0bd73064b7f6 160
dudmuck 0:0bd73064b7f6 161 checksumIndex = NmeaChecksum( NmeaString, rx_buf_lens[idx], checksum );
dudmuck 0:0bd73064b7f6 162
dudmuck 0:0bd73064b7f6 163 // could we calculate a verification checksum ?
dudmuck 0:0bd73064b7f6 164 if( checksumIndex < 0 )
dudmuck 0:0bd73064b7f6 165 {
dudmuck 4:b8c049fa7db2 166 //printf("gps:checksumIndex:%d\r\n", checksumIndex);
dudmuck 0:0bd73064b7f6 167 return false;
dudmuck 0:0bd73064b7f6 168 }
dudmuck 0:0bd73064b7f6 169
dudmuck 0:0bd73064b7f6 170 // check if there are enough char in the serial buffer to read checksum
dudmuck 0:0bd73064b7f6 171 if( checksumIndex >= ( rx_buf_lens[idx] - 2 ) )
dudmuck 0:0bd73064b7f6 172 {
dudmuck 4:b8c049fa7db2 173 //printf("gps:checksumIndex:%d\r\n", checksumIndex);
dudmuck 0:0bd73064b7f6 174 return false;
dudmuck 0:0bd73064b7f6 175 }
dudmuck 0:0bd73064b7f6 176
dudmuck 0:0bd73064b7f6 177 // check the checksum
dudmuck 0:0bd73064b7f6 178 if( ( NmeaString[checksumIndex] == checksum[0] ) && ( NmeaString[checksumIndex + 1] == checksum[1] ) )
dudmuck 0:0bd73064b7f6 179 {
dudmuck 0:0bd73064b7f6 180 return true;
dudmuck 0:0bd73064b7f6 181 }
dudmuck 0:0bd73064b7f6 182 else
dudmuck 0:0bd73064b7f6 183 {
dudmuck 0:0bd73064b7f6 184 if (verbose)
dudmuck 0:0bd73064b7f6 185 printf("gps:checksum fail idx:%d %c%c %c%c\r\n", checksumIndex, checksum[0], checksum[1], NmeaString[checksumIndex], NmeaString[checksumIndex+1]);
dudmuck 0:0bd73064b7f6 186 return false;
dudmuck 0:0bd73064b7f6 187 }
dudmuck 0:0bd73064b7f6 188 }
dudmuck 0:0bd73064b7f6 189
dudmuck 0:0bd73064b7f6 190 void GPS::ConvertPositionFromStringToNumerical( )
dudmuck 0:0bd73064b7f6 191 {
dudmuck 0:0bd73064b7f6 192 int i;
dudmuck 0:0bd73064b7f6 193
dudmuck 0:0bd73064b7f6 194 double valueTmp1;
dudmuck 0:0bd73064b7f6 195 double valueTmp2;
dudmuck 0:0bd73064b7f6 196 double valueTmp3;
dudmuck 0:0bd73064b7f6 197 double valueTmp4;
dudmuck 0:0bd73064b7f6 198
dudmuck 0:0bd73064b7f6 199 // Convert the latitude from ASCII to uint8_t values
dudmuck 0:0bd73064b7f6 200 for( i = 0 ; i < 10 ; i++ )
dudmuck 0:0bd73064b7f6 201 {
dudmuck 0:0bd73064b7f6 202 NmeaGpsData.NmeaLatitude[i] = NmeaGpsData.NmeaLatitude[i] & 0xF;
dudmuck 0:0bd73064b7f6 203 }
dudmuck 0:0bd73064b7f6 204 // Convert latitude from degree/minute/second (DMS) format into decimal
dudmuck 0:0bd73064b7f6 205 valueTmp1 = ( double )NmeaGpsData.NmeaLatitude[0] * 10.0 + ( double )NmeaGpsData.NmeaLatitude[1];
dudmuck 0:0bd73064b7f6 206 valueTmp2 = ( double )NmeaGpsData.NmeaLatitude[2] * 10.0 + ( double )NmeaGpsData.NmeaLatitude[3];
dudmuck 0:0bd73064b7f6 207 valueTmp3 = ( double )NmeaGpsData.NmeaLatitude[5] * 1000.0 + ( double )NmeaGpsData.NmeaLatitude[6] * 100.0 +
dudmuck 0:0bd73064b7f6 208 ( double )NmeaGpsData.NmeaLatitude[7] * 10.0 + ( double )NmeaGpsData.NmeaLatitude[8];
dudmuck 0:0bd73064b7f6 209
dudmuck 0:0bd73064b7f6 210 Latitude = valueTmp1 + ( ( valueTmp2 + ( valueTmp3 * 0.0001 ) ) / 60.0 );
dudmuck 0:0bd73064b7f6 211
dudmuck 0:0bd73064b7f6 212 if( NmeaGpsData.NmeaLatitudePole[0] == 'S' )
dudmuck 0:0bd73064b7f6 213 {
dudmuck 0:0bd73064b7f6 214 Latitude *= -1;
dudmuck 0:0bd73064b7f6 215 }
dudmuck 0:0bd73064b7f6 216
dudmuck 0:0bd73064b7f6 217 // Convert the longitude from ASCII to uint8_t values
dudmuck 0:0bd73064b7f6 218 for( i = 0 ; i < 10 ; i++ )
dudmuck 0:0bd73064b7f6 219 {
dudmuck 0:0bd73064b7f6 220 NmeaGpsData.NmeaLongitude[i] = NmeaGpsData.NmeaLongitude[i] & 0xF;
dudmuck 0:0bd73064b7f6 221 }
dudmuck 0:0bd73064b7f6 222 // Convert longitude from degree/minute/second (DMS) format into decimal
dudmuck 0:0bd73064b7f6 223 valueTmp1 = ( double )NmeaGpsData.NmeaLongitude[0] * 100.0 + ( double )NmeaGpsData.NmeaLongitude[1] * 10.0 + ( double )NmeaGpsData.NmeaLongitude[2];
dudmuck 0:0bd73064b7f6 224 valueTmp2 = ( double )NmeaGpsData.NmeaLongitude[3] * 10.0 + ( double )NmeaGpsData.NmeaLongitude[4];
dudmuck 0:0bd73064b7f6 225 valueTmp3 = ( double )NmeaGpsData.NmeaLongitude[6] * 1000.0 + ( double )NmeaGpsData.NmeaLongitude[7] * 100;
dudmuck 0:0bd73064b7f6 226 valueTmp4 = ( double )NmeaGpsData.NmeaLongitude[8] * 10.0 + ( double )NmeaGpsData.NmeaLongitude[9];
dudmuck 0:0bd73064b7f6 227
dudmuck 0:0bd73064b7f6 228 Longitude = valueTmp1 + ( valueTmp2 / 60.0 ) + ( ( ( valueTmp3 + valueTmp4 ) * 0.0001 ) / 60.0 );
dudmuck 0:0bd73064b7f6 229
dudmuck 0:0bd73064b7f6 230 if( NmeaGpsData.NmeaLongitudePole[0] == 'W' )
dudmuck 0:0bd73064b7f6 231 {
dudmuck 0:0bd73064b7f6 232 Longitude *= -1;
dudmuck 0:0bd73064b7f6 233 }
dudmuck 0:0bd73064b7f6 234
dudmuck 0:0bd73064b7f6 235 //printf("DD %f, %f\r\n", Latitude, Longitude);
dudmuck 0:0bd73064b7f6 236 }
dudmuck 0:0bd73064b7f6 237
dudmuck 0:0bd73064b7f6 238 void GPS::ConvertPositionIntoBinary( )
dudmuck 0:0bd73064b7f6 239 {
dudmuck 0:0bd73064b7f6 240 long double temp;
dudmuck 0:0bd73064b7f6 241
dudmuck 0:0bd73064b7f6 242 if( Latitude >= 0 ) // North
dudmuck 0:0bd73064b7f6 243 {
dudmuck 0:0bd73064b7f6 244 temp = Latitude * MaxNorthPosition;
dudmuck 0:0bd73064b7f6 245 LatitudeBinary = temp / 90;
dudmuck 0:0bd73064b7f6 246 }
dudmuck 0:0bd73064b7f6 247 else // South
dudmuck 0:0bd73064b7f6 248 {
dudmuck 0:0bd73064b7f6 249 temp = Latitude * MaxSouthPosition;
dudmuck 0:0bd73064b7f6 250 LatitudeBinary = temp / 90;
dudmuck 0:0bd73064b7f6 251 }
dudmuck 0:0bd73064b7f6 252
dudmuck 0:0bd73064b7f6 253 if( Longitude >= 0 ) // East
dudmuck 0:0bd73064b7f6 254 {
dudmuck 0:0bd73064b7f6 255 temp = Longitude * MaxEastPosition;
dudmuck 0:0bd73064b7f6 256 LongitudeBinary = temp / 180;
dudmuck 0:0bd73064b7f6 257 }
dudmuck 0:0bd73064b7f6 258 else // West
dudmuck 0:0bd73064b7f6 259 {
dudmuck 0:0bd73064b7f6 260 temp = Longitude * MaxWestPosition;
dudmuck 0:0bd73064b7f6 261 LongitudeBinary = temp / 180;
dudmuck 0:0bd73064b7f6 262 }
dudmuck 1:2f5fbb33ae8b 263
dudmuck 1:2f5fbb33ae8b 264 //printf("binary: %x %x\r\n", LatitudeBinary, LongitudeBinary);
dudmuck 1:2f5fbb33ae8b 265 if (LatitudeBinary == LAT_UNFIXED && LongitudeBinary == LONG_UNFIXED)
dudmuck 1:2f5fbb33ae8b 266 have_fix = false;
dudmuck 1:2f5fbb33ae8b 267 else
dudmuck 1:2f5fbb33ae8b 268 have_fix = true;
dudmuck 0:0bd73064b7f6 269 }
dudmuck 0:0bd73064b7f6 270
dudmuck 0:0bd73064b7f6 271 int GPS::ParseGPSData(int idx)
dudmuck 0:0bd73064b7f6 272 {
dudmuck 0:0bd73064b7f6 273 uint8_t i, j, fieldSize;
dudmuck 0:0bd73064b7f6 274 char *NmeaString;
dudmuck 0:0bd73064b7f6 275
dudmuck 0:0bd73064b7f6 276 if (NmeaValidateChecksum(idx) == false) {
dudmuck 0:0bd73064b7f6 277 if (verbose)
dudmuck 0:0bd73064b7f6 278 printf("gps:bad nmea checksum:%s\r\n", rx_bufs[rx_bufs_out_idx]);
dudmuck 0:0bd73064b7f6 279 return FAIL;
dudmuck 0:0bd73064b7f6 280 }
dudmuck 0:0bd73064b7f6 281
dudmuck 0:0bd73064b7f6 282 NmeaString = rx_bufs[idx];
dudmuck 1:2f5fbb33ae8b 283
dudmuck 1:2f5fbb33ae8b 284 if (NmeaString[0] == 'P' && NmeaString[1] == 'M' && NmeaString[2] == 'T' && NmeaString[3] == 'K') {
dudmuck 1:2f5fbb33ae8b 285 /* anything useful from PMTK packets? */
dudmuck 1:2f5fbb33ae8b 286 return SUCCESS;
dudmuck 1:2f5fbb33ae8b 287 }
dudmuck 1:2f5fbb33ae8b 288
dudmuck 0:0bd73064b7f6 289 fieldSize = 0;
dudmuck 0:0bd73064b7f6 290 i = 0;
dudmuck 0:0bd73064b7f6 291 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 292 {
dudmuck 0:0bd73064b7f6 293 if( fieldSize > 6 )
dudmuck 0:0bd73064b7f6 294 {
dudmuck 1:2f5fbb33ae8b 295 printf("gps parse:%s\r\n", NmeaString);
dudmuck 0:0bd73064b7f6 296 return FAIL;
dudmuck 0:0bd73064b7f6 297 }
dudmuck 0:0bd73064b7f6 298 }
dudmuck 0:0bd73064b7f6 299
dudmuck 0:0bd73064b7f6 300 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 301 {
dudmuck 0:0bd73064b7f6 302 NmeaGpsData.NmeaDataType[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 303 }
dudmuck 0:0bd73064b7f6 304 // Parse the GPGGA data
dudmuck 0:0bd73064b7f6 305 if( strncmp( ( const char* )NmeaGpsData.NmeaDataType, ( const char* )NmeaDataTypeGPGGA, 5 ) == 0 )
dudmuck 0:0bd73064b7f6 306 {
dudmuck 0:0bd73064b7f6 307 // NmeaUtcTime
dudmuck 0:0bd73064b7f6 308 fieldSize = 0;
dudmuck 0:0bd73064b7f6 309 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 310 {
dudmuck 0:0bd73064b7f6 311 if( fieldSize > 11 )
dudmuck 0:0bd73064b7f6 312 {
dudmuck 0:0bd73064b7f6 313 return FAIL;
dudmuck 0:0bd73064b7f6 314 }
dudmuck 0:0bd73064b7f6 315 }
dudmuck 0:0bd73064b7f6 316 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 317 {
dudmuck 0:0bd73064b7f6 318 NmeaGpsData.NmeaUtcTime[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 319 }
dudmuck 0:0bd73064b7f6 320 // NmeaLatitude
dudmuck 0:0bd73064b7f6 321 fieldSize = 0;
dudmuck 0:0bd73064b7f6 322 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 323 {
dudmuck 0:0bd73064b7f6 324 if( fieldSize > 10 )
dudmuck 0:0bd73064b7f6 325 {
dudmuck 0:0bd73064b7f6 326 return FAIL;
dudmuck 0:0bd73064b7f6 327 }
dudmuck 0:0bd73064b7f6 328 }
dudmuck 0:0bd73064b7f6 329 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 330 {
dudmuck 0:0bd73064b7f6 331 NmeaGpsData.NmeaLatitude[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 332 }
dudmuck 0:0bd73064b7f6 333 // NmeaLatitudePole
dudmuck 0:0bd73064b7f6 334 fieldSize = 0;
dudmuck 0:0bd73064b7f6 335 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 336 {
dudmuck 0:0bd73064b7f6 337 if( fieldSize > 2 )
dudmuck 0:0bd73064b7f6 338 {
dudmuck 0:0bd73064b7f6 339 return FAIL;
dudmuck 0:0bd73064b7f6 340 }
dudmuck 0:0bd73064b7f6 341 }
dudmuck 0:0bd73064b7f6 342 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 343 {
dudmuck 0:0bd73064b7f6 344 NmeaGpsData.NmeaLatitudePole[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 345 }
dudmuck 0:0bd73064b7f6 346 // NmeaLongitude
dudmuck 0:0bd73064b7f6 347 fieldSize = 0;
dudmuck 0:0bd73064b7f6 348 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 349 {
dudmuck 0:0bd73064b7f6 350 if( fieldSize > 11 )
dudmuck 0:0bd73064b7f6 351 {
dudmuck 0:0bd73064b7f6 352 return FAIL;
dudmuck 0:0bd73064b7f6 353 }
dudmuck 0:0bd73064b7f6 354 }
dudmuck 0:0bd73064b7f6 355 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 356 {
dudmuck 0:0bd73064b7f6 357 NmeaGpsData.NmeaLongitude[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 358 }
dudmuck 0:0bd73064b7f6 359 // NmeaLongitudePole
dudmuck 0:0bd73064b7f6 360 fieldSize = 0;
dudmuck 0:0bd73064b7f6 361 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 362 {
dudmuck 0:0bd73064b7f6 363 if( fieldSize > 2 )
dudmuck 0:0bd73064b7f6 364 {
dudmuck 0:0bd73064b7f6 365 return FAIL;
dudmuck 0:0bd73064b7f6 366 }
dudmuck 0:0bd73064b7f6 367 }
dudmuck 0:0bd73064b7f6 368 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 369 {
dudmuck 0:0bd73064b7f6 370 NmeaGpsData.NmeaLongitudePole[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 371 }
dudmuck 0:0bd73064b7f6 372 // NmeaFixQuality
dudmuck 0:0bd73064b7f6 373 fieldSize = 0;
dudmuck 0:0bd73064b7f6 374 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 375 {
dudmuck 0:0bd73064b7f6 376 if( fieldSize > 2 )
dudmuck 0:0bd73064b7f6 377 {
dudmuck 0:0bd73064b7f6 378 return FAIL;
dudmuck 0:0bd73064b7f6 379 }
dudmuck 0:0bd73064b7f6 380 }
dudmuck 0:0bd73064b7f6 381 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 382 {
dudmuck 0:0bd73064b7f6 383 NmeaGpsData.NmeaFixQuality[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 384 }
dudmuck 0:0bd73064b7f6 385 // NmeaSatelliteTracked
dudmuck 0:0bd73064b7f6 386 fieldSize = 0;
dudmuck 0:0bd73064b7f6 387 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 388 {
dudmuck 0:0bd73064b7f6 389 if( fieldSize > 3 )
dudmuck 0:0bd73064b7f6 390 {
dudmuck 0:0bd73064b7f6 391 return FAIL;
dudmuck 0:0bd73064b7f6 392 }
dudmuck 0:0bd73064b7f6 393 }
dudmuck 0:0bd73064b7f6 394 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 395 {
dudmuck 0:0bd73064b7f6 396 NmeaGpsData.NmeaSatelliteTracked[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 397 }
dudmuck 0:0bd73064b7f6 398 // NmeaHorizontalDilution
dudmuck 0:0bd73064b7f6 399 fieldSize = 0;
dudmuck 0:0bd73064b7f6 400 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 401 {
dudmuck 0:0bd73064b7f6 402 if( fieldSize > 6 )
dudmuck 0:0bd73064b7f6 403 {
dudmuck 0:0bd73064b7f6 404 return FAIL;
dudmuck 0:0bd73064b7f6 405 }
dudmuck 0:0bd73064b7f6 406 }
dudmuck 0:0bd73064b7f6 407 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 408 {
dudmuck 0:0bd73064b7f6 409 NmeaGpsData.NmeaHorizontalDilution[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 410 }
dudmuck 0:0bd73064b7f6 411 // NmeaAltitude
dudmuck 0:0bd73064b7f6 412 fieldSize = 0;
dudmuck 0:0bd73064b7f6 413 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 414 {
dudmuck 0:0bd73064b7f6 415 if( fieldSize > 8 )
dudmuck 0:0bd73064b7f6 416 {
dudmuck 0:0bd73064b7f6 417 return FAIL;
dudmuck 0:0bd73064b7f6 418 }
dudmuck 0:0bd73064b7f6 419 }
dudmuck 0:0bd73064b7f6 420 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 421 {
dudmuck 0:0bd73064b7f6 422 NmeaGpsData.NmeaAltitude[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 423 }
dudmuck 0:0bd73064b7f6 424 // NmeaAltitudeUnit
dudmuck 0:0bd73064b7f6 425 fieldSize = 0;
dudmuck 0:0bd73064b7f6 426 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 427 {
dudmuck 0:0bd73064b7f6 428 if( fieldSize > 2 )
dudmuck 0:0bd73064b7f6 429 {
dudmuck 0:0bd73064b7f6 430 return FAIL;
dudmuck 0:0bd73064b7f6 431 }
dudmuck 0:0bd73064b7f6 432 }
dudmuck 0:0bd73064b7f6 433 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 434 {
dudmuck 0:0bd73064b7f6 435 NmeaGpsData.NmeaAltitudeUnit[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 436 }
dudmuck 0:0bd73064b7f6 437 // NmeaHeightGeoid
dudmuck 0:0bd73064b7f6 438 fieldSize = 0;
dudmuck 0:0bd73064b7f6 439 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 440 {
dudmuck 0:0bd73064b7f6 441 if( fieldSize > 8 )
dudmuck 0:0bd73064b7f6 442 {
dudmuck 0:0bd73064b7f6 443 return FAIL;
dudmuck 0:0bd73064b7f6 444 }
dudmuck 0:0bd73064b7f6 445 }
dudmuck 0:0bd73064b7f6 446 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 447 {
dudmuck 0:0bd73064b7f6 448 NmeaGpsData.NmeaHeightGeoid[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 449 }
dudmuck 0:0bd73064b7f6 450 // NmeaHeightGeoidUnit
dudmuck 0:0bd73064b7f6 451 fieldSize = 0;
dudmuck 0:0bd73064b7f6 452 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 453 {
dudmuck 0:0bd73064b7f6 454 if( fieldSize > 2 )
dudmuck 0:0bd73064b7f6 455 {
dudmuck 0:0bd73064b7f6 456 return FAIL;
dudmuck 0:0bd73064b7f6 457 }
dudmuck 0:0bd73064b7f6 458 }
dudmuck 0:0bd73064b7f6 459 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 460 {
dudmuck 0:0bd73064b7f6 461 NmeaGpsData.NmeaHeightGeoidUnit[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 462 }
dudmuck 0:0bd73064b7f6 463
dudmuck 0:0bd73064b7f6 464 //FormatGpsData( );
dudmuck 0:0bd73064b7f6 465 ConvertPositionFromStringToNumerical( );
dudmuck 0:0bd73064b7f6 466 ConvertPositionIntoBinary( );
dudmuck 0:0bd73064b7f6 467 return SUCCESS;
dudmuck 0:0bd73064b7f6 468 }
dudmuck 0:0bd73064b7f6 469 else if ( strncmp( ( const char* )NmeaGpsData.NmeaDataType, ( const char* )NmeaDataTypeGPRMC, 5 ) == 0 )
dudmuck 0:0bd73064b7f6 470 {
dudmuck 0:0bd73064b7f6 471 // NmeaUtcTime
dudmuck 0:0bd73064b7f6 472 fieldSize = 0;
dudmuck 0:0bd73064b7f6 473 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 474 {
dudmuck 0:0bd73064b7f6 475 if( fieldSize > 11 )
dudmuck 0:0bd73064b7f6 476 {
dudmuck 0:0bd73064b7f6 477 return FAIL;
dudmuck 0:0bd73064b7f6 478 }
dudmuck 0:0bd73064b7f6 479 }
dudmuck 0:0bd73064b7f6 480 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 481 {
dudmuck 0:0bd73064b7f6 482 NmeaGpsData.NmeaUtcTime[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 483 }
dudmuck 0:0bd73064b7f6 484 // NmeaDataStatus
dudmuck 0:0bd73064b7f6 485 fieldSize = 0;
dudmuck 0:0bd73064b7f6 486 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 487 {
dudmuck 0:0bd73064b7f6 488 if( fieldSize > 2 )
dudmuck 0:0bd73064b7f6 489 {
dudmuck 0:0bd73064b7f6 490 return FAIL;
dudmuck 0:0bd73064b7f6 491 }
dudmuck 0:0bd73064b7f6 492 }
dudmuck 0:0bd73064b7f6 493 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 494 {
dudmuck 0:0bd73064b7f6 495 NmeaGpsData.NmeaDataStatus[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 496 }
dudmuck 0:0bd73064b7f6 497 // NmeaLatitude
dudmuck 0:0bd73064b7f6 498 fieldSize = 0;
dudmuck 0:0bd73064b7f6 499 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 500 {
dudmuck 0:0bd73064b7f6 501 if( fieldSize > 10 )
dudmuck 0:0bd73064b7f6 502 {
dudmuck 0:0bd73064b7f6 503 return FAIL;
dudmuck 0:0bd73064b7f6 504 }
dudmuck 0:0bd73064b7f6 505 }
dudmuck 0:0bd73064b7f6 506 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 507 {
dudmuck 0:0bd73064b7f6 508 NmeaGpsData.NmeaLatitude[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 509 }
dudmuck 0:0bd73064b7f6 510 // NmeaLatitudePole
dudmuck 0:0bd73064b7f6 511 fieldSize = 0;
dudmuck 0:0bd73064b7f6 512 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 513 {
dudmuck 0:0bd73064b7f6 514 if( fieldSize > 2 )
dudmuck 0:0bd73064b7f6 515 {
dudmuck 0:0bd73064b7f6 516 return FAIL;
dudmuck 0:0bd73064b7f6 517 }
dudmuck 0:0bd73064b7f6 518 }
dudmuck 0:0bd73064b7f6 519 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 520 {
dudmuck 0:0bd73064b7f6 521 NmeaGpsData.NmeaLatitudePole[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 522 }
dudmuck 0:0bd73064b7f6 523 // NmeaLongitude
dudmuck 0:0bd73064b7f6 524 fieldSize = 0;
dudmuck 0:0bd73064b7f6 525 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 526 {
dudmuck 0:0bd73064b7f6 527 if( fieldSize > 11 )
dudmuck 0:0bd73064b7f6 528 {
dudmuck 0:0bd73064b7f6 529 return FAIL;
dudmuck 0:0bd73064b7f6 530 }
dudmuck 0:0bd73064b7f6 531 }
dudmuck 0:0bd73064b7f6 532 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 533 {
dudmuck 0:0bd73064b7f6 534 NmeaGpsData.NmeaLongitude[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 535 }
dudmuck 0:0bd73064b7f6 536 // NmeaLongitudePole
dudmuck 0:0bd73064b7f6 537 fieldSize = 0;
dudmuck 0:0bd73064b7f6 538 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 539 {
dudmuck 0:0bd73064b7f6 540 if( fieldSize > 2 )
dudmuck 0:0bd73064b7f6 541 {
dudmuck 0:0bd73064b7f6 542 return FAIL;
dudmuck 0:0bd73064b7f6 543 }
dudmuck 0:0bd73064b7f6 544 }
dudmuck 0:0bd73064b7f6 545 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 546 {
dudmuck 0:0bd73064b7f6 547 NmeaGpsData.NmeaLongitudePole[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 548 }
dudmuck 0:0bd73064b7f6 549 // NmeaSpeed
dudmuck 0:0bd73064b7f6 550 fieldSize = 0;
dudmuck 0:0bd73064b7f6 551 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 552 {
dudmuck 0:0bd73064b7f6 553 if( fieldSize > 8 )
dudmuck 0:0bd73064b7f6 554 {
dudmuck 0:0bd73064b7f6 555 return FAIL;
dudmuck 0:0bd73064b7f6 556 }
dudmuck 0:0bd73064b7f6 557 }
dudmuck 0:0bd73064b7f6 558 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 559 {
dudmuck 0:0bd73064b7f6 560 NmeaGpsData.NmeaSpeed[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 561 }
dudmuck 0:0bd73064b7f6 562 // NmeaDetectionAngle
dudmuck 0:0bd73064b7f6 563 fieldSize = 0;
dudmuck 0:0bd73064b7f6 564 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 565 {
dudmuck 0:0bd73064b7f6 566 if( fieldSize > 8 )
dudmuck 0:0bd73064b7f6 567 {
dudmuck 0:0bd73064b7f6 568 return FAIL;
dudmuck 0:0bd73064b7f6 569 }
dudmuck 0:0bd73064b7f6 570 }
dudmuck 0:0bd73064b7f6 571 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 572 {
dudmuck 0:0bd73064b7f6 573 NmeaGpsData.NmeaDetectionAngle[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 574 }
dudmuck 0:0bd73064b7f6 575 // NmeaDate
dudmuck 0:0bd73064b7f6 576 fieldSize = 0;
dudmuck 0:0bd73064b7f6 577 while( NmeaString[i + fieldSize++] != ',' )
dudmuck 0:0bd73064b7f6 578 {
dudmuck 0:0bd73064b7f6 579 if( fieldSize > 8 )
dudmuck 0:0bd73064b7f6 580 {
dudmuck 0:0bd73064b7f6 581 return FAIL;
dudmuck 0:0bd73064b7f6 582 }
dudmuck 0:0bd73064b7f6 583 }
dudmuck 0:0bd73064b7f6 584 for( j = 0; j < fieldSize; j++, i++ )
dudmuck 0:0bd73064b7f6 585 {
dudmuck 0:0bd73064b7f6 586 NmeaGpsData.NmeaDate[j] = NmeaString[i];
dudmuck 0:0bd73064b7f6 587 }
dudmuck 0:0bd73064b7f6 588
dudmuck 0:0bd73064b7f6 589 //FormatGpsData( );
dudmuck 0:0bd73064b7f6 590 ConvertPositionFromStringToNumerical( );
dudmuck 0:0bd73064b7f6 591 ConvertPositionIntoBinary( );
dudmuck 0:0bd73064b7f6 592 return SUCCESS;
dudmuck 0:0bd73064b7f6 593 }
dudmuck 0:0bd73064b7f6 594 else
dudmuck 0:0bd73064b7f6 595 {
dudmuck 0:0bd73064b7f6 596 return FAIL;
dudmuck 0:0bd73064b7f6 597 }
dudmuck 0:0bd73064b7f6 598 }
dudmuck 0:0bd73064b7f6 599
dudmuck 0:0bd73064b7f6 600 void GPS::service()
dudmuck 0:0bd73064b7f6 601 {
dudmuck 0:0bd73064b7f6 602 while (rx_bufs_in_idx != rx_bufs_out_idx) {
dudmuck 0:0bd73064b7f6 603 //printf("%02d:%s\r\n", rx_buf_lens[rx_bufs_out_idx], rx_bufs[rx_bufs_out_idx]);
dudmuck 0:0bd73064b7f6 604 if (verbose)
dudmuck 0:0bd73064b7f6 605 printf("gps:%s\r\n", rx_bufs[rx_bufs_out_idx]);
dudmuck 0:0bd73064b7f6 606 ParseGPSData(rx_bufs_out_idx);
dudmuck 0:0bd73064b7f6 607 if (++rx_bufs_out_idx == NUM_RX_BUFS)
dudmuck 0:0bd73064b7f6 608 rx_bufs_out_idx = 0;
dudmuck 0:0bd73064b7f6 609 }
dudmuck 0:0bd73064b7f6 610
dudmuck 2:b531881123bf 611 /*if (pps_occurred) {
dudmuck 0:0bd73064b7f6 612 pps_occurred = false;
dudmuck 0:0bd73064b7f6 613 if (verbose)
dudmuck 0:0bd73064b7f6 614 printf("gps:pps\r\n");
dudmuck 2:b531881123bf 615 }*/
dudmuck 0:0bd73064b7f6 616 }
dudmuck 0:0bd73064b7f6 617
dudmuck 0:0bd73064b7f6 618