Changeset - 95c4c7f33ecb
[Not reviewed]
default
0 1 0
mkanning@CL-SEC241-10.cedarville.edu - 12 years ago 2012-11-29 15:43:06
mkanning@CL-SEC241-10.cedarville.edu
NMEA parser first pass complete
1 file changed with 235 insertions and 83 deletions:
0 comments (0 inline, 0 general)
master/master/lib/trackuinoGPS/gpsMKa.c
Show inline comments
 
/*
 
* gpsMKa.c
 
*
 
* Created: 11/15/2012 12:02:38 PM
 
*  Author: mkanning
 
*/
 
/*
 
 
#include <stdbool.h>
 
#include <avr/io.h>
 
#include "gpsMKa.h"
 
#include "../serial.h"
 

	
 
// holds the byte ALREADY PARSED. includes starting character
 
int bytesReceived = 0;
 

	
 
//data (and checksum) of most recent transmission
 
char data[16];
 
@@ -20,25 +21,29 @@ int skipBytes = 0;
 

	
 
//used to index data arrays during data collection
 
int numBytes = 0;
 

	
 
//variables to store data from transmission
 
//least significant digit is stored at location 0 of arrays
 
uint8_t tramsmissionType;
 
uint8_t tramsmissionType[5];
 
uint8_t timestamp[9];	//hhmmss.ss
 
uint8_t latitude[8];	//lllll.lla
 
uint8_t longitude[8];	//yyyyy.yya
 
uint8_t longitude[8];	//yyyyy.yyb
 
uint8_t quality;		//quality for GGA and validity for RMC
 
uint8_t numSatellites[2];
 
uint8_t hdop[4];		//xx.x
 
uint8_t altitude[8];	//xxxxxx.x
 
uint8_t wgs84Height[6];	//sxxx.x
 
uint8_t lastUpdated[6];	//blank - included for testing
 
uint8_t stationID[6];	//blank - included for testing
 
uint8_t checksum;		//xx
 

	
 
uint8_t checksum[2];	//xx
 
uint8_t knots[5];		//xxx.xx
 
uint8_t course[5];		//xxx.x
 
uint8_t datestamp[6];	//ddmmyy
 
uint8_t variation[6];	//xxx.xb
 
int calculatedChecksum;
 

	
 
// transmission state machine
 
enum decodeState {
 
	//shared fields
 
	INITIALIZE=0,
 
	GET_TYPE,
 
@@ -53,243 +58,390 @@ enum decodeState {
 
	GGA_ALTITUDE,
 
	GGA_WGS84,
 
	GGA_LAST_UPDATE,
 
	GGA_STATION_ID,
 
	//RMC data fields
 
	RMC_TIME,
 
	RMC_WARNING,
 
	RMC_VALIDITY,
 
	RMC_LATITUDE,
 
	RMC_LONGITUDE,
 
	RMC_KNOTS,
 
	RMC_COURSE,
 
	RMC_DATE,
 
	RMC_MAG_VERIATION,
 
	RMC_MAG_VARIATION,
 
	
 
}decodeState;
 

	
 
/// MKa GPS transmission parser START
 
//// MKa GPS transmission parser START
 
void parse_gps_transmission(void){
 
	bytesReceived++;
 
	
 
	// Pull byte off of the buffer
 
	char byte = uart_getchar();
 
	char byte = serial1_readChar();
 
	
 
	// $--GGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx
 
	//        ^8        ^18       ^28
 
	if(byte == '$') //start of transmission sentence
 
	{
 
		bytesReceived = 1; //resets transmission if '$' is found
 
		decodeState = GET_TYPE;
 
		numBytes = 0;
 
		numBytes = 0; //prep for next phases
 
		skipBytes = 0;
 
		calculatedChecksum = 0;
 
	}
 
	
 
	//parse transmission type
 
	else if (decodeState == GET_TYPE)
 
	{
 
		if (bytesReceived == 4 ) //check 4th byte
 
		tramsmissionType[numBytes] = byte;
 
		numBytes++;
 
		
 
		if(byte == ',') //end of this data type
 
		{
 
			tramsmissionType = byte;
 
		}
 
		
 
		if(byte = ',') //end of type data
 
		{
 
			if (tramsmissionType == 'G')
 
			if (tramsmissionType[2] == 'G' &&
 
			tramsmissionType[3] == 'G' &&
 
			tramsmissionType[4] == 'A')
 
			{
 
				decodeState = GGA_TIME;
 
			}
 
			else if(tramsmissionType == 'R')
 
			else if (tramsmissionType[2] == 'R' &&
 
			tramsmissionType[3] == 'M' &&
 
			tramsmissionType[4] == 'C')
 
			{
 
				decodeState = RMC_TIME; //not implemented
 
				decodeState = RMC_TIME;
 
			}
 
			else
 
			else //this is an invalid transmission type
 
			{
 
				//reset
 
				decodeState = INITIALIZE;
 
				bytesReceived = 0;
 
			}
 
		}
 
	}
 
	
 
	//parse GGA timestamp
 
	///parses GGA transmissions START
 
	/// $--GGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*xx
 
	//timestamp
 
	else if (decodeState == GGA_TIME)
 
	{
 
		if (byte = ',')//end of timestamp data
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = GGA_LATITUDE;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
		}
 
		else //store the byte of timestamp data
 
		else //store data
 
		{
 
			timestamp[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA latitude data
 
	//latitude
 
	else if (decodeState == GGA_LATITUDE)
 
	{
 
		if (byte == ',' && skipBytes == 0) //discard this byte
 
		{
 
			skipBytes = 1;
 
		}
 
		else if (byte == ',') //end of latitude data
 
		else if (byte == ',') //end of this data type
 
		{
 
			decodeState = GGA_LONGITUDE;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
		}
 
		else
 
		else //store data
 
		{
 
			latitude[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA longitude data
 
	//longitude
 
	else if (decodeState == GGA_LONGITUDE)
 
	{
 
		if (byte == ',' && skipBytes == 0) //discard this byte
 
		{
 
			skipBytes = 1;
 
		}
 
		else if (byte == ',') //end of latitude data
 
		else if (byte == ',') //end of this data type
 
		{
 
			decodeState = GGA_QUALITY;
 
			numBytes = 0;
 
			numBytes = 0; //prep for next phase of parse
 
			skipBytes = 0;
 
		}
 
		else
 
		else //store data
 
		{
 
			longitude[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA quality data
 
	else if (decodeState = GGA_QUALITY)
 
	//GGA quality
 
	else if (decodeState == GGA_QUALITY)
 
	{
 
		if (byte = ',')//end of quality data
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = GGA_SATELLITES;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else
 
		else //store data
 
		{
 
			quality = byte; //maybe reset if invalid data ??
 
		}
 
	}
 
	
 
	//parse GGA number of satellites data
 
	else if (decodeState = GGA_SATELLITES)
 
	//number of satellites
 
	else if (decodeState == GGA_SATELLITES)
 
	{
 
		if (byte = ',')//end of data
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = GGA_HDOP;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data
 
		{
 
			numSatellites[numBytes] = byte;
 
			numSatellites[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA HDOP data
 
	else if (decodeState = GGA_HDOP)
 
	//HDOP
 
	else if (decodeState == GGA_HDOP)
 
	{
 
		if (byte = ',')//end of data
 
		if (byte == ',' ) //end of this data type
 
		{
 
			decodeState = GGA_ALTITUDE;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
			numBytes = 0; //prep for next phase of parse
 
			skipBytes = 0;
 
		}
 
		else //store data
 
		{
 
			hdop[numBytes] = byte; //store byte of data
 
			hdop[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA altitude data
 
	else if (decodeState = GGA_ALTITUDE)
 
	//altitude
 
	else if (decodeState == GGA_ALTITUDE)
 
	{
 
		if (byte = ',')//end of data
 
		if (byte == ',' && skipBytes == 0) //discard this byte
 
		{
 
			skipBytes = 1;
 
		}
 
		else if(byte == ',') //end of this data type
 
		{
 
			decodeState = GGA_WGS84;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data
 
		{
 
			altitude[numBytes] = byte;
 
			altitude[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA WGS84 Height data
 
	else if (decodeState = GGA_WGS84)
 
	//WGS84 Height
 
	else if (decodeState == GGA_WGS84)
 
	{
 
		if (byte = ',')//end of data
 
		if (byte == ',' && skipBytes == 0) //discard this byte
 
		{
 
			skipBytes = 1;
 
		}
 
		else if(byte == ',') //end of this data type
 
		{
 
			decodeState = GGA_LAST_UPDATE;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
		}
 
		else //store data
 
		{
 
			wgs84Height[numBytes] = byte;
 
			wgs84Height[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA last DGPS update data
 
	else if (decodeState = GGA_LAST_UPDATE)
 
	//last GGA DGPS update
 
	else if (decodeState == GGA_LAST_UPDATE)
 
	{
 
		if (byte = ',')//end of data
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = GGA_STATION_ID;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data - this should be blank
 
		{
 
			lastUpdated[numBytes] = byte;
 
			lastUpdated[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA DGPS station ID data
 
	else if (decodeState = GGA_STATION_ID)
 
	//GGA DGPS station ID
 
	else if (decodeState == GGA_STATION_ID)
 
	{
 
		if (byte = ',')//end of data
 
		if (byte == ',' || byte == '*') //end of this data type
 
		{
 
			decodeState = GGA_CHECKSUM;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
			decodeState = GPS_CHECKSUM;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data - this should be blank
 
		{
 
			stationID[numBytes] = byte;
 
			stationID[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	///parses GGA transmissions END
 
	
 
	/// $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh
 
	///parses RMC transmissions
 
	//time
 
	else if(decodeState == RMC_TIME)
 
	{
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = RMC_VALIDITY;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data
 
		{
 
			timestamp[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//parse GGA checksum data
 
	else if (decodeState = GGA_CHECKSUM)
 
	//validity
 
	else if(decodeState == RMC_VALIDITY)
 
	{
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = RMC_LATITUDE;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
		}
 
		else //store data
 
	{
 
		if (byte = ',')//end of data - terminating character ??
 
			quality = byte;
 
			numBytes++;
 
		}
 
	}
 
	
 
	//latitude
 
	else if(decodeState == RMC_LATITUDE)
 
		{
 
			decodeState = INITIALIZE;
 
		if (byte == ',' && skipBytes == 1) //discard this byte
 
		{
 
			skipBytes = 1; 
 
		}
 
		else if (byte == ',') //end of this data type
 
		{
 
			decodeState = RMC_LONGITUDE;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
		}
 
		else //store data
 
		{
 
			checksum[numBytes] = byte;
 
			latitude[numBytes]= byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//longitude
 
	else if(decodeState == RMC_LONGITUDE)
 
	{
 
		if (byte == ',' && skipBytes == 1) //discard this byte
 
		{
 
			skipBytes = 1; 
 
		}
 
		else if (byte == ',') //end of this data type
 
		{
 
			decodeState = RMC_KNOTS;
 
			skipBytes = 0;
 
			numBytes = 0;
 
		}
 
		else //store data
 
		{
 
			longitude[numBytes]= byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//knots
 
	else if(decodeState == RMC_KNOTS)
 
	{
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = RMC_COURSE;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data
 
		{
 
			knots[numBytes]= byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//course
 
	else if(decodeState == RMC_COURSE)
 
	{
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = RMC_DATE;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data
 
		{
 
			course[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//date
 
	else if(decodeState == RMC_DATE)
 
	{
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = RMC_MAG_VARIATION;
 
			skipBytes = 0; //prep for next phase of parse
 
			numBytes = 0;
 
}
 
*/
 
/// MKa GPS transmission parser END
 
\ No newline at end of file
 
		else //store data
 
		{
 
			datestamp[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//magnetic variation
 
	else if(decodeState == RMC_MAG_VARIATION)
 
	{
 
		if (byte == ',') //end of this data type
 
		{
 
			decodeState = GPS_CHECKSUM;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data
 
		{
 
			variation[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	///parses RMC transmissions END
 
	
 
	
 
	//checksum
 
	else if (decodeState == GPS_CHECKSUM)
 
	{
 
		if (numBytes == 2) //end of data - terminating character ??
 
		{
 
			decodeState = INITIALIZE;
 
			numBytes = 0; //prep for next phase of parse
 
		}
 
		else //store data
 
		{
 
			checksum[numBytes] = byte; //adjust number of bytes to fit array
 
			numBytes++;
 
		}
 
	}
 
	
 
	//input byte into running checksum
 
	XORbyteWithChecksum(byte);
 
}
 
/// MKa GPS transmission parser END
 

	
 
void XORbyteWithChecksum(uint8_t byte){
 
	calculatedChecksum ^= (int)byte; //this may need to be re-coded
 
}
 

	
0 comments (0 inline, 0 general)