Example #1
0
void TM_GPS_INT_CheckTerm(TM_GPS_Data_t* GPS_Data) {
#ifndef GPS_DISABLE_GPGSA
	static uint8_t ids_count = 0;
#endif
	uint32_t temp;
	uint8_t count;
	if (TM_GPS_Term_Number == 0) {
		/* Statement indicator */
		if (TM_GPS_INT_StringStartsWith(TM_GPS_Term, "$GPGGA")) {
			TM_GPS_Statement = GPS_GPGGA;
		} else if (TM_GPS_INT_StringStartsWith(TM_GPS_Term, "$GPRMC")) {
			TM_GPS_Statement = GPS_GPRMC;
		} else if (TM_GPS_INT_StringStartsWith(TM_GPS_Term, "$GPGSA")) {
			TM_GPS_Statement = GPS_GPGSA;
		} else if (TM_GPS_INT_StringStartsWith(TM_GPS_Term, "$GPGSV")) {
			TM_GPS_Statement = GPS_GPGSV;
		} else {
			TM_GPS_Statement = GPS_ERR;
		}
		/* Do nothing */
		return;
	}
	if (TM_GPS_Statement == GPS_ERR) {
		/* Not valid input data */
		return;
	}
	switch (GPS_CONCAT(TM_GPS_Statement, TM_GPS_Term_Number)) {
#ifndef GPS_DISABLE_GPGGA
		case GPS_POS_LATITUDE:	/* GPGGA */
			/* Convert latitude */
			count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.Latitude = (temp % 100) / 60.0;
			TM_GPS_INT_Data.Latitude += temp / 100;
		
			count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Latitude += temp / (TM_GPS_INT_Pow(10, count) * 60.0);
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_LATITUDE);
			break;
		case GPS_POS_NS: /* GPGGA */
			if (TM_GPS_Term[0] == 'S') {
				/* South has negative coordinate */
				TM_GPS_INT_Data.Latitude = -TM_GPS_INT_Data.Latitude;
			}
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_NS);
			break;
		case GPS_POS_LONGITUDE: /* GPGGA */
			/* Convert longitude */
			count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.Longitude = (temp % 100) / 60.0;
			TM_GPS_INT_Data.Longitude += temp / 100;
		
			count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Longitude += temp / (TM_GPS_INT_Pow(10, count) * 60.0);
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_LONGITUDE);
			break;
		case GPS_POS_EW: /* GPGGA */
			if (TM_GPS_Term[0] == 'W') {
				/* West has negative coordinate */
				TM_GPS_INT_Data.Longitude = -TM_GPS_INT_Data.Longitude;
			}
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_EW);
			break;
		case GPS_POS_SATS: /* GPGGA */
			/* Satellites in use */
			TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.Satellites = temp;
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_SATS);
			break;
		case GPS_POS_FIX: /* GPGGA */
			/* GPS Fix */
			TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.Fix = temp;	
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_FIX);
			break;
		case GPS_POS_ALTITUDE: /* GPGGA */
			/* Convert altitude above sea */
			if (TM_GPS_Term[0] == '-') {
				count = TM_GPS_INT_Atoi(&TM_GPS_Term[1], &temp);
				TM_GPS_INT_Data.Altitude = temp;
				
				count++;
				count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
				TM_GPS_INT_Data.Altitude += temp / (TM_GPS_INT_Pow(10, count) * 1.0);
				
				TM_GPS_INT_Data.Altitude = -TM_GPS_INT_Data.Altitude;
			} else {
				count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
				TM_GPS_INT_Data.Altitude = temp;
		
				count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
				TM_GPS_INT_Data.Altitude += temp / (TM_GPS_INT_Pow(10, count) * 1.0);
			}
			
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_ALTITUDE);
			break;
		case GPS_POS_TIME: /* GPGGA */
			/* Set time */
			count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.Time.Seconds = temp % 100;
			TM_GPS_INT_Data.Time.Minutes = (temp / 100) % 100;
			TM_GPS_INT_Data.Time.Hours = (temp / 10000) % 100;
			/* Hundredths */
			TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Time.Hundredths = temp;
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_TIME);
			break;
