UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:interrupt_driven_tsip
#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
 
//8O1 send routine for initial setup
 
int suart_send(char c)
{
	u08 n;
	u08 p=FALSE;		//odd parity
	CLEAR;				//start bit
	delay;
	for(n=0;n<8;n++)		//the data
	{
		if(c & 0x01)
		{
			SET;		//update parity
			p=!p;
		}
		else
		{
			CLEAR;
		}
		c>>=1;
		delay;
	}
	if(p)				//the parity
	{
		SET;
	}
	else
	{
		CLEAR;
	}
	delay;
	SET;				//stop bit
	delay;
	return 0;
}
 
ISR(USART_RX_vect)			//UART interrupt on mega xx8 series
{
	static u08 id;
	static u08 placemarker;
	static gps_type gps;
	static u08 state;		//state machine
	u08 *d=(u08*)&gps;		//points to our data
	if(UCSR0A & (BV(FE0)|BV(UPE0)))	//a framing or parity error causes us to drop the packet
	{
		state=0;
	}
	char c=UDR0;
	if(state==2 || state==4)				//the two states where we can write something
	{
		if(!placemarker && id==0x6D)		//start of packet - the status byte
		{
			gps.status= c & 0x0F;		//number from 0 to 7, 0=undefined, 7=ground station,4 3D
			gps.nosats=(c & 0xF0)>>4;	//number of tracked satellites
		}
		else if(id==0x4A)	//lla(time) packet - 4 floats
		{
			if(placemarker<12)				//lla
			{
				d[27-placemarker]=c;
			}
			if(placemarker>15 && placemarker<20)	//time
			{
				d[31-placemarker]=c;		//time of fix
			}
		}
		else if(id==0x56 && placemarker<12)  //enu packet - 3 floats
		{
			d[11-placemarker]=c;
		}
		else if(placemarker>27)				//max 7 floats
		{
			state=0;					//we had too much data, something is wrong
		}
		placemarker++;					//incr placeholder
	}
	switch(state)		//run the state machine
	{
		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)
		{
			state=0;				//end of packet - we arent in one
			if(id==0x6D)			//the 0x6D packet is sent after a fix calculation or at 1Hz
			{
				gps.packetflag=TRUE;//TRUE==1
				toggle_pin;			//toggles pin D5 - flashing LED tells us gps is working
				if(!Gps.packetflag)		//main has unlocked the data
					{
						Gps=gps;		//copy into the global variable
					}
			}
		}
		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;
	}
}
code/interrupt_driven_tsip.txt ยท Last modified: 2008/10/11 11:28 by laurenceb