#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; } }