#endif
#ifndef GPS_DISABLE_GPRMC
		case GPS_POS_SPEED:	/* GPRMC */	
			/* Convert speed */
			count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.Speed = (float)temp;
		
			count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Speed += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0));
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_SPEED);
			break;
		case GPS_POS_DATE: /* GPRMC */	
			/* Set date */
			TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.Date.Year = temp % 100;
			TM_GPS_INT_Data.Date.Month = (temp / 100) % 100;
			TM_GPS_INT_Data.Date.Date = (temp / 10000) % 100;
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_DATE);
			break;
		case GPS_POS_VALIDITY: /* GPRMC */	
			if (TM_GPS_Term[0] == 'A') {
				/* GPS Signal valid */
				TM_GPS_INT_Data.Validity = 1;
			} else {
				/* GPS Signal not valid */
				TM_GPS_INT_Data.Validity = 0;
			}
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_VALIDITY);
			break;
		case GPS_POS_DIRECTION: /* GPRMC */
			count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.Direction = (float)temp;
		
			count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Direction += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0));
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_DIRECTION);
			break;
#endif
#ifndef GPS_DISABLE_GPGSA
		case GPS_POS_HDOP: /* GPGSA */
			count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.HDOP = (float)temp;
		
			count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
			TM_GPS_INT_Data.HDOP += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0));
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_HDOP);
			break;
		case GPS_POS_PDOP: /* GPGSA */
			count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.PDOP = (float)temp;
		
			count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
			TM_GPS_INT_Data.PDOP += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0));
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_PDOP);
			break;
		case GPS_POS_VDOP: /* GPGSA */
			count = TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.VDOP = (float)temp;
		
			count = TM_GPS_INT_Atoi(&TM_GPS_Term[++count], &temp);
			TM_GPS_INT_Data.VDOP += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0));
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_VDOP);
			break;
		case GPS_POS_FIXMODE: /* GPGSA */
			/* Satellites in view */
			TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.FixMode = temp;
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_FIXMODE);
			break;
		case GPS_POS_SAT1:
		case GPS_POS_SAT2:
		case GPS_POS_SAT3:
		case GPS_POS_SAT4:
		case GPS_POS_SAT5:
		case GPS_POS_SAT6:
		case GPS_POS_SAT7:
		case GPS_POS_SAT8:
		case GPS_POS_SAT9:
		case GPS_POS_SAT10:
		case GPS_POS_SAT11:
		case GPS_POS_SAT12:
			/* Satellite numbers */
			TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.SatelliteIDs[TM_GPS_Term_Number - 3] = temp;
		
			ids_count++;
		
			if (ids_count == TM_GPS_INT_Data.Satellites) {
				ids_count = 0;
				/* Set flag */
				
				TM_GPS_INT_SetFlag(GPS_FLAG_SATS1_12);
			}
			break;
#endif
#ifndef GPS_DISABLE_GPGSV
		case GPS_POS_SATSINVIEW: /* GPGSV */
			/* Satellites in view */
			TM_GPS_INT_Atoi(TM_GPS_Term, &temp);
			TM_GPS_INT_Data.SatellitesInView = temp;
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_SATSINVIEW);
			break;
#endif
		default: 
			break;
	}
}
void TM_GPS_INT_CheckTerm(TM_GPS_t* GPS_Data) {
	uint32_t temp;
#ifndef GPS_DISABLE_GPGSA
	static uint8_t ids_count = 0;
#endif
	uint8_t count, i;
	if (GPS_Term_Number == 0) {
		/* Statement indicator */
		if (TM_GPS_INT_StringStartsWith(GPS_Term, "$GPGGA")) {
			TM_GPS_Statement = GPS_GPGGA;
		} else if (TM_GPS_INT_StringStartsWith(GPS_Term, "$GPRMC")) {
			TM_GPS_Statement = GPS_GPRMC;
		} else if (TM_GPS_INT_StringStartsWith(GPS_Term, "$GPGSA")) {
			TM_GPS_Statement = GPS_GPGSA;
		} else if (TM_GPS_INT_StringStartsWith(GPS_Term, "$GPGSV")) {
			TM_GPS_Statement = GPS_GPGSV;
		} else {
			TM_GPS_Statement = GPS_ERR;
		}
		
		strcpy(GPS_Statement_Name, GPS_Term);			/* Copy term to variable */
		return;											/* Do nothing */
	}
	
	/* Check custom terms one by one */
	for (i = 0; i < GPS_Data->CustomStatementsCount; i++) {
		/* Term is inside current statement */
		if (TM_GPS_INT_StringStartsWith(GPS_Statement_Name, GPS_Data->CustomStatements[i]->Statement)) {
			/* Term number is correct */
			if (GPS_Term_Number == GPS_Data->CustomStatements[i]->TermNumber) {
				/* Copy string value */
				strcpy(GPS_Data->CustomStatements[i]->Value, GPS_Term);
				
				/* Set updated flag */
				GPS_Data->CustomStatements[i]->Updated = 1;
			}
		}
	}
	
	switch (GPS_CONCAT(TM_GPS_Statement, GPS_Term_Number)) {
#ifndef GPS_DISABLE_GPGGA
		case GPS_POS_LATITUDE:	/* GPGGA */
			/* Convert latitude */
			count = TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.Latitude = temp / 100;
			TM_GPS_INT_Data.Latitude += (float)(temp % 100) / (float)60;
		
			count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Latitude += temp / (TM_GPS_INT_Pow(10, count) * 60.0);
			TM_GPS_INT_SetFlag(GPS_FLAG_LATITUDE);
			break;
		case GPS_POS_NS: /* GPGGA */
			if (GPS_Term[0] == 'S') {
				TM_GPS_INT_Data.Latitude = -TM_GPS_INT_Data.Latitude;	/* South has negative coordinate */
			}
			TM_GPS_INT_SetFlag(GPS_FLAG_NS);
			break;
		case GPS_POS_LONGITUDE: /* GPGGA */
			/* Convert longitude */
			count = TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.Longitude = temp / 100; /* Degrees */
			TM_GPS_INT_Data.Longitude += (float)(temp % 100) / (float)60;
		
			count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Longitude += temp / (TM_GPS_INT_Pow(10, count) * 60.0);
			TM_GPS_INT_SetFlag(GPS_FLAG_LONGITUDE);
			break;
		case GPS_POS_EW: /* GPGGA */
			if (GPS_Term[0] == 'W') {
				TM_GPS_INT_Data.Longitude = -TM_GPS_INT_Data.Longitude;	/* West has negative coordinate */
			}
			TM_GPS_INT_SetFlag(GPS_FLAG_EW);
			break;
		case GPS_POS_SATS: /* GPGGA */
			/* Satellites in use */
			TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.Satellites = temp;
			TM_GPS_INT_SetFlag(GPS_FLAG_SATS);
			break;
		case GPS_POS_FIX: /* GPGGA */
			/* GPS Fix */
			TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.Fix = temp;
			TM_GPS_INT_SetFlag(GPS_FLAG_FIX);
			break;
		case GPS_POS_ALTITUDE: /* GPGGA */
			/* Convert altitude above sea */
			if (GPS_Term[0] == '-') {
				count = TM_GPS_INT_Atoi(&GPS_Term[1], &temp);
				TM_GPS_INT_Data.Altitude = temp;
				
				count++;
				count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
				TM_GPS_INT_Data.Altitude += temp / (TM_GPS_INT_Pow(10, count) * 1.0);
				
				TM_GPS_INT_Data.Altitude = -TM_GPS_INT_Data.Altitude;
			} else {
				count = TM_GPS_INT_Atoi(GPS_Term, &temp);
				TM_GPS_INT_Data.Altitude = temp;
		
				count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
				TM_GPS_INT_Data.Altitude += temp / (TM_GPS_INT_Pow(10, count) * 1.0);
			}
			TM_GPS_INT_SetFlag(GPS_FLAG_ALTITUDE);
			break;
		case GPS_POS_TIME: /* GPGGA */
			/* Set time */
			count = TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.Time.Seconds = temp % 100;
			TM_GPS_INT_Data.Time.Minutes = (int)(temp * (float) 0.01) % 100;
			TM_GPS_INT_Data.Time.Hours = (int)(temp * (float)0.0001) % 100;
			/* Hundredths */
			TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Time.Hundredths = temp;
			TM_GPS_INT_SetFlag(GPS_FLAG_TIME);
			break;
#endif
#ifndef GPS_DISABLE_GPRMC
		case GPS_POS_SPEED:	/* GPRMC */	
			/* Convert speed */
			count = TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.Speed = (float)temp;
		
			count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Speed += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0));
		
			/* Set flag */
			TM_GPS_INT_SetFlag(GPS_FLAG_SPEED);
			break;
		case GPS_POS_DATE: /* GPRMC */	
			/* Set date */
			TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.Date.Year = temp % 100;
			TM_GPS_INT_Data.Date.Month = (int)(temp * 0.01f) % 100;
			TM_GPS_INT_Data.Date.Date = (int)(temp * 0.0001f) % 100;
			TM_GPS_INT_SetFlag(GPS_FLAG_DATE);
			break;
		case GPS_POS_VALIDITY: /* GPRMC */	
			/* GPS valid status */
			TM_GPS_INT_Data.Validity = GPS_Term[0] == 'A';
			TM_GPS_INT_SetFlag(GPS_FLAG_VALIDITY);
			break;
		case GPS_POS_DIRECTION: /* GPRMC */
			count = TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.Direction = (float)temp;
		
			count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
			TM_GPS_INT_Data.Direction += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0f));
			TM_GPS_INT_SetFlag(GPS_FLAG_DIRECTION);
			break;
