code:interrupt_driven_tsip
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
code:interrupt_driven_tsip [2008/06/16 01:49] – laurenceb | code:interrupt_driven_tsip [2008/10/11 11:28] (current) – laurenceb | ||
---|---|---|---|
Line 3: | Line 3: | ||
extern gps_type Gps; | extern gps_type Gps; | ||
- | // Interrupt driven TSIP (lassen iq) parser for Atmel AVR | + | // Interrupt driven TSIP (lassen iq) parser for Atmel AVR (state machine based) |
- | ISR(USART_RX_vect) //UART interrupt on mega xx8 series | + | #define ETX 0x03 //as defined in TSIP specs |
+ | #define DLE 0x10 | ||
+ | |||
+ | //8O1 send routine for initial setup | ||
+ | |||
+ | int suart_send(char c) | ||
{ | { | ||
- | static | + | u08 n; |
- | static | + | u08 p=FALSE; //odd parity |
- | static u08 placemark; | + | CLEAR; //start bit |
- | static gps_type gps; | + | delay; |
- | static u08 *d; | + | for(n=0;n<8;n++) //the data |
- | static u08 odd; | + | |
- | char c=UDR0; | + | |
- | if(odd) //destuffing; a double <DLE> in the data will cause one to be overwritten | + | |
{ | { | ||
- | placemarker++; | + | if(c & 0x01) |
+ | { | ||
+ | SET; | ||
+ | p=!p; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | CLEAR; | ||
+ | } | ||
+ | c>> | ||
+ | delay; | ||
} | } | ||
- | if(c==0x10) //keep track of number of <DLE> | + | if(p) //the parity |
{ | { | ||
- | odd=!odd; | + | SET; |
- | ) | + | } |
- | if(c==0x03 && !odd) //< | + | else |
{ | { | ||
- | placemarker=0; | + | CLEAR; |
- | LLA=FALSE; | + | |
- | VENU=FALSE; | + | |
- | odd=FALSE; | + | |
} | } | ||
- | else if(placemarker==1) // | + | delay; |
+ | SET; | ||
+ | delay; | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | ISR(USART_RX_vect) // | ||
+ | { | ||
+ | static u08 id; | ||
+ | static u08 placemarker; | ||
+ | static gps_type gps; | ||
+ | static u08 state; | ||
+ | u08 *d=(u08*)&gps; //points to our data | ||
+ | if(UCSR0A & (BV(FE0)|BV(UPE0))) // | ||
{ | { | ||
- | switch(c) | + | state=0; |
- | { | + | |
- | case 0x4A: | + | |
- | LLA=TRUE; | + | |
- | break; | + | |
- | case 0x56: | + | |
- | VENU=TRUE; | + | |
- | break; | + | |
- | default: | + | |
- | } | + | |
} | } | ||
- | if(LLA) | + | char c=UDR0; |
+ | if(state==2 || state==4) //the two states where we can write something | ||
{ | { | ||
- | switch(placemarker) | + | if(!placemarker |
{ | { | ||
- | case 3: | + | gps.status= c & 0x0F; //number from 0 to 7, 0=undefined, 7=ground station,4 3D |
- | d=&gps.latitude; | + | gps.nosats=(c & 0xF0)>>4; //number of tracked satellites |
- | break; | + | |
- | case | + | |
- | d=& | + | |
- | break; | + | |
- | case 11: | + | |
- | d=&gps.altitude; | + | |
- | break; | + | |
- | default: | + | |
- | } | + | |
- | if(d==& | + | |
- | { | + | |
- | memcpy(d+placemarker-3, | + | |
} | } | ||
- | if(d==& | + | else if(id==0x4A) //lla(time) packet - 4 floats |
{ | { | ||
- | memcpy(d+placemarker-7,&c,1); | + | if(placemarker< |
+ | { | ||
+ | d[27-placemarker]=c; | ||
+ | } | ||
+ | if(placemarker> | ||
+ | { | ||
+ | d[31-placemarker]=c; //time of fix | ||
+ | } | ||
} | } | ||
- | if(d==&gps.latitude) | + | else if(id==0x56 && placemarker< |
{ | { | ||
- | memcpy(d+placemarker-11,&c,1); | + | d[11-placemarker]=c; |
} | } | ||
- | if(placemarker==14) | + | else if(placemarker>27) //max 7 floats |
{ | { | ||
- | LLA=FALSE; | + | state=0; //we had too much data, something is wrong |
} | } | ||
+ | placemarker++; | ||
} | } | ||
- | if(VENU) | + | switch(state) //run the state machine |
{ | { | ||
- | switch(placemarker) | + | case 0: |
+ | if(c==DLE) //wait for a dle before proceeding | ||
{ | { | ||
- | case 3: | + | state=1; |
- | d=& | + | |
- | break; | + | |
- | case 7: | + | |
- | d=& | + | |
- | break; | + | |
- | case 11: | + | |
- | d=& | + | |
- | break; | + | |
- | default: | + | |
- | } | + | |
- | if(d==& | + | |
- | { | + | |
- | memcpy(d+placemarker-3,& | + | |
} | } | ||
- | if(d==& | + | break; |
+ | case 1: | ||
+ | placemarker=0; | ||
+ | if(c==0x4A || c==0x6D || c==0x56) //packet ids | ||
{ | { | ||
- | memcpy(d+placemarker-7,& | + | state=2; |
+ | id=c; | ||
} | } | ||
- | if(d==& | + | else // |
{ | { | ||
- | memcpy(d+placemarker-11,& | + | state=0; |
+ | } | ||
+ | break; | ||
+ | case 2: | ||
+ | if(c==DLE) //a dle in the data? | ||
+ | { | ||
+ | state=3; | ||
} | } | ||
- | if(placemarker==14) | + | break; |
+ | case 3: | ||
+ | if(c==ETX) | ||
{ | { | ||
- | toggle_pin; //toggles pin D5 - flashing LED tells us gps is working | + | state=0; //end of packet |
- | if(!Gps.packetflag) //main has unlocked | + | if(id==0x6D) //the 0x6D packet is sent after a fix calculation or at 1Hz |
{ | { | ||
- | Gps.packetflag=TRUE; | + | gps.packetflag=TRUE;// |
- | Gps=gps; | + | toggle_pin; |
- | VENU=FALSE; | + | if(!Gps.packetflag) // |
+ | { | ||
+ | Gps=gps; | ||
+ | } | ||
} | } | ||
} | } | ||
+ | else if(c==DLE) // | ||
+ | { | ||
+ | state=4; | ||
+ | } | ||
+ | else // | ||
+ | { | ||
+ | state=0; | ||
+ | } | ||
+ | break; | ||
+ | case 4: | ||
+ | if(c==ETX || c==DLE) // | ||
+ | { | ||
+ | state=0; | ||
+ | } | ||
+ | break; | ||
+ | default: | ||
+ | state=0; | ||
} | } | ||
}</ | }</ |
code/interrupt_driven_tsip.1213580956.txt.gz · Last modified: 2008/07/19 23:31 (external edit)