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:
27:94a6f0589993
Parent:
26:c2208b0ff78b
Child:
29:dead10cce6e9
--- a/main.cpp	Fri Jun 21 04:47:32 2013 +0000
+++ b/main.cpp	Fri Jun 21 05:48:02 2013 +0000
@@ -22,12 +22,23 @@
 DigitalInOut pre_fire(p30); //connected to the mid-connection for 2.5mm connector (T2i)
 
 
+
+/* Look at https://mbed.org/users/sam_grove/code/BufferedSerial/ */
+/* I wrote this and it works quite well. IRQ driven UART with software buffers for TX and RX */
+/* Same API as Serial with some enhancements */
+/* This will reduce the loop around main time. Right now the problem is that the delay */
+/* between events changes based on the UART speed */
+
 //USB serial data stream back to the PC
 Serial toPC(USBTX, USBRX);      //connect the GPS TX, RX to p9 and p10
 
 Timer timeFromStart;
 Timer timeFromPosVelMessageReceipt;
 
+/* should make all flags uint32_t for fastest access */
+/* encapsulate all this into a structure */
+/* or several based on what peripheral they belong to */
+
 bool detectedGPS1PPS = false;       //flag set in the ISR and reset after processing the 1PPS event
 int PPSCounter = 0;                 //counts the 1PPS occurrences
 int byteCounter = 0;                //byte counter -- zeroed at 1PPS
@@ -40,8 +51,12 @@
 bool camera1EventDetected = false;  //flag from ISR indicating a clock event occurred
 double camera1Time;                 //GPS time of the camera event 
 int TotalBadCRCmatches = 0;         //counter for the bad CRC matches for all GPS messages
+volatile int PPSTimeOffset = 0;
 
-volatile int PPSTimeOffset = 0;
+/* Ive done some of this. Look at: */
+/* https://mbed.org/users/sam_grove/code/OEM615/ */
+/* https://mbed.org/users/sam_grove/code/ADIS16488/ */
+/* a starting point that i'd done back during the hardware tester */
 
 //////////////////////////////////////////////////////////////////////
 // the below should become classes
@@ -51,6 +66,8 @@
 #include "PCMessaging.h"    //PC messaging activities
 
 
+/* This should be called from a PC message handler when found. */
+
 // stuff to send the SD file to the PC
 #include "SDShell.h"
 void transferFile()
@@ -66,6 +83,8 @@
     emulate.shell(toPC, sd, "/sd"); // now the SDShell object will serve SD files via UNIX commands
 }
 
+/* Move into the GPS class */
+
 //ISR for detection of the GPS 1PPS
 void detect1PPSISR(void)
 {
@@ -90,6 +109,10 @@
 };
 
 
+
+/* Break up into GPS class and PC message class */
+/* GPS boot up messages should be checking for a response rather than waiting a predefined time */
+/* SD card stuff should also be a seperate class. Allow for dynamic directory and file awareness */
 ///////////////////////////////////////////////////////
 //set up the USB port and the GPS COM port
 /////////////////////////////////////////////////////// 
@@ -191,6 +214,9 @@
 int main() 
 {
     
+    /* IMO this should all be ASCII (GPS data). Too much processing on the mbed side for messages that arent used */
+    /* the parsing and error checking + printf with floating point are EXPENSIVE CPU instructions */
+    
     //these are structures for the to GPS messages that must be parsed
     MESSAGEHEADER msgHdr;
     OEM615BESTPOS posMsg;   //BESTPOS structure in OEMV615.h that has matching time to a BESTVEL message
@@ -199,24 +225,41 @@
     OEM615BESTVEL curVel;   //BESTVEL structure in OEMV615.h
 
 
+    /* Self explanitory */
+    
     fire.output();  //set the fire pin as outoput
     pre_fire.output();  //set the pre-fire pin as output
+    
+    /* both should be open drain */
+    
     //fire.mode(OpenDrain);
     
+    /* not necessary if open drain outputs */
+    
     //set up for the first trigger
     fire = 1;
     pre_fire = 1;
+    
+    /* for lower power modes of operation all this should be different classes and called when the PC requests it */
+    /* always on and idle is a waste of battery power. Could probabally add 30-50% life by leaving things off until needed */
+    
     //set up the GPS and mbed COM ports
     setupCOM(); 
     
+    /* same as above */
+    
     //set up the ADIS16488 
     setupADIS();
 
     setUpMessages();  //set up the expected text message commands from the PC 
     
+    /* same as above */
+    
     //initiate the interrupt to catch the GPS receiver serial bytes as they are presented
     GPS_COM1.attach(&readSerialByte, MODSERIAL::RxIrq);
     
+    /* same as above */
+    
     timeFromPPS.start();  //start the time for measuring time from 1PPS events
     timeFromStart.start();
     
@@ -239,6 +282,9 @@
     recordData = false;
     sendRecData = false;     
     
+    /* I'd get these off the stack and into a global structure */
+    /* If you did have a stack error condition (buffer overwrite) all this could be clobbered */
+    
     unsigned long cyclesPerSec = 0;  //main while() loop cycles per GPS sec
     bool GPSdataWritten = false;
     bool finishTrigger = false;
@@ -246,6 +292,8 @@
     
     //while(PPSCounter < 300)
     
+    /* New command logic will keep this loop from ever exiting */
+    
     bool newMission = true;
     
     ///////////////////////////////////////////////////////////////////////////
@@ -254,9 +302,14 @@
     while(newMission)
     {        
             
+        /* right idea. Build messages and parse */
+        
         //read the USB serial data from the PC to check for commands
         readFromPC();
         
+        /* file should only be open when writing. If you crash and the file is open */
+        /* the data will be lost. Should be in a class that takes structures or strings to write to the file */
+        
         //this will close the fpNav file on the SD card if the file is open 
         //and the elapsed time from PosVel messages is > 60 secs
         //this prevents loosing the fpNav file if the PC goes down
@@ -267,9 +320,13 @@
             recordData  = false;
         }
                 
+        /* Should be done when reading and building the message */
+        
         // for any received PC message, take the appropriate action
         processPCmessages(fpNav, posMsg, velMsg);
         
+        /* file should always be closed until needed */
+        
         //if we receive a "GETFILE" message from the PC -- close the fpNavFile and break from the while() loop
         if (get_file_msg)  
         {
@@ -277,6 +334,10 @@
             break;  //terminate the while loop when we receive this message from the PC
         }
         
+        /* wait looks unnecessary (and bad during runtime). During all tests with the camera the pre-fire is */
+        /* 250mS before the fire. Not sure if this changes the time til shutter open */
+        /* Look at the Timeout class */
+        
         if(fireTrigger)  //comes from a PC request message
         {
             unsigned long triggerTime = GPSTimemsecs + PPSTimeOffset*1000.0 + timeFromPPS.read_us()/1000.0;
@@ -290,6 +351,8 @@
             triggerInterval.start();
         }
         
+        /* see above */
+        
         //the trigger requires a pulse -- the above portion lowers the signal and the below raises it
         //this has been tested at 50 msecs and it will not fire at that pulse duration
         if(finishTrigger && triggerInterval.read_ms() > 100)
@@ -300,6 +363,8 @@
             finishTrigger = false;  //completes the trigger firing pulse definition
         }
         
