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 //8O1 send routine for initial setup void suart_send(char c) { u08 n; u08 p=FALSE; 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; } ISR(USART_RX_vect) //UART interrupt on mega xx8 series { static u08 id; static u08 placemarker; static gps_type gps; static u08 *d; //static u08 state; //state machine 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) //the status byte { gps.status= c & 0x07; //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 && placemarker<16) //lla packet { if(!placemarker) { d=&gps.latitude; } d[placemarker]=c; } else if(id==0x56 && placemarker<12) //venu packet { if(!placemarker) { d=&gps.veast; } d[placemarker]=c; } else if(placemarker>27) //max 7 floats { state=0; //we had too much data, something is wrong } placemarker++; //incr placeholder } 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=gps; //copy into the global variable Gps.packetflag=TRUE; //this is usually the last interesting part of the fix info to come through state=0; //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; } }
code/interrupt_driven_tsip.1216510404.txt.gz · Last modified: 2008/10/11 11:28 (external edit)