#endif
#ifndef GPS_DISABLE_GPGSA
		case GPS_POS_HDOP: /* GPGSA */
			count = TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.HDOP = (float)temp;
		
			count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
			TM_GPS_INT_Data.HDOP += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0f));
			TM_GPS_INT_SetFlag(GPS_FLAG_HDOP);
			break;
		case GPS_POS_PDOP: /* GPGSA */
			count = TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.PDOP = (float)temp;
		
			count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
			TM_GPS_INT_Data.PDOP += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0f));
			TM_GPS_INT_SetFlag(GPS_FLAG_PDOP);
			break;
		case GPS_POS_VDOP: /* GPGSA */
			count = TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.VDOP = (float)temp;
		
			count = TM_GPS_INT_Atoi(&GPS_Term[++count], &temp);
			TM_GPS_INT_Data.VDOP += (float)((float)temp / (TM_GPS_INT_Pow(10, count) * 1.0f));
			TM_GPS_INT_SetFlag(GPS_FLAG_VDOP);
			break;
		case GPS_POS_FIXMODE: /* GPGSA */
			/* Satellites in view */
			TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.FixMode = temp;
			TM_GPS_INT_SetFlag(GPS_FLAG_FIXMODE);
			break;
		case GPS_POS_SAT1:
		case GPS_POS_SAT2:
		case GPS_POS_SAT3:
		case GPS_POS_SAT4:
		case GPS_POS_SAT5:
		case GPS_POS_SAT6:
		case GPS_POS_SAT7:
		case GPS_POS_SAT8:
		case GPS_POS_SAT9:
		case GPS_POS_SAT10:
		case GPS_POS_SAT11:
		case GPS_POS_SAT12:
			/* Satellite numbers */
			TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.SatelliteIDs[GPS_Term_Number - 3] = temp;
			ids_count++;							/* Increase number of satellites found */
		
			if (ids_count == TM_GPS_INT_Data.Satellites) {
				ids_count = 0;						/* Reset count, we have all statements */
				TM_GPS_INT_SetFlag(GPS_FLAG_SATS1_12);
			}
			break;
#endif
#ifndef GPS_DISABLE_GPGSV
		case GPS_POS_SATSINVIEW: /* GPGSV */
			/* Satellites in view */
			TM_GPS_INT_Atoi(GPS_Term, &temp);
			TM_GPS_INT_Data.SatellitesInView = temp;
			TM_GPS_INT_SetFlag(GPS_FLAG_SATSINVIEW);
			break;
#endif
		default: 
			break;
	}
	
#ifndef GPS_DISABLE_GPGSV
	/* Check for GPGSV statement separatelly */
	if (TM_GPS_Statement == GPS_GPGSV) {	
		if (GPS_Term_Number == 1) {
			TM_GPS_INT_Atoi(GPS_Term, &temp);			/* Save number of GPGSV statements */
			GPGSV_StatementsCount = temp;
		}
		if (GPS_Term_Number == 2) {
			TM_GPS_INT_Atoi(GPS_Term, &temp);			/* Save current of GPGSV statement number */
			GPSGV_StatementNumber = temp;
		}
		
		/* Data */
		if (GPS_Term_Number >= 4) {
			TM_GPS_INT_Atoi(GPS_Term, &temp);			/* Convert to number */
			
			GPGSV_Term_Number = GPS_Term_Number - 4;	/* Get proper value */
			GPGSV_Term_Mod = GPGSV_Term_Number % 4;
			GPGSV_Term_Number = (GPSGV_StatementNumber - 1) * 4 + (GPGSV_Term_Number / 4);
			
			if (GPGSV_Term_Number < GPS_MAX_SATS_IN_VIEW) {	/* If still memory available */
				/* Check offset from 4 */
				if (GPGSV_Term_Mod == 0) {
					TM_GPS_INT_Data.SatDesc[GPGSV_Term_Number].ID = temp;
				} else if (GPGSV_Term_Mod == 1) {
					TM_GPS_INT_Data.SatDesc[GPGSV_Term_Number].Elevation = temp;
				} else if (GPGSV_Term_Mod == 2) {
					TM_GPS_INT_Data.SatDesc[GPGSV_Term_Number].Azimuth = temp;
				} else if (GPGSV_Term_Mod == 3) {
					TM_GPS_INT_Data.SatDesc[GPGSV_Term_Number].SNR = temp;
				}
			}
		}
	}
#endif
}