UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:interrupt_driven_tsip

This is an old revision of the document!


#include "main.h"
//global(s)
extern gps_type Gps;
 
// Interrupt driven TSIP (lassen iq) parser for Atmel AVR (state machine based)
 
#define ETX 0x03			//as defined in TSIP specs
#define DLE 0x10
 
ISR(USART_RX_vect)			//UART interrupt on mega xx8 series
{
	static u08 id;
	static u08 placemark;
	static gps_type gps;
	static u08 *d;
	static u08 state;		//state machine
	char c=UDR0;
	switch(state)
	{
		case 0:
		if(c==DLE)		//wait for a dle before proceeding
		{
			state=1;
		}
		break;
		case 1:
		placemarker=0;
		if(c==0x4A || c==0x6D || c==0x56)		//packet ids
		{
			state=2;
			id=c;
		}
		else			//unknown or not something we are interested in
		{
			state=0;
		}		
		break;
		case 2:
		if(c==DLE)				//a dle in the data?
		{
			state=3;
		}
		break;
		case 3:
		if(c==ETX)
		{
			toggle_pin;			//toggles pin D5 - flashing LED tells us gps is working
			if(!Gps.packetflag)		//main has unlocked the data
			{
				Gps.packetflag=TRUE;	//this is usually the last interesting part of the fix info to come through
				Gps=gps;		//copy into the global variable
				VENU=FALSE;		//dont need to run again
			}
		}
		else if(c==DLE)				//double stuffed dle
		{
			state=4;
		}
		else					//this shouldnt happen
		{
			state=0;
		}
		break;
		case 4:
		if(c==ETX || c==DLE)			//state 4 shouldnt get either of these
		{
			state=0;
		}
		break;
		default:				//something wrong, go to 0
		state=0;
	}
	if(state==2 || state==4)			//the two states where we can write something
	{
		if(!placemarker && id==0x6D)		//the status byte
		{
			gps.status= c & 0x07;		//number from 0 to 7, 0=undefined, 7=ground station,4 3D
		}
		else if(placemarker<12)			//we only get first 3 floats
		{
			if(id==0x4A)
			{
				switch(placemarker)	//we copy the UART into ram with memcpy
				{
					case 0:
					d=&gps.latitude;
					break;
					case 4:
					d=&gps.longitude;
					break;
					case 8:
					d=&gps.altitude;
					break;
					default:
				}		
				if(d==&gps.latitude)
				{
					memcpy(d+placemarker,&c,1);
				}
				if(d==&gps.longitude)
				{
					memcpy(d+placemarker-4,&c,1);
				}
				if(d==&gps.latitude)
				{
					memcpy(d+placemarker-8,&c,1);
				}
			}
			else if(id==0x56)
			{
				switch(placemarker)
				{
					case 0:
					d=&gps.veast;
					break;
					case 4:
					d=&gps.vnorth;
					break;
					case 8:
					d=&gps.vup;
					break;
					default:
				}	
				if(d==&gps.veast)
				{
					memcpy(d+placemarker,&c,1);
				}
				if(d==&gps.vnorth)
				{
					memcpy(d+placemarker-4,&c,1);
				}
				if(d==&gps.vup)
				{
					memcpy(d+placemarker-8,&c,1);
				}
			}
		}
		else if(placemarker>27)				//max 7 floats
		{
			state=0;				//we had too much data, something is wrong
		}
		placemarker++;					//incr placeholder
	}
}
code/interrupt_driven_tsip.1213625422.txt.gz · Last modified: 2008/07/19 23:31 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki