Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: USBDevice max32630fthr
Revision 15:7d75ecaeabdb, committed 2017-07-04
- Comitter:
- koziniec
- Date:
- Tue Jul 04 17:24:55 2017 +0000
- Parent:
- 14:8ff04e82bda2
- Child:
- 16:c5634210628d
- Commit message:
- Essential documentation of the GPS BLACK CODE is completed.; Time to move onto the RockBlock code.
Changed in this revision
| BLACKCODE.txt | Show annotated file Show diff for this revision Revisions of this file |
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLACKCODE.txt Tue Jul 04 17:24:55 2017 +0000 @@ -0,0 +1,29 @@ +An EPIRB is a crucial piece of safety equipment. Someone's life could be placed at risk if it fails or behaves in an unpredictable manner. +An open EPIRB encourages development and feature enhancement which is a good thing but is potentially at odds with safety. What if you +change the user interface and the user can't figure out how to send an SOS? What if you introduce a bug and unit crashes? + +To address this issue, open EPIRB uses a two phase start up. When you initially power on the device it enters a minimum functionality mode +during which one of two messages can be sent. A routine positional update which logs the operator's current GPS location via the Iridium +Satellite constellation or an SOS message. After a brief period the minimum functionality phase ends and the full functionality begins. +In the full functionality phase it is possible to do everything that can be done in the minimum functionality mode as well as sending and +receiving short text messages, regularly logging position and any other functions that are yet to be thought of. + +Every piece of configuration and code necessary to achieve minimum functionality is known as BLACK CODE. To achieve reliability BLACK CODE +changes are not made trivially. They should be limited to bug fixes, usability and perhaps improving readibility and understanding of the code. +Before making a change to BLACK CODE, ask yourself how this enhances the reliability of the unit. This is an area of minimum functionality and +not a place to add new features. Adding a new feature increases the chance of failure and consequently increases the risk that a needed SOS +won't be sent. When it is necessary to make BLACK CODE changes it is essential the changes are thoroughly thought through, tested and approved +by the client. Any additional libraries, functions or variables must be labelled as BLACK if any BLACK CODE relies on it. + +Only BLACK CODE should run until the end of the minimum functionality period. In fact, a good test of the code base is to delete everything that +isn't BLACK and show that an SOS can still be sent. + +After the minimum functionality period expires, functionality is deliverd by regular code (non BLACK). Here careful coding and rigourous testing +should also occur but development and functionality are encouraged. + +REUSE OF BLACK CODE +The full functionality program space is encouraged to reuse BLACK code as this serves to further exercise and test these crucial components. If there is a +proposal for substantial changes to be made to BLACK CODE functions, it is recommended that the BLACK CODE functions be replicated in their new form +and labelled as RED CODE. The full functionality code should then call on the experimental RED CODE to allow debugging and field evaluation to +occur without jeapordising the stability of the BLACK CODE code base. Once the RED CODE is thouroughly debugged, tested and documented it can +be considered for inclusion as BLACK CODE. Thus the full functionality code becomes a testing environment for the minimum functionality code base. \ No newline at end of file
--- a/main.cpp Mon Jul 03 16:50:59 2017 +0000
+++ b/main.cpp Tue Jul 04 17:24:55 2017 +0000
@@ -1,20 +1,22 @@
-
+/* BLACK CODE INCLUDE START
+ External libraries are worrying!
+ Keep it simple and avoid anything non essential or obscure.
+ Consider copying functions from libraries into the code so
+ we have control. */
#include "mbed.h"
#include "max32630fthr.h"
#include <stdbool.h>
+/* BLACK CODE INCLUDE END */
+
+/* BLACK CODE DEFINE START */
#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.
+/* BLACK CODE DEFINE END */
-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
+/* BLACK CODE GLOBAL VAR START */
+const int GPS_TIMEOUT=180; //Wait three minutes maximum for GPS.
char gpsfix_last_utc_time[11] = {0};
char gpsfix_last_utc_date[7] = {0};
char gpsfix_longtitude[12] = {0};
@@ -26,8 +28,23 @@
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.
+/* BLACK CODE GLOBAL VAR END */
+
+/* BLACK CODE PERIPHERAL INIT START */
+DigitalOut red_led(LED1,1);
+DigitalOut green_led(LED2,1);
+DigitalOut gps_led(LED3,1); //Blue
+Serial pc(USBTX, USBRX);
+Serial gps(P5_3, P5_4, 9600);
+I2C i2c(P5_7,P6_0); // SDA, SCL
+/* BLACK CODE PERIPHERAL INIT END */
void gps_power(bool state)
+/* BLACK CODE
+ MAX32630FTHR routine to control the output of the 3v3 line.
+ This is achieved by issuing commands to the MAX14690 controller.
+ In this case when the GPS is shutdown we clear any serial
+ data to avoid issues with mbeds buggy serial code */
{
char data[2];
data[0] = 0x16; //MAX14690 LDO3cfg register
@@ -46,6 +63,10 @@
}
int get_epoch_from_last_gps_time(void)
+/* BLACK CODE
+ Given appropriate global char arrays of time and date information,
+ return a unix time epoch.
+*/
{
struct tm t;
time_t epoch;
@@ -65,9 +86,34 @@
t.tm_isdst = 0; // Is DST on? 1 = yes, 0 = no, -1 = unknown
epoch = mktime(&t);
return epoch;
+ //BLACK CODE
}
int gps_update(void)
+/* BLACK CODE
+ gps_update
+ Reads NMEA data from a serial interface defined as "gps".
+ The function waits for a valid $GPRMC sentence. It then decodes the sentence and populates the
+ following global variables which are assumed to exist.
+
+ 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}; char gpsfix_course[7] = {0};
+ char gpsfix_variation[7] = {0}; char gpsfix_mag_var_ew[1] = {0}; char gpsfix_ns = 0; char gpsfix_ew = 0;
+
+ The following are also assumed to be part of the global declarations.
+ #define EXIT_SUCCESS 0
+ #define EXIT_FAILURE 1
+ const int GPS_TIMEOUT=180;
+ a gps_power() function that controls power to the GPS unit.
+
+ If the function is successful it returns a 0. If a valid fix is not obtined within the GPS_TIMEOUT
+ period a 1 is returned.
+
+ The code has been tested with a uBlox 6M but other GPS units may work.
+ The code is deliberately blocking as the mbed OS seems to crash on serial interrupts and buffer overflow.
+ The serial port is continuously read while waiting for a fix. Once a fix is obtained or a timeout occurs
+ the GPS is powered down and remaining data read out of the buffer.
+*/
{
gps_power(ON);
time_t gps_on_time = time(NULL); //Start time for GPS timeout calculation.
@@ -83,12 +129,12 @@
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
+ while (nmea_char != '*') { //Loop, building sentence and calc'ing CS until a * is seen
+ 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] = ' '; //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
+ 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
}
@@ -99,7 +145,6 @@
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;
@@ -146,7 +191,7 @@
}
if (token != NULL) {
token = strtok(NULL, ",");
- pc.printf("Speed in knots: %s\n\r",token);
+ //pc.printf("Speed in knots: %s\n\r",token);
}
if (token != NULL) {
token = strtok(NULL, ",");
@@ -170,20 +215,26 @@
}
}
return EXIT_SUCCESS;
+ //BLACK CODE
}
main()
-{
+/* Start of BLACK CODE region. This area provides minimal SOS and position
+ updating. It needs to be robust and well tested. Put all the fancy stuff
+ outside this area. Changes here should be limited to fixing bugs and
+ simplifying the code.
+*/
+{ //Set the power button behaviour.
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 );
-
+ //Set the voltage to 3v3 for the GPS.
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:");
@@ -191,7 +242,7 @@
time_t seconds = time(NULL); //get current epoch
pc.printf("%d",i);
while(time(NULL) - seconds < 1) {
- if (true/*button_combination()==SOS_PRESSED*/) {
+ if (false/*button_combination()==SOS_PRESSED*/) {
//do the emergency code
if (gps_update()==EXIT_SUCCESS) {
gps_data_present = true;
@@ -211,7 +262,8 @@
}
pc.printf("\b"); //Backspace
}
- // normal functionality lives here
+/* END OF BLACK CODE REGION - Put all the fancy stuff down here
+*/
pc.printf("\n\rStarting normal operation\n\r");
/*
if (true) { //Temp simulation