this version has all of Jim's fixes for reading the GPS and IMU data synchronously

Dependencies:   MODSERIAL SDFileSystem mbed SDShell CRC CommHandler FP LinkedList LogUtil

Revision:
29:dead10cce6e9
Parent:
28:fcea53fcc712
Child:
30:96d133f3008e
--- a/OEM615.h	Wed Nov 13 22:12:04 2013 +0000
+++ b/OEM615.h	Thu Jan 09 14:09:05 2014 +0000
@@ -1,100 +1,5 @@
 #include "crc.h"
 
-#pragma pack(1)  //this forces the structure to be packed on byte boundaries (with no byte filler)
-//set up the GPS message header in a structure to enable easy reading -- see the OEM615 manual (Table 4, page 24)
-struct MESSAGEHEADER   
-{
-    char synchAA;                   //1st synch word
-    char synch44;                   //2nd synch word
-    char synch12;                   //3rd synch word
-    unsigned char headerLength;     //always 28
-    unsigned short messageID;       //42  (0x2A  BESTPOS) , 43 (2B  RANGE) , or 99 (x63 BESTVEL), 
-    char messageType;               //always = 0 for binary
-    unsigned char portAddress;      //0x20 for COM1
-    // from spec:  The length in bytes of the body of the message, not including the header nor the CRC
-    unsigned short messageLength;   //not including header or CRC
-    unsigned short sequence;        //typically 0
-    unsigned char idleTime;         //Time the processor is idle, in the last second
-    unsigned char timeStatus;       //Enum Indicating quality of the GPS reference time
-    unsigned short GPSweek;         //GPS reference week
-    unsigned long GPSTime_msecs;    //from beginning of week
-    unsigned long receiverStatus;   //32-bits representing the status of hardware and software
-    unsigned short reserved;
-    unsigned short receiverSWversion;  //receiver software build number
-    //total length in bytes of this header is 28
-};
-MESSAGEHEADER *msgHeader[6];
-
-#pragma pack(1)
-//structure for OEM615 BESTVEL log message  (page 314)
-struct OEM615BESTVEL
-{
-    MESSAGEHEADER msgHeader;
-    int solStatus;                      //solution status
-    //solutionStatusOEMStar solStatus;  //solution status
-    int velType;                        //position or velocity type
-    //velTypeOEMStar posType;           //position or velocity type   
-    float latency;
-    float age;
-    double horizontalSpeed;         //horizontal velocity vector magnitude (m/s)
-    double heading;                 //deg from North called TRK GND in specification
-    double verticalSpeed;           //vertical velocity magnitude (m/s)
-    float reserved;
-    unsigned long CRC;
-};
-
-/*  Solution Status descritpion from OEMV manual
-0   SOL_COMPUTED        Solution computed
-1   INSUFFICIENT_OBS    Insufficient observations
-2   NO_CONVERGENCE      No convergence
-3   SINGULARITY         Singularity at parameters matrix
-4   COV_TRACE           Covariance trace exceeds maximum (trace > 1000 m)
-5   TEST_DIST           Test distance exceeded (maximum of 3 rejections if distance >10 km)
-6   COLD_START          Not yet converged from cold start
-7   V_H_LIMIT           Height or velocity limits exceeded
-8   VARIANCE            Variance exceeds limits
-9   RESIDUALS           Residuals are too large
-10  DELTA_POS           Delta position is too large
-11  NEGATIVE_VAR        Negative variance
-12  Reserved
-13  INTEGRITY_WARNING   Large residuals make position unreliable
-18  PENDING             
-19  INVALID_FIX         The fixed position, entered using the FIX POSITION command, is not valid
-20  UNAUTHORIZED        Position type is unauthorized - HP or XP 
-*/
-
-#pragma pack(1)
-//structure for BESTPOS message 
-struct OEM615BESTPOS
-{
-    MESSAGEHEADER msgHeader;
-    int solStatus;                      //solution status
-    //solutionStatusOEMStar solStatus;  //solution status
-    int posType;                        //position or velocity type
-    //posTypeOEMStar posType;           //position or velocity type
-    double latitude;                    //latitude
-    double longitude;                   //longitude
-    double height;                      //height above mean sea level
-    float undulation;                   //the realtionship between the geoid and the
-                                        //ellipsoid of the chosen datum (m)
-    char datumID[4];                    //datum ID is actually an enum that is not implemented
-    float latitudeSTD;                  //latitude standard deviation
-    float longitudeSTD;                 //longitude standard deviation
-    float heightSTD;                    //height standard deviation
-    char baseStationID[4];              //base station ID
-    float diffAge;                      //differential age (s)
-    float solutionAge;                  //solution age (s)
-    unsigned char numSV;                //number of satellite vehicles tracked
-    unsigned char numSolSV;             //number of satellite vehicles used in solution
-    unsigned char numGGL1;              //number of GPS plus Glonass L1
-    unsigned char res1;
-    unsigned char res2;
-    unsigned char extSolStatus;         //extended solution status
-    unsigned char res3;
-    unsigned char sigMask;              //signals used mask
-    unsigned long CRC;
-};
-
 //GPS-specific pins
 DigitalOut GPS_Reset(p18);      //GPS RESET line
 InterruptIn PPSInt(p15);        // GPS 1PPS (timemark) from the OEM615
@@ -106,21 +11,20 @@
 //mbed tx/rx interface to the GPS COM1 port
 MODSERIAL GPS_COM1(p9,p10);  //this serial port communicates with the GPS receiver serial port (COM1)
 
-int test = 0;
-unsigned short messageCounter = 0;
-unsigned short savedMessageCounter = 0;
-const unsigned short maxGPSbytesPerSec = 1536;
-unsigned char msgBuffer[maxGPSbytesPerSec];  //array to contain one full second of GPS bytes
-const unsigned char maxGPSMessagesPerSec = 12;
-unsigned short messageLocation[maxGPSMessagesPerSec] = {0};  //stores the message location start within the message buffer
+bool loadingMessageBuffer = false;
+
+const unsigned short maxGPSbytesPerSec = 512;
 
-unsigned short bytesFromMessageHdrDetect = 0;
-union SWAPBYTES { unsigned char b[2]; unsigned short w; };
-volatile SWAPBYTES messageLength;  //used to swap the bytes
-unsigned long computedCRC = 0;  //final resulting computed CRC for this message
-unsigned long incrementalCRC = 0;  //incrementally-formed CRC over message sequence
-unsigned short endByteForCRCcomputation[maxGPSMessagesPerSec];
-bool completeMessageAvailable = false;
+int messagePerSecCounter = 0;
+unsigned char msgBuffer0[maxGPSbytesPerSec];  //array to contain one full second of GPS bytes
+unsigned char msgBuffer1[maxGPSbytesPerSec];  //array to contain one full second of GPS bytes
+unsigned char msgBuffer2[maxGPSbytesPerSec];  //array to contain one full second of GPS bytes
+int GPSbyteCounter0 = 0;
+int GPSbyteCounter1 = 0;
+int GPSbyteCounter2 = 0;
+bool message0Complete = false;
+bool message1Complete = false;
+bool message2Complete = false;
 
 void sendASCII(char* ASCI_message, int numChars)
 {
@@ -149,48 +53,38 @@
     MODSERIAL *serial = q->serial;      //see example of MODSERIAL usage in cookbook
     unsigned char synch0 = serial->getc();  //get the next byte
     
-    //byteCounter is zeroed only at a 1PPA event in the 1PPS ISR
-    //all message bytes stored for a single GPS second 
-    msgBuffer[byteCounter % maxGPSbytesPerSec] = synch0;
-    
-     //accumulate the CRC for this message
-     //incrementalCRC re-initialized after message header is is detected
-     CRC32Value( incrementalCRC, synch0); 
+    totalGPSBytes++;
 
-    //Trap the GPS message header byte-string per Novatel OEM615 spec: 0xAA44121C
-    //generate a 4-byte sliding-window sequence from the input bytes
-    //shift last 4-byte value left 8 bits & push current-read byte (synch0) into low-order byte
-    test = (test<<8) | synch0; 
-    
-    //alternative 8-byte test (uses a long long 64bit word)
-    //  AA44121C002A0020   //message 42 (BESTPOS)   
-    //  AA44121C002B0020   //message 43 (BESTVEL)
-    //  AA44121C00990020   //message 99 (RANGE)
-   
-    if (test == 0xAA44121C) //test for the Receiver message header signature
+    //all OEM615 GPS ASCII messages begin with the unique character: "#"
+    //read til we get a "#" and then start storing the message
+    if (synch0 == '#')
     {
-        messageLocation[perSecMessageCounter % maxGPSMessagesPerSec] = byteCounter-3; //store the location of this message (1st of 4 synch word)
-        perSecMessageCounter++;  //counts messages this second
-        bytesFromMessageHdrDetect = 0;  //start byte counter for this message
-        incrementalCRC = 0x39b0f0e1;    //initializes the recursive CRC after the AA44121C header byte sequence 
-     }
-     else if (bytesFromMessageHdrDetect == 5) messageLength.b[0] = synch0;  //first byte of msg length
-     else if (bytesFromMessageHdrDetect == 6)   //second byte of message length
-     {
-        messageLength.b[1] = synch0; 
-        endByteForCRCcomputation[perSecMessageCounter] = 24 + messageLength.w;  //use union to perform byte-swap from stored bytes
-     }
-     else if (bytesFromMessageHdrDetect == endByteForCRCcomputation[perSecMessageCounter])  //stop the CRC recursive computation
-        computedCRC = incrementalCRC;  //store the computed CRC for this message for use in main  
-     else if (bytesFromMessageHdrDetect == (endByteForCRCcomputation[perSecMessageCounter] + 4) )  //detect the end of the message (end of its CRC)
-     {
-        savedMessageCounter = perSecMessageCounter;  //message counter can be corrupted before use in main
-        completeMessageAvailable = true;  //set flg for the main message processing
-     }
-         
-     //byteCounter reset to zero in main after the 1PPS is detected -- its NOT reset in the 1PPS ISR
-     byteCounter++;     //total per-sec byte counter (reset to zero in main when 1PPS detected) 
-     bytesFromMessageHdrDetect++;  //counts the byes received after a message header
+        if     (messagePerSecCounter == 0)  GPSbyteCounter0 = 0;
+        else if(messagePerSecCounter == 1)  GPSbyteCounter1 = 0;
+        else if(messagePerSecCounter == 2)  GPSbyteCounter2 = 0;
+        loadingMessageBuffer = true;
+    }
+
+    if     (messagePerSecCounter == 0)  { msgBuffer0[GPSbyteCounter0 % maxGPSbytesPerSec] = synch0; GPSbyteCounter0++; }
+    else if(messagePerSecCounter == 1)  { msgBuffer1[GPSbyteCounter1 % maxGPSbytesPerSec] = synch0; GPSbyteCounter1++; }
+    else if(messagePerSecCounter == 2)  { msgBuffer2[GPSbyteCounter2 % maxGPSbytesPerSec] = synch0; GPSbyteCounter2++; }
+    
+    //stop storing the message when we get a LF
+    if (synch0 == 0x0a /* LF*/)   //test for line feed
+    {
+        if     (messagePerSecCounter == 0)  message0Complete = true;
+        else if(messagePerSecCounter == 1)  message1Complete = true;
+        else if(messagePerSecCounter == 2)  message2Complete = true;
+        messagePerSecCounter++;        //count the messages per second
+    }
+    
+    //how this can fail??
+    //  1) get noisy # occurrences (unique starting character)
+    //  2) get noisy LF occurrences (unique ending character)
+    //  3) get noisy data packet values or extra values
+    //  4) we will also need to vet the data on the PC side
+    //  5) here, we should do minimal testing and just pass the data as is 
+    
 };