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 if(UCSR0A & (BV(FE0)|BV(UPE0))) //a framing or parity error causes us to drop the packet { state=0; } 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.1213703678.txt.gz · Last modified: 2008/07/19 23:31 (external edit)