Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of GPS_Incremental by
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
Generated on Tue Jul 12 2022 19:39:50 by
1.7.2
