UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:interrupt_driven_tsip

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
code:interrupt_driven_tsip [2008/06/16 01:49] laurencebcode: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 LLA+ u08 n
- static u08 VENU+ 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; //update parity 
 + p=!p; 
 +
 + else 
 +
 + CLEAR; 
 +
 + c>>=1; 
 + delay;
  }  }
- if(c==0x10) //keep track of number of <DLE>+ if(p) //the parity
  {  {
- odd=!odd;  + SET
- ) + } 
- if(c==0x03 && !odd) //<ETX> end of a packet ie a new one is coming- there are even <DLE> in a packet+ else
  {  {
- placemarker=0; + CLEAR;
- LLA=FALSE; +
- VENU=FALSE; //we dont know what sort of packet it is yet +
- odd=FALSE; //no <DLE> so far, i.e. an even number of <DLE>+
  }  }
- else if(placemarker==1) //packet id+ 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
  {  {
- switch(c) + state=0;
-+
- case 0x4A: +
- LLA=TRUE; +
- break; +
- case 0x56: +
- VENU=TRUE; +
- break; +
- default: //unknown packet, leave it +
- }+
  }  }
- if(LLA)+ char c=UDR0; 
 + if(state==2 || state==4) //the two states where we can write something
  {  {
- switch(placemarker)+ if(!placemarker && id==0x6D) //start of packet - the status byte
  {  {
- case 3: + gps.status0x0F; //number from 0 to 7, 0=undefined, 7=ground station,4 3D 
- d=&gps.latitude; + gps.nosats=(0xF0)>>4; //number of tracked satellites
- break; +
- case 7+
- d=&gps.longitude; +
- break; +
- case 11: +
- d=&gps.altitude; +
- break; +
- default: +
- }  +
- if(d==&gps.latitude) +
-+
- memcpy(d+placemarker-3,&c,1);+
  }  }
- if(d==&gps.longitude)+ else if(id==0x4A) //lla(time) packet - 4 floats
  {  {
- memcpy(d+placemarker-7,&c,1);+ if(placemarker<12) //lla 
 +
 + d[27-placemarker]=c
 +
 + if(placemarker>15 && placemarker<20) //time 
 +
 + d[31-placemarker]=c; //time of fix 
 + }
  }  }
- if(d==&gps.latitude)+ else if(id==0x56 && placemarker<12 //enu packet - 3 floats
  {  {
- 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++; //incr placeholder
  }  }
- 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=&gps.veast; +
- break; +
- case 7: +
- d=&gps.vnorth; +
- break; +
- case 11: +
- d=&gps.vup; +
- break; +
- default: +
- }  +
- if(d==&gps.veast) +
-+
- memcpy(d+placemarker-3,&c,1);+
  }  }
- if(d==&gps.vnorth)+ break; 
 + case 1: 
 + placemarker=0; 
 + if(c==0x4A || c==0x6D || c==0x56) //packet ids
  {  {
- memcpy(d+placemarker-7,&c,1);+ state=2; 
 + id=c;
  }  }
- if(d==&gps.vup)+ else //unknown or not something we are interested in
  {  {
- memcpy(d+placemarker-11,&c,1);+ 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 we arent in one 
- if(!Gps.packetflag) //main has unlocked the data+ if(id==0x6D) //the 0x6D packet is sent after a fix calculation or at 1Hz
  {  {
- Gps.packetflag=TRUE; //this is usually the last interesting part of the fix info to come through + gps.packetflag=TRUE;//TRUE==1 
- Gps=gps; //copy into the global variable + toggle_pin; //toggles pin D5 - flashing LED tells us gps is working 
- VENU=FALSE; //dont need to run again+ 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> }</code>
code/interrupt_driven_tsip.1213580956.txt.gz · Last modified: 2008/07/19 23:31 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki