james kain / Mbed 2 deprecated GPS_Incremental

Dependencies:   mbed

Fork of GPS_Incremental by Dan Matthews

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OEM615.h Source File

OEM615.h

00001     
00002 #pragma pack(1)  //this forces the structure to be packed on byte boundaries (with no byte filler)
00003 //set up the GPS message header in a structure to enable easy reading -- see the OEM615 manual (Table 4, page 24)
00004 struct MESSAGEHEADER   
00005 {
00006     char synchAA;                   //1st synch word
00007     char synch44;                   //2nd synch word
00008     char synch12;                   //3rd synch word
00009     unsigned char headerLength;     //always 28
00010     unsigned short messageID;       //42  (0x2A  BESTPOS) , 43 (2B  RANGE) , or 99 (x63 BESTVEL), 
00011     char messageType;               //always = 0 for binary
00012     unsigned char portAddress;      //0x20 for COM1
00013     // from spec:  The length in bytes of the body of the message, not including the header nor the CRC
00014     unsigned short messageLength;   //not including header or CRC
00015     unsigned short sequence;        //typically 0
00016     unsigned char idleTime;         //Time the processor is idle, in the last second
00017     unsigned char timeStatus;       //Enum Indicating quality of the GPS reference time
00018     unsigned short GPSweek;         //GPS reference week
00019     unsigned long GPSTime_msecs;    //from beginning of week
00020     unsigned long receiverStatus;   //32-bits representing the status of hardware and software
00021     unsigned short reserved;
00022     unsigned short receiverSWversion;  //receiver software build number
00023     //total length in bytes of this header is 28
00024 };
00025 MESSAGEHEADER *msgHeader[6];
00026 
00027 #pragma pack(1)
00028 //structure for OEM615 BESTVEL log message  (page 314)
00029 struct OEM615BESTVEL
00030 {
00031     MESSAGEHEADER msgHeader;
00032     int solStatus;                      //solution status
00033     //solutionStatusOEMStar solStatus;  //solution status
00034     int velType;                        //position or velocity type
00035     //velTypeOEMStar posType;           //position or velocity type   
00036     float latency;
00037     float age;
00038     double horizontalSpeed;         //horizontal velocity vector magnitude (m/s)
00039     double heading;                 //deg from North called TRK GND in specification
00040     double verticalSpeed;           //vertical velocity magnitude (m/s)
00041     float reserved;
00042     unsigned long CRC;
00043 };
00044 
00045 /*  Solution Status descritpion from OEMV manual
00046 0   SOL_COMPUTED        Solution computed
00047 1   INSUFFICIENT_OBS    Insufficient observations
00048 2   NO_CONVERGENCE      No convergence
00049 3   SINGULARITY         Singularity at parameters matrix
00050 4   COV_TRACE           Covariance trace exceeds maximum (trace > 1000 m)
00051 5   TEST_DIST           Test distance exceeded (maximum of 3 rejections if distance >10 km)
00052 6   COLD_START          Not yet converged from cold start
00053 7   V_H_LIMIT           Height or velocity limits exceeded
00054 8   VARIANCE            Variance exceeds limits
00055 9   RESIDUALS           Residuals are too large
00056 10  DELTA_POS           Delta position is too large
00057 11  NEGATIVE_VAR        Negative variance
00058 12  Reserved
00059 13  INTEGRITY_WARNING   Large residuals make position unreliable
00060 18  PENDING             
00061 19  INVALID_FIX         The fixed position, entered using the FIX POSITION command, is not valid
00062 20  UNAUTHORIZED        Position type is unauthorized - HP or XP 
00063 */
00064 
00065 #pragma pack(1)
00066 //structure for BESTPOS message 
00067 struct OEM615BESTPOS
00068 {
00069     MESSAGEHEADER msgHeader;
00070     int solStatus;                      //solution status
00071     //solutionStatusOEMStar solStatus;  //solution status
00072     int posType;                        //position or velocity type
00073     //posTypeOEMStar posType;           //position or velocity type
00074     double latitude;                    //latitude
00075     double longitude;                   //longitude
00076     double height;                      //height above mean sea level
00077     float undulation;                   //the realtionship between the geoid and the
00078                                         //ellipsoid of the chosen datum (m)
00079     char datumID[4];                    //datum ID is actually an enum that is not implemented
00080     float latitudeSTD;                  //latitude standard deviation
00081     float longitudeSTD;                 //longitude standard deviation
00082     float heightSTD;                    //height standard deviation
00083     char baseStationID[4];              //base station ID
00084     float diffAge;                      //differential age (s)
00085     float solutionAge;                  //solution age (s)
00086     unsigned char numSV;                //number of satellite vehicles tracked
00087     unsigned char numSolSV;             //number of satellite vehicles used in solution
00088     unsigned char numGGL1;              //number of GPS plus Glonass L1
00089     unsigned char res1;
00090     unsigned char res2;
00091     unsigned char extSolStatus;         //extended solution status
00092     unsigned char res3;
00093     unsigned char sigMask;              //signals used mask
00094     unsigned long CRC;
00095 };
00096 
00097 //GPS-specific pins
00098 DigitalOut GPS_Reset(p18);      //GPS RESET line
00099 InterruptIn PPSInt(p15);        // GPS 1PPS (timemark) from the OEM615
00100 InterruptIn IMUClock(p17);
00101 
00102 Timer timeFromPPS;
00103 unsigned long GPSTimemsecs = 0;
00104 double GPSTime = 0;
00105 int PPSTimeOffset = 0;
00106 
00107 //mbed tx/rx interface to the GPS COM1 port
00108 MODSERIAL GPS_COM1(p9,p10);  //this serial port communicates with the GPS receiver serial port (COM1)
00109 
00110 int test = 0;
00111 unsigned short messageCounter = 0;
00112 unsigned short savedMessageCounter = 0;
00113 const unsigned short maxGPSbytesPerSec = 1536;
00114 unsigned char msgBuffer[maxGPSbytesPerSec];  //array to contain one full second of GPS bytes
00115 const unsigned char maxGPSMessagesPerSec = 12;
00116 unsigned short messageLocation[maxGPSMessagesPerSec] = {0};  //stores the message location start within the message buffer
00117 
00118 unsigned short bytesFromMessageHdrDetect = 0;
00119 union SWAPBYTES { unsigned char b[2]; unsigned short w; };
00120 volatile SWAPBYTES messageLength;  //used to swap the bytes
00121 unsigned long computedCRC = 0;  //final resulting computed CRC for this message
00122 unsigned long incrementalCRC = 0;  //incrementally-formed CRC over message sequence
00123 unsigned short endByteForCRCcomputation = 0;
00124 bool completeMessageAvailable = false;
00125 
00126 //this code was taken from the Novatel Firmware document page 35
00127 //#define CRC32_POLYNOMIAL 0xEDB88320L
00128 /* --------------------------------------------------------------------------
00129 Calculate a CRC value to be used by CRC calculation functions.
00130 -------------------------------------------------------------------------- */
00131 /*
00132 ////////////////////////////////////////////
00133 //original code from the OEM615 manual
00134 ////////////////////////////////////////////
00135 unsigned long CRC32Value(int i)
00136 {
00137     int j;
00138     unsigned long ulCRC;
00139     ulCRC = i;
00140     for ( j = 8 ; j > 0; j-- )
00141     {
00142         if ( ulCRC & 1 )
00143         ulCRC = ( ulCRC >> 1 ) ^ CRC32_POLYNOMIAL;
00144         else
00145         ulCRC >>= 1;
00146     }
00147     return ulCRC;
00148 } 
00149 */
00150 
00151 #define CRC32_POLYNOMIAL 0xEDB88320L
00152 void CRC32Value(unsigned long &CRC, unsigned char c)
00153 {
00154     /////////////////////////////////////////////////////////////////////////////////////
00155     //CRC must be initialized as zero 
00156     //c is a character from the sequence that is used to form the CRC
00157     //this code is a modification of the code from the Novatel OEM615 specification
00158     /////////////////////////////////////////////////////////////////////////////////////
00159     unsigned long ulTemp1 = ( CRC >> 8 ) & 0x00FFFFFFL;
00160     unsigned long ulCRC = ((int) CRC ^ c ) & 0xff ;
00161     for (int  j = 8 ; j > 0; j-- )
00162     {
00163         if ( ulCRC & 1 )
00164             ulCRC = ( ulCRC >> 1 ) ^ CRC32_POLYNOMIAL;
00165         else
00166             ulCRC >>= 1;
00167     }
00168     CRC = ulTemp1 ^ ulCRC;
00169 } 
00170 
00171 /* --------------------------------------------------------------------------
00172 Calculates the CRC-32 of a block of data all at once
00173 //the CRC is from the complete message (header plus data) 
00174 //but excluding (of course) the CRC at the end
00175 -------------------------------------------------------------------------- */
00176 unsigned long CalculateBlockCRC32(
00177         unsigned long ulCount,    /* Number of bytes in the data block */
00178         unsigned char *ucBuffer ) /* Data block */
00179 {
00180     //////////////////////////////////////////////////////////////////////
00181     //the below code tests the CRC32Value procedure used in a markov form
00182     //////////////////////////////////////////////////////////////////////
00183     unsigned long CRC = 0;
00184     for (int i = 0; i<ulCount; i++)  CRC32Value( CRC, *ucBuffer++ );
00185     return  CRC;
00186 }
00187 
00188 /*
00189 unsigned long CalculateBlockCRC32(
00190         unsigned long ulCount, 
00191         unsigned char *ucBuffer )
00192 {
00193 ////////////////////////////////////////////
00194 //original code from the OEM615 manual
00195 ////////////////////////////////////////////
00196     unsigned long ulTemp1;
00197     unsigned long ulTemp2;
00198     unsigned long ulCRC = 0;
00199     while ( ulCount-- != 0 )
00200     {
00201         ulTemp1 = ( ulCRC >> 8 ) & 0x00FFFFFFL;
00202         ulTemp2 = CRC32Value( ((int) ulCRC ^ *ucBuffer++ ) & 0xff );
00203         ulCRC = ulTemp1 ^ ulTemp2;
00204     }
00205     return( ulCRC );
00206 }
00207 */
00208 void sendASCII(char* ASCI_message, int numChars)
00209 {
00210     /////////////////////////////////////////////////
00211     //send an ASCII command to the GPS receiver
00212     /////////////////////////////////////////////////
00213 
00214     //char ASCI_message[] = "unlogall COM1";
00215     int as = numChars - 1;
00216     unsigned char CR = 0x0d;  //ASCII Carriage Return
00217     unsigned char LF = 0x0a;  //ASCII Line Feed
00218     
00219     //printf("%s", ch);
00220     //printf("\n");
00221 
00222     for (int i=0; i<as; i++) GPS_COM1.putc(ASCI_message[i]); 
00223     GPS_COM1.putc(CR);   //carriage return at end
00224     GPS_COM1.putc(LF);   //line feed at end
00225 };
00226 
00227 
00228 //see the mbed COOKBOOK for MODSERIAL
00229 //MODSERIAL is an easy to use library that extends Serial to add fully buffered input and output.
00230 void readSerialByte(MODSERIAL_IRQ_INFO *q)
00231 { 
00232     MODSERIAL *serial = q->serial;      //see example of MODSERIAL usage in cookbook
00233     unsigned char synch0 = serial->getc();  //get the next byte
00234     
00235     //byteCounter is zeroed only at a 1PPA event in the 1PPS ISR
00236     //all message bytes stored for a single GPS second 
00237     msgBuffer[byteCounter % maxGPSbytesPerSec] = synch0;
00238     
00239      //accumulate the CRC for this message
00240      //incrementalCRC re-initialized after message header is is detected
00241      CRC32Value( incrementalCRC, synch0); 
00242 
00243     //Trap the GPS message header byte-string per Novatel OEM615 spec: 0xAA44121C
00244     //generate a 4-byte sliding-window sequence from the input bytes
00245     //shift last 4-byte value left 8 bits & push current-read byte (synch0) into low-order byte
00246     test = (test<<8) | synch0; 
00247    
00248     if (test == 0xAA44121C) //test for the Receiver message header signature
00249     {
00250         messageLocation[perSecMessageCounter % maxGPSMessagesPerSec] = byteCounter-3; //store the location of this message (1st of 4 synch word)
00251         perSecMessageCounter++;  //counts messages this second
00252         bytesFromMessageHdrDetect = 0;  //start byte counter for this message
00253         incrementalCRC = 0x39b0f0e1;    //initializes the recursive CRC after the AA44121C header byte sequence 
00254      }
00255      else if (bytesFromMessageHdrDetect == 5) messageLength.b[0] = synch0;  //first byte of msg length
00256      else if (bytesFromMessageHdrDetect == 6)   //second byte of message length
00257      {
00258         messageLength.b[1] = synch0; 
00259         endByteForCRCcomputation = 24 + messageLength.w;  //use union to perform byte-swap from stored bytes
00260      }
00261      else if (bytesFromMessageHdrDetect == endByteForCRCcomputation)  //stop the CRC recursive computation
00262         computedCRC = incrementalCRC;  //store the computed CRC for this message for use in main  
00263      else if (bytesFromMessageHdrDetect == (endByteForCRCcomputation + 4) )  //detect the end of the message (end of its CRC)
00264      {
00265         savedMessageCounter = perSecMessageCounter;  //message counter can be corrupted before use in main
00266         completeMessageAvailable = true;  //set flg for the main message processing
00267      }
00268          
00269      //byteCounter reset to zero in main after the 1PPS is detected -- its NOT reset in the 1PPS ISR
00270      byteCounter++;     //total per-sec byte counter (reset to zero in main when 1PPS detected) 
00271      bytesFromMessageHdrDetect++;  //counts the byes received after a message header
00272 };
00273 
00274 
00275 
00276 
00277 
00278 
00279