+        /* who clears this, PPS? */
+        
         cyclesPerSec++;
 
         ////////////////////////////////////////////////////////////////////////////
@@ -327,6 +392,8 @@
             //toPC.printf("tmeFrom1PPS= %5d  ID= %3d Ln = %3d computedCRC= %08x msgCRC= %08x msgCntr = %3d CRCerr=%4d\n", 
             //    timeFromPPS.read_us(), msgHdr.messageID, msgHdr.messageLength, computedCRC, msgCRC, savedMessageCounter, TotalBadCRCmatches);
                 
+            /* is this really necessary? Seems like keeping it in ascii and sending in ascii would make more sense */
+            
             if ( msgCRC == computedCRC)  //computedCRC is performed as we read each bvyte
             {
                 //if the CRC check is valid -- then get the time from the header
@@ -378,6 +445,8 @@
         }
 
         
+        /* should move into a file management class for protection and error checking */
+        
         //write the GPS data to the SD card
         //NOTE:  this is valid only for a once-per-sec GPS message
         //for this case, all messages come out well prior to 0.5 secs after the 1PPS
@@ -387,6 +456,9 @@
                 GPSdataWritten = true;
         }
         
+        /* would have 2 arrays of structures and a pointer in the class than changes between the buffers. */
+        /* This way there is 1 write and management in 1 place */
+        
         //the IMU data record is read from the SPI in the ISR and the IMUDataReady is set true
         //we write the IMU data here
         if (IMUDataReady)  //IMUDataReady is true if we have a recent IMU data record
@@ -406,6 +478,8 @@
             IMUDataReady = false;
         }
         
+        /* should remove floating point if possible and send as milli-sec integers */
+        
         //this is a command from the PC to fire a trigger
         if (camera1EventDetected)  //we have detected a camera trigger event
         {
@@ -413,6 +487,8 @@
             camera1EventDetected = false;
         }
         
+        /* managed in GPS class */
+        
         if (detectedGPS1PPS)  //true if we are exactly at a 1PPS event detection
         {   
             //toPC.printf("PPS=%4d stat=%1d bytes=%3d GPSMsgs=%2d  #write=%8d cycles=%6d\n", 
@@ -435,21 +511,30 @@
     ///////////////////////////////////////////
       
 
+     /* should already be closed by file management class */
+     
      if (fpNav != NULL)
      {
         fclose(fpNav);  //insurance
         toPC.printf("WMsg closeFPNav \n");
      }
      
+     /* accessable by SDShell class */
+     /* see: https://mbed.org/users/sam_grove/code/SDShell/ */
+     
      toPC.printf("WMsg totalBytesWritten  %5d \n", totalBytesWritten);
      wait_ms(100);
      
+     /* just a state of the communication management class */
+     
      //send the nav file to the PC
      transferFile();
      //rxMsg = txMsg = 0;  // just indicate that we're in here
      // to exit this function the HOST (ie: computer or PC app) must send "exit" otherwise the mbed will act
      // like a terminal and serve SD file data forever
     
+     /* no longer needed */
+     
      toPC.printf("WMsg normalTermination  \n");
      wait_ms(100);