Test software for SatChat prototype hardware Platform - MAX32630FTHR
Dependencies: USBDevice max32630fthr
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
Generated on Wed Jul 13 2022 02:51:16 by 1.7.2