Esempio n. 1
0
// Flush the current word buffer
// out to the phraseBuffer
static void flushWord(void){
	uint8_t data;
	size_t wordLen = wordBuffer.datalength;

	// If the phrase cannot accept the entire
	// word then say the current phrase first
	if(bufferFreeSpace(&phraseBuffer) <= wordLen){
		flushPhrase();
	}

	// Write the word to the phrase buffer
	while(bufferGet(&wordBuffer,&data)){
		bufferPut(&phraseBuffer,data);
	}
}
Esempio n. 2
0
static void handler(unsigned char c, void* device){
	GPS_NMEA* gps = (GPS_NMEA*)device;

	// Get working data
	int msgIndex = gps->msgIndex;
	boolean error = gps->error;
	char* msg = gps->msg;

	// If its a $ then its the start of a msg
	if(c=='$'){
		msgIndex = 0;	// reset the msg buffer
		error=FALSE;	// clear error state
	}

	// Store the character
	if(msgIndex < MAX_NMEA_MSG-1){
		msg[msgIndex++] = c;	// store character
		msg[msgIndex] = 0;		// null terminate string
	}else{
		error=TRUE;				// the message is too long
	}

	// Test for end of line
	if(c=='\n' && error==FALSE){
		// Have got a line of length msgIndex

		// Test for minimum size of '$GP...<,>.....*xx<cr><lf>'
		if(msgIndex >= 8){
			if(msg[0]=='$' && msg[1]=='G' && msg[2]=='P' && msg[6]==',' && msg[msgIndex-1]=='\n' && msg[msgIndex-2]=='\r' && msg[msgIndex-5]=='*'){
				uint8_t myChecksum=0;
				uint8_t i;

				// Looks like a valid message
				msg[msgIndex-2]=0;	// chop off cr/lf
				msgIndex=0;

				// We only use GPRMC and GPGGA
				if( msg[3]=='R' && msg[4]=='M' && msg[5]=='C') goto ok;
				if( msg[3]=='G' && msg[4]=='G' && msg[5]=='A') goto ok;
				goto end;

				// Calculate the checksum
ok:				for(i=1; ;){
					c = msg[i++];

					// Shouldn't happen - but check for end of string
					if(c=='\0'){
						goto end;
					}

					if(c=='*'){
						break;
					}
					myChecksum ^= c;
				}

				// Remove checksum
				msg[i-1]=0;

				// String length including terminator
				size_t msgLen = i;

				if(bufferFreeSpace(&gps->msgQueueBuf) < msgLen){
					// not enough space in buffer
					goto end;
				}


				// Get received checksum
				uint8_t rxChecksum=0;
				c = msg[i++];
				if(c>='0' && c<='9'){
					rxChecksum += c-'0';
				}else{
					rxChecksum += c-'A'+10;
				}
				rxChecksum *= 16;
				c = msg[i++];
				if(c>='0' && c<='9'){
					rxChecksum += c-'0';
				}else{
					rxChecksum += c-'A'+10;
				}

				// If checksums agree then add message to queue
				if(rxChecksum==myChecksum){
					if( ! bufferQueue(&gps->msgQueueBuf, msg, msgLen) ){
						goto end;			// couldn't add it for some reason
					}

				}else{
					#ifdef DEBUG
					PRINTF(stdout,"Bad checksum:");
					#endif
				}
			}
		}
	}
end:
	// Set working data
	gps->msgIndex = msgIndex;
	gps->error = error;
}