Test software for SatChat prototype hardware Platform - MAX32630FTHR

Dependencies:   USBDevice max32630fthr

main.cpp

Committer:
koziniec
Date:
2017-07-03
Revision:
14:8ff04e82bda2
Parent:
13:ff0b39177386
Child:
15:7d75ecaeabdb

File content as of revision 14:8ff04e82bda2:


#include "mbed.h"
#include "max32630fthr.h"
#include <stdbool.h>
#define ON 0
#define OFF 1
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
const int GPS_TIMEOUT=180;            //Wait three minutes maximum for GPS.

Serial pc(USBTX, USBRX);
Serial gps(P5_3, P5_4, 9600);
I2C i2c(P5_7,P6_0); // SDA, SCL

DigitalOut red_led(LED1,1);
DigitalOut green_led(LED2,1);
DigitalOut gps_led(LED3,1); //Blue
char gpsfix_last_utc_time[11] = {0};
char gpsfix_last_utc_date[7] = {0};
char gpsfix_longtitude[12] = {0};
char gpsfix_latitude[12] = {0};
char gpsfix_speed[8] = {0};     //Set but not used
char gpsfix_course[7] = {0};    //Set but not used
char gpsfix_variation[7] = {0}; //Set but not used
char gpsfix_mag_var_ew[1] = {0};//Set but not used
char gpsfix_ns = 0;
char gpsfix_ew = 0;
bool gps_data_present = false;  //If this is false we can't even use stale GPS data.

void gps_power(bool state)
{
    char    data[2];
    data[0] = 0x16;     //MAX14690 LDO3cfg register
    if (state == ON) {
        data[1] = 0xE2; //Enable LDO3
        i2c.write( 0x50, data, 2 );
        gps_led=ON;
    } else {
        data[1] = 0xE0; //Disable LDO3
        i2c.write( 0x50, data, 2 );
        gps_led=OFF;
        while (gps.readable()) {
                char dummy = gps.getc();    //Empty serial buffer because overflows reveal MBED bugs :-(
        }
    }
}

int get_epoch_from_last_gps_time(void)
{
    struct tm t;
    time_t epoch;
    char two_char_str[3] = {0};
    memcpy(two_char_str, gpsfix_last_utc_date+4, 2);
    t.tm_year = atoi(two_char_str)+100;         //Years since 1900
    memcpy(two_char_str, gpsfix_last_utc_date+2, 2);
    t.tm_mon = atoi(two_char_str)-1;            // Month, 0 - jan gpsfix_last_utc_date
    memcpy(two_char_str, gpsfix_last_utc_date, 2);
    t.tm_mday = atoi(two_char_str);             // Day of the month gpsfix_last_utc_date
    memcpy(two_char_str, gpsfix_last_utc_time, 2);
    t.tm_hour = atoi(two_char_str);
    memcpy(two_char_str, gpsfix_last_utc_time+2, 2);
    t.tm_min = atoi(two_char_str);
    memcpy(two_char_str, gpsfix_last_utc_time+4, 2);
    t.tm_sec = atoi(two_char_str);
    t.tm_isdst = 0;        // Is DST on? 1 = yes, 0 = no, -1 = unknown
    epoch = mktime(&t);
    return epoch;
}

int gps_update(void)
{
    gps_power(ON);
    time_t gps_on_time = time(NULL);    //Start time for GPS timeout calculation.
    bool wait_for_fix = true;           //Set this to false once a fix is obtained.
    while (wait_for_fix) {              //Keep monitoring the GPS until we get a fix.
        if ((time(NULL) - gps_on_time) > GPS_TIMEOUT) {
            gps_power(OFF);
            return EXIT_FAILURE;        //Return an error if the GPS takes too long for a fix.
        }
        int checksum = 0;
        char nmea_sentence[83] = {0};   //NMEA length max is 82 + 1 terminator. Fill with NULL terminators to save doing it later.
        while (gps.getc()!='$');        //wait for start of sentence
        int nmea_index = 0;
        nmea_sentence[nmea_index] = '$';    //Manually insert the '$' because we don't want it included in the checksum loop
        char nmea_char = gps.getc();        //get sentence first char from GPS
        while (nmea_char != '*') {          //Loop building sentence and calc'ing CS until *
            checksum ^= nmea_char;         //Calc checksum as we read sentence
            if ((nmea_sentence[nmea_index] == ',')&&(nmea_char == ',')) {
                nmea_sentence[++nmea_index] = ' ';  //Pad consecutive comma with a space to make it possible to use strtok with empty values
            }
            nmea_sentence[++nmea_index] = nmea_char; //build the sentence with the next character
            if (nmea_index > 81) {
                nmea_index=81;          //Don't overflow sentence buffer
            }
            nmea_char = gps.getc();     //get next char from GPS
        }
        //Last character was the '*' so next two are CS
        char hex_checksum[3] = {0};
        hex_checksum[0] = gps.getc();
        hex_checksum[1] = gps.getc();
        if (checksum == (int)strtol(hex_checksum, NULL, 16) ) {     //Compare calc and read checksums.

            //Valid sentence so check if it's a GPRMC
            const char gprmc[7] = "$GPRMC";
            char *token;
            token = strtok(nmea_sentence, ",");
            if (strcmp(token,gprmc) == 0) {     //GPRMC ?
                //pc.printf( " %s\n\r", token );  //Get the time
                if (token != NULL) {
                    token = strtok(NULL, ",");
                    if (*token != 32) {         //If there is a time present (anything but a space), record it.
                        //pc.printf("Time: %s\n\r",token);
                        gps_led =! gps_led;   //Flash blue LED
                        memcpy(gpsfix_last_utc_time, token, sizeof gpsfix_last_utc_time - 1);
                    }
                }
                if (token != NULL) {
                    token = strtok(NULL, ",");
                /*    if (*token == 'V') {
                        pc.printf("VOID");
                    } */
                } 
                if (*token == 'A') {                //Is this an 'A'ctive (valid) fix?
                    pc.printf("Got a fix\n\r");
                    gps_power(OFF);                 //Yes - No need for GPS now
                    wait_for_fix = false;           //Stop looping now we have a fix.
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        //pc.printf("Latitude: %s\n\r",token);
                        memcpy(gpsfix_latitude, token, sizeof gpsfix_latitude - 1);
                    }
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        //pc.printf("North/South: %s\n\r",token);
                        gpsfix_ns = *token;
                    }
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        //pc.printf("Longitude: %s\n\r",token);
                        memcpy(gpsfix_longtitude, token, sizeof gpsfix_longtitude - 1);
                    }
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        //pc.printf("East/West: %s\n\r",token);
                        gpsfix_ew = *token;
                    }
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        pc.printf("Speed in knots: %s\n\r",token);
                    }
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        //pc.printf("True course: %s\n\r",token);
                    }
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        //pc.printf("Date: %s\n\r",token);
                        memcpy(gpsfix_last_utc_date, token, sizeof gpsfix_last_utc_date - 1);
                    }
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        //pc.printf("Variation: %s\n\r",token);
                    }
                    if (token != NULL) {
                        token = strtok(NULL, ",");
                        //pc.printf("Variation East/West: %s\n\r",token);
                    }
                }
            }
        }
    }
    return EXIT_SUCCESS;
}

main()
{
    char    data[2];
    data[0] = 0x1A;     //MAX14690 BootCfg register
    data[1] = 0x30;     //Always-On Mode, off state via PWR_OFF_CMD
    i2c.write( 0x50, data, 2 );

    data[0] = 0x17;     //MAX14690 LDO3Vset register
    data[1] = 0x19;     //3.3V
    i2c.write( 0x50, data, 2 );
    gps_power(OFF);
    wait(2);
    pc.printf("\n\n\rOpen EPIRB - Simple mode\n\r");
    pc.printf("Press and hold both side buttons to signal rescue needed\n\r");
    pc.printf("Full functionality will start in:");
    for (int i=9; i > 0; i--) {
        time_t seconds = time(NULL);    //get current epoch
        pc.printf("%d",i);
        while(time(NULL) - seconds < 1) {
            if (true/*button_combination()==SOS_PRESSED*/) {
                //do the emergency code
                if (gps_update()==EXIT_SUCCESS) {
                    gps_data_present = true;
                    int gps_epoch = get_epoch_from_last_gps_time();
                    set_time(gps_epoch);
                    pc.printf("Got a GPS fix and time.\n\r");
                    pc.printf("Sending SOS in 10 seconds");
                    green_led=ON;
                } else {
                    pc.printf("\n\rGPS timed out and we have no existing fix.\n\r");
                    pc.printf("We can send an Iridium packet but coordinates are rough.\n\r");
                    pc.printf("Sending SOS in 10 seconds");
                    red_led=ON;
                }
                while(true) {}; //STOP HERE
            }
        }
        pc.printf("\b");            //Backspace
    }
    // normal functionality lives here
    pc.printf("\n\rStarting normal operation\n\r");
/*
    if (true) {         //Temp simulation
        while (1) {
            if (gps_update()==EXIT_SUCCESS) {
                gps_data_present = true;
                int gps_epoch = get_epoch_from_last_gps_time();
                set_time(gps_epoch);
                pc.printf("Got a GPS fix and time.\n\r");
            } else {
                pc.printf("GPS timed out and we have no existing fix.\n\r");
                pc.printf("We can send an Iridium packet but coordinates are rough.\n\r");
            }
            time_t seconds = time(NULL);
            //printf("Time as a basic string = %s", ctime(&seconds));
            wait(60);
            seconds = time(NULL);

            wait(33);
            seconds = time(NULL);
            printf("Time as a basic string = %s", ctime(&seconds));
            wait(60);
        } */
    }