Test software for SatChat prototype hardware Platform - MAX32630FTHR

Dependencies:   USBDevice max32630fthr

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*  BLACK CODE INCLUDE START
00002     External libraries are worrying!
00003     Keep it simple and avoid anything non essential or obscure.
00004     Consider copying functions from libraries into the code so
00005     we have control. */
00006 #include "mbed.h"
00007 #include "max32630fthr.h"
00008 #include <stdbool.h>
00009 /*  BLACK CODE INCLUDE END */
00010 
00011 /*  BLACK CODE DEFINE START */
00012 #define ON 0
00013 #define OFF 1
00014 #define EXIT_SUCCESS 0
00015 #define EXIT_FAILURE 1
00016 /*  BLACK CODE DEFINE END */
00017 
00018 /*  BLACK CODE GLOBAL VAR START */
00019 const int GPS_TIMEOUT=180;            //Wait three minutes maximum for GPS.
00020 char gpsfix_last_utc_time[11] = {0};
00021 char gpsfix_last_utc_date[7] = {0};
00022 char gpsfix_longtitude[12] = {0};
00023 char gpsfix_latitude[12] = {0};
00024 char gpsfix_speed[8] = {0};     //Set but not used
00025 char gpsfix_course[7] = {0};    //Set but not used
00026 char gpsfix_variation[7] = {0}; //Set but not used
00027 char gpsfix_mag_var_ew[1] = {0};//Set but not used
00028 char gpsfix_ns = 0;
00029 char gpsfix_ew = 0;
00030 bool gps_data_present = false;  //If this is false we can't even use stale GPS data.
00031 /*  BLACK CODE GLOBAL VAR END */
00032 
00033 /*  BLACK CODE PERIPHERAL INIT START */
00034 DigitalOut red_led(LED1,1);
00035 DigitalOut green_led(LED2,1);
00036 DigitalOut gps_led(LED3,1); //Blue
00037 Serial pc(USBTX, USBRX);
00038 Serial gps(P5_3, P5_4, 9600);
00039 I2C i2c(P5_7,P6_0); // SDA, SCL
00040 /*  BLACK CODE PERIPHERAL INIT END */
00041 
00042 void gps_power(bool state)
00043 /*  BLACK CODE
00044     MAX32630FTHR routine to control the output of the 3v3 line.
00045     This is achieved by issuing commands to the MAX14690 controller.
00046     In this case when the GPS is shutdown we clear any serial
00047     data to avoid issues with mbeds buggy serial code  */
00048 {
00049     char    data[2];
00050     data[0] = 0x16;     //MAX14690 LDO3cfg register
00051     printf("GPS Power:");
00052     if (state == ON) {
00053         data[1] = 0xE2; //Enable LDO3
00054         i2c.write( 0x50, data, 2 );
00055         gps_led=ON;
00056         printf("ON\n\r");
00057     } else {
00058         data[1] = 0xE0; //Disable LDO3
00059         i2c.write( 0x50, data, 2 );
00060         gps_led=OFF;
00061         while (gps.readable()) {
00062                 char dummy = gps.getc();    //Empty serial buffer because overflows reveal MBED bugs :-(
00063         }
00064         printf("OFF\n\r");
00065     }
00066 }
00067 
00068 int get_epoch_from_last_gps_time(void)
00069 /*  BLACK CODE
00070     Given appropriate global char arrays of time and date information,
00071     return a unix time epoch.
00072 */
00073 {
00074     struct tm t;
00075     time_t epoch;
00076     char two_char_str[3] = {0};
00077     memcpy(two_char_str, gpsfix_last_utc_date+4, 2);
00078     t.tm_year = atoi(two_char_str)+100;         //Years since 1900
00079     memcpy(two_char_str, gpsfix_last_utc_date+2, 2);
00080     t.tm_mon = atoi(two_char_str)-1;            // Month, 0 - jan gpsfix_last_utc_date
00081     memcpy(two_char_str, gpsfix_last_utc_date, 2);
00082     t.tm_mday = atoi(two_char_str);             // Day of the month gpsfix_last_utc_date
00083     memcpy(two_char_str, gpsfix_last_utc_time, 2);
00084     t.tm_hour = atoi(two_char_str);
00085     memcpy(two_char_str, gpsfix_last_utc_time+2, 2);
00086     t.tm_min = atoi(two_char_str);
00087     memcpy(two_char_str, gpsfix_last_utc_time+4, 2);
00088     t.tm_sec = atoi(two_char_str);
00089     t.tm_isdst = 0;        // Is DST on? 1 = yes, 0 = no, -1 = unknown
00090     epoch = mktime(&t);
00091     return epoch;
00092     //BLACK CODE
00093 }
00094 
00095 int gps_update(void)
00096 /*  BLACK CODE
00097     gps_update
00098     Reads NMEA data from a serial interface defined as "gps".
00099     The function waits for a valid $GPRMC sentence. It then decodes the sentence and populates the
00100     following global variables which are assumed to exist.
00101     
00102     gpsfix_last_utc_time[11] = {0}; char gpsfix_last_utc_date[7] = {0};char gpsfix_longtitude[12] = {0};
00103     char gpsfix_latitude[12] = {0}; char gpsfix_speed[8] = {0}; char gpsfix_course[7] = {0};
00104     char gpsfix_variation[7] = {0}; char gpsfix_mag_var_ew[1] = {0}; char gpsfix_ns = 0; char gpsfix_ew = 0;
00105     
00106     The following are also assumed to be part of the global declarations.
00107     #define EXIT_SUCCESS 0
00108     #define EXIT_FAILURE 1
00109     const int GPS_TIMEOUT=180;
00110     a gps_power() function that controls power to the GPS unit.
00111     
00112     If the function is successful it returns a 0.  If a valid fix is not obtined within the GPS_TIMEOUT 
00113     period a 1 is returned.
00114     
00115     The code has been tested with a uBlox 6M but other GPS units may work.
00116     The code is deliberately blocking as the mbed OS seems to crash on serial interrupts and buffer overflow.
00117     The serial port is continuously read while waiting for a fix. Once a fix is obtained or a timeout occurs
00118     the GPS is powered down and remaining data read out of the buffer.
00119 */
00120 {
00121     gps_power(ON);
00122     time_t gps_on_time = time(NULL);    //Start time for GPS timeout calculation.
00123     bool wait_for_fix = true;           //Set this to false once a fix is obtained.
00124     while (wait_for_fix) {              //Keep monitoring the GPS until we get a fix.
00125         if ((time(NULL) - gps_on_time) > GPS_TIMEOUT) {
00126             gps_power(OFF);
00127             return EXIT_FAILURE;        //Return an error if the GPS takes too long for a fix.
00128         }
00129         int checksum = 0;
00130         char nmea_sentence[83] = {0};   //NMEA length max is 82 + 1 terminator. Fill with NULL terminators to save doing it later.
00131         while (gps.getc()!='$');        //wait for start of sentence
00132         int nmea_index = 0;
00133         nmea_sentence[nmea_index] = '$';    //Manually insert the '$' because we don't want it included in the checksum loop
00134         char nmea_char = gps.getc();        //get sentence first char from GPS
00135         while (nmea_char != '*') {          //Loop, building sentence and calc'ing CS until a * is seen
00136             checksum ^= nmea_char;          //Calc checksum as we read sentence
00137             if ((nmea_sentence[nmea_index] == ',')&&(nmea_char == ',')) {
00138                 nmea_sentence[++nmea_index] = ' ';      //Pad consecutive comma with a space to make it possible to use strtok with empty values
00139             }
00140             nmea_sentence[++nmea_index] = nmea_char;    //build the sentence with the next character
00141             if (nmea_index > 81) {
00142                 nmea_index=81;          //Don't overflow sentence buffer
00143             }
00144             nmea_char = gps.getc();     //get next char from GPS
00145         }
00146         //Last character was the '*' so next two are CS
00147         char hex_checksum[3] = {0};
00148         hex_checksum[0] = gps.getc();
00149         hex_checksum[1] = gps.getc();
00150         if (checksum == (int)strtol(hex_checksum, NULL, 16) ) {     //Compare calc and read checksums.
00151             //Valid sentence so check if it's a GPRMC
00152             const char gprmc[7] = "$GPRMC";
00153             char *token;
00154             token = strtok(nmea_sentence, ",");
00155             if (strcmp(token,gprmc) == 0) {     //GPRMC
00156 pc.printf( " %s\n\r", token );  //Get the time
00157                 if (token != NULL) {
00158                     token = strtok(NULL, ",");
00159                     if (*token != 32) {         //If there is a time present (anything but a space), record it.
00160                         //pc.printf("Time: %s\n\r",token);
00161                         gps_led =! gps_led;   //Flash blue LED
00162                         memcpy(gpsfix_last_utc_time, token, sizeof gpsfix_last_utc_time - 1);
00163                     }
00164                 }
00165                 if (token != NULL) {
00166                     token = strtok(NULL, ",");
00167 if (*token == 'V') {
00168        pc.printf("VOID");
00169 } 
00170                 } 
00171                 if (*token == 'A') {                //Is this an 'A'ctive (valid) fix?
00172                     pc.printf("Got a fix\n\r");
00173                     gps_power(OFF);                 //Yes - No need for GPS now
00174                     wait_for_fix = false;           //Stop looping now we have a fix.
00175                     if (token != NULL) {
00176                         token = strtok(NULL, ",");
00177 pc.printf("Latitude: %s\n\r",token);
00178                         memcpy(gpsfix_latitude, token, sizeof gpsfix_latitude - 1);
00179                     }
00180                     if (token != NULL) {
00181                         token = strtok(NULL, ",");
00182 pc.printf("North/South: %s\n\r",token);
00183                         gpsfix_ns = *token;
00184                     }
00185                     if (token != NULL) {
00186                         token = strtok(NULL, ",");
00187 pc.printf("Longitude: %s\n\r",token);
00188                         memcpy(gpsfix_longtitude, token, sizeof gpsfix_longtitude - 1);
00189                     }
00190                     if (token != NULL) {
00191                         token = strtok(NULL, ",");
00192 pc.printf("East/West: %s\n\r",token);
00193                         gpsfix_ew = *token;
00194                     }
00195                     if (token != NULL) {
00196                         token = strtok(NULL, ",");
00197                         //pc.printf("Speed in knots: %s\n\r",token);
00198                     }
00199                     if (token != NULL) {
00200                         token = strtok(NULL, ",");
00201                         //pc.printf("True course: %s\n\r",token);
00202                     }
00203                     if (token != NULL) {
00204                         token = strtok(NULL, ",");
00205 pc.printf("Date: %s\n\r",token);
00206                         memcpy(gpsfix_last_utc_date, token, sizeof gpsfix_last_utc_date - 1);
00207                     }
00208                     if (token != NULL) {
00209                         token = strtok(NULL, ",");
00210                         //pc.printf("Variation: %s\n\r",token);
00211                     }
00212                     if (token != NULL) {
00213                         token = strtok(NULL, ",");
00214                         //pc.printf("Variation East/West: %s\n\r",token);
00215                     }
00216                 }
00217             }
00218         }
00219     }
00220     return EXIT_SUCCESS;
00221     //BLACK CODE
00222 }
00223 
00224 main()
00225 {   /*Set the power button behaviour.
00226       char    data[2];
00227       data[0] = 0x1A;     //MAX14690 BootCfg register
00228       data[1] = 0x30;     //Always-On Mode, off state via PWR_OFF_CMD
00229       i2c.write( 0x50, data, 2 );
00230     */
00231     
00232     //Set the voltage to 3v3 for the GPS.
00233     char data[2];
00234     data[0] = 0x17;     //MAX14690 LDO3Vset register
00235     data[1] = 0x19;     //3.3V
00236     i2c.write( 0x50, data, 2 );
00237     gps_power(OFF);
00238 
00239     while (1) {
00240         if (gps_update()==EXIT_SUCCESS) {
00241             gps_data_present = true;
00242             int gps_epoch = get_epoch_from_last_gps_time();
00243             set_time(gps_epoch);
00244             pc.printf("Got a GPS fix and time.\n\r");
00245         } else {
00246             pc.printf("GPS timed out and we have no existing fix.\n\r");
00247             pc.printf("We can send an Iridium packet but coordinates are rough.\n\r");
00248         }
00249         time_t seconds = time(NULL);
00250         //printf("Time as a basic string = %s", ctime(&seconds));
00251         wait(60);
00252         seconds = time(NULL);
00253 
00254         wait(33);
00255         seconds = time(NULL);
00256         printf("Time as a basic string = %s", ctime(&seconds));
00257         wait(60);
00258     } 
00259 }
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268