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
Diff: main.cpp
- Revision:
- 27:94a6f0589993
- Parent:
- 26:c2208b0ff78b
- Child:
- 29:dead10cce6e9
diff -r c2208b0ff78b -r 94a6f0589993 main.cpp --- 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);