From 524665fc221b0d483453c67b7211e282cebc8980 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Nov 2009 16:04:41 -0800 Subject: [PATCH] Add date to GPS data, captured from GPRMC packet. Pull the date out of the GPS stream and send it over the telemetry link and write it to the eeprom. Signed-off-by: Keith Packard --- ao-tools/ao-view/aoview_state.c | 4 ++ ao-tools/lib/cc-telem.c | 12 ++++++ ao-tools/lib/cc.h | 3 ++ src/ao.h | 10 +++++ src/ao_gps_print.c | 4 ++ src/ao_gps_report.c | 12 +++++- src/ao_gps_skytraq.c | 67 +++++++++++++++++++++++++++++---- src/ao_gps_test.c | 4 ++ src/ao_gps_test_skytraq.c | 4 ++ 9 files changed, 111 insertions(+), 9 deletions(-) diff --git a/ao-tools/ao-view/aoview_state.c b/ao-tools/ao-view/aoview_state.c index 2f613d44..21cea99a 100644 --- a/ao-tools/ao-view/aoview_state.c +++ b/ao-tools/ao-view/aoview_state.c @@ -315,6 +315,10 @@ aoview_state_notify(struct cc_telem *data) aoview_state_add_deg(1, "Longitude", state->gps.lon, 'E', 'W'); aoview_table_add_row(1, "GPS altitude", "%d", state->gps.alt); aoview_table_add_row(1, "GPS height", "%d", state->gps_height); + aoview_table_add_row(1, "GPS date", "%04d-%02d-%02d", + state->gps.gps_time.year, + state->gps.gps_time.month, + state->gps.gps_time.day); aoview_table_add_row(1, "GPS time", "%02d:%02d:%02d", state->gps.gps_time.hour, state->gps.gps_time.minute, diff --git a/ao-tools/lib/cc-telem.c b/ao-tools/lib/cc-telem.c index 0e1483f7..9a2f6155 100644 --- a/ao-tools/lib/cc-telem.c +++ b/ao-tools/lib/cc-telem.c @@ -127,6 +127,7 @@ cc_telem_parse(const char *input_line, struct cc_telem *telem) if (strcmp (words[36], "unlocked") == 0) { telem->gps.gps_connected = 1; telem->gps.gps_locked = 0; + telem->gps.gps_time.year = telem->gps.gps_time.month = telem->gps.gps_time.day = 0; telem->gps.gps_time.hour = telem->gps.gps_time.minute = telem->gps.gps_time.second = 0; telem->gps.lat = telem->gps.lon = 0; telem->gps.alt = 0; @@ -134,6 +135,16 @@ cc_telem_parse(const char *input_line, struct cc_telem *telem) } else if (nword >= 40) { telem->gps.gps_locked = 1; telem->gps.gps_connected = 1; + if (version >= 2) { + sscanf(words[36], "%d-%d-%d", + &telem->gps.gps_time.year, + &telem->gps.gps_time.month, + &telem->gps.gps_time.day); + words += 1; + nword -= 1; + } else { + telem->gps.gps_time.year = telem->gps.gps_time.month = telem->gps.gps_time.day = 0; + } sscanf(words[36], "%d:%d:%d", &telem->gps.gps_time.hour, &telem->gps.gps_time.minute, &telem->gps.gps_time.second); cc_parse_pos(&telem->gps.lat, words[37]); cc_parse_pos(&telem->gps.lon, words[38]); @@ -142,6 +153,7 @@ cc_telem_parse(const char *input_line, struct cc_telem *telem) } else { telem->gps.gps_connected = 0; telem->gps.gps_locked = 0; + telem->gps.gps_time.year = telem->gps.gps_time.month = telem->gps.gps_time.day = 0; telem->gps.gps_time.hour = telem->gps.gps_time.minute = telem->gps.gps_time.second = 0; telem->gps.lat = telem->gps.lon = 0; telem->gps.alt = 0; diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h index b8e3c061..ebc0db7d 100644 --- a/ao-tools/lib/cc.h +++ b/ao-tools/lib/cc.h @@ -192,6 +192,9 @@ struct cc_flightcooked { struct cc_gps_time { + int year; + int month; + int day; int hour; int minute; int second; diff --git a/src/ao.h b/src/ao.h index f266ac64..c1a0f6e3 100644 --- a/src/ao.h +++ b/src/ao.h @@ -493,6 +493,7 @@ ao_ee_init(void); #define AO_LOG_GPS_LON 'W' #define AO_LOG_GPS_ALT 'H' #define AO_LOG_GPS_SAT 'V' +#define AO_LOG_GPS_DATE 'Y' #define AO_LOG_POS_NONE (~0UL) @@ -538,6 +539,11 @@ struct ao_log_record { uint8_t state; uint8_t c_n; } gps_sat; + struct { + uint8_t year; + uint8_t month; + uint8_t day; + } gps_date; struct { uint16_t d0; uint16_t d1; @@ -720,8 +726,12 @@ ao_serial_init(void); #define AO_GPS_VALID (1 << 4) #define AO_GPS_RUNNING (1 << 5) +#define AO_GPS_DATE_VALID (1 << 6) struct ao_gps_data { + uint8_t year; + uint8_t month; + uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; diff --git a/src/ao_gps_print.c b/src/ao_gps_print.c index cc751337..95439ec7 100644 --- a/src/ao_gps_print.c +++ b/src/ao_gps_print.c @@ -53,6 +53,10 @@ ao_gps_print(__xdata struct ao_gps_data *gps_data) __reentrant ao_gps_split(gps_data->latitude, &lat); ao_gps_split(gps_data->longitude, &lon); + printf(" 20%02d-%02d-%02d", + gps_data->year, + gps_data->month, + gps_data->day); printf(" %2d:%02d:%02d", gps_data->hour, gps_data->minute, diff --git a/src/ao_gps_report.c b/src/ao_gps_report.c index 75c944f5..e3e27523 100644 --- a/src/ao_gps_report.c +++ b/src/ao_gps_report.c @@ -22,6 +22,7 @@ ao_gps_report(void) { static __xdata struct ao_log_record gps_log; static __xdata struct ao_gps_data gps_data; + uint8_t date_reported = 0; for (;;) { ao_sleep(&ao_gps_data); @@ -49,6 +50,14 @@ ao_gps_report(void) gps_log.u.gps_altitude.altitude = gps_data.altitude; gps_log.u.gps_altitude.unused = 0xffff; ao_log_data(&gps_log); + if (!date_reported && (gps_data.flags & AO_GPS_DATE_VALID)) { + date_reported = 1; + gps_log.type = AO_LOG_GPS_DATE; + gps_log.u.gps_date.year = gps_data.year; + gps_log.u.gps_date.month = gps_data.month; + gps_log.u.gps_date.day = gps_data.day; + ao_log_data(&gps_log); + } } } @@ -71,8 +80,7 @@ ao_gps_tracking_report(void) gps_log.tick = ao_time(); gps_log.type = AO_LOG_GPS_SAT; for (c = 0; c < n; c++) - if ((gps_log.u.gps_sat.svid = gps_tracking_data.sats[c].svid) && - (gps_log.u.gps_sat.state = gps_tracking_data.sats[c].state)) + if ((gps_log.u.gps_sat.svid = gps_tracking_data.sats[c].svid)) { gps_log.u.gps_sat.c_n = gps_tracking_data.sats[c].c_n_1; ao_log_data(&gps_log); diff --git a/src/ao_gps_skytraq.c b/src/ao_gps_skytraq.c index cd5f78b9..b2eef04b 100644 --- a/src/ao_gps_skytraq.c +++ b/src/ao_gps_skytraq.c @@ -19,9 +19,9 @@ #include "ao.h" #endif -#define AO_GPS_LEADER 3 +#define AO_GPS_LEADER 2 -static const char ao_gps_header[] = "GPG"; +static const char ao_gps_header[] = "GP"; __xdata uint8_t ao_gps_mutex; static __xdata char ao_gps_char; @@ -32,6 +32,7 @@ __xdata struct ao_gps_data ao_gps_data; __xdata struct ao_gps_tracking_data ao_gps_tracking_data; static __xdata struct ao_gps_data ao_gps_next; +static __xdata uint8_t ao_gps_date_flags; static __xdata struct ao_gps_tracking_data ao_gps_tracking_next; static const char ao_gps_config[] = { @@ -181,7 +182,7 @@ ao_gps_parse_flag(char no_c, char yes_c) __reentrant void ao_gps(void) __reentrant { - char c; + char a, c; uint8_t i; ao_serial_set_speed(AO_SERIAL_SPEED_9600); @@ -198,7 +199,7 @@ ao_gps(void) __reentrant ao_gps_cksum = 0; ao_gps_error = 0; - /* Skip anything other than GPG */ + /* Skip anything other than GP */ for (i = 0; i < AO_GPS_LEADER; i++) { ao_gps_lexchar(); if (ao_gps_char != ao_gps_header[i]) @@ -209,6 +210,8 @@ ao_gps(void) __reentrant /* pull the record identifier characters off the link */ ao_gps_lexchar(); + a = ao_gps_char; + ao_gps_lexchar(); c = ao_gps_char; ao_gps_lexchar(); i = ao_gps_char; @@ -216,7 +219,7 @@ ao_gps(void) __reentrant if (ao_gps_char != ',') continue; - if (c == (uint8_t) 'G' && i == (uint8_t) 'A') { + if (a == (uint8_t) 'G' && c == (uint8_t) 'G' && i == (uint8_t) 'A') { /* Now read the data into the gps data record * * $GPGGA,025149.000,4528.1723,N,12244.2480,W,1,05,2.0,103.5,M,-19.5,M,,0000*66 @@ -245,7 +248,7 @@ ao_gps(void) __reentrant * *66 checksum */ - ao_gps_next.flags = AO_GPS_RUNNING; + ao_gps_next.flags = AO_GPS_RUNNING | ao_gps_date_flags; ao_gps_next.hour = ao_gps_decimal(2); ao_gps_next.minute = ao_gps_decimal(2); ao_gps_next.second = ao_gps_decimal(2); @@ -290,7 +293,7 @@ ao_gps(void) __reentrant ao_mutex_put(&ao_gps_mutex); ao_wakeup(&ao_gps_data); } - } else if (c == (uint8_t) 'S' && i == (uint8_t) 'V') { + } else if (a == (uint8_t) 'G' && c == (uint8_t) 'S' && i == (uint8_t) 'V') { uint8_t done; /* Now read the data into the GPS tracking data record * @@ -345,6 +348,56 @@ ao_gps(void) __reentrant ao_mutex_put(&ao_gps_mutex); ao_wakeup(&ao_gps_tracking_data); } + } else if (a == (uint8_t) 'R' && c == (uint8_t) 'M' && i == (uint8_t) 'C') { + /* Parse the RMC record to read out the current date */ + + /* $GPRMC,111636.932,A,2447.0949,N,12100.5223,E,000.0,000.0,030407,,,A*61 + * + * Recommended Minimum Specific GNSS Data + * + * 111636.932 UTC time 11:16:36.932 + * A Data Valid (V = receiver warning) + * 2447.0949 Latitude + * N North/south indicator + * 12100.5223 Longitude + * E East/west indicator + * 000.0 Speed over ground + * 000.0 Course over ground + * 030407 UTC date (ddmmyy format) + * A Mode indicator: + * N = data not valid + * A = autonomous mode + * D = differential mode + * E = estimated (dead reckoning) mode + * M = manual input mode + * S = simulator mode + * 61 checksum + */ + ao_gps_skip_field(); + for (i = 0; i < 8; i++) { + ao_gps_lexchar(); + ao_gps_skip_field(); + } + a = ao_gps_decimal(2); + c = ao_gps_decimal(2); + i = ao_gps_decimal(2); + /* Skip remaining fields */ + while (ao_gps_char != '*' && ao_gps_char != '\n' && ao_gps_char != '\r') { + ao_gps_lexchar(); + ao_gps_skip_field(); + } + if (ao_gps_char == '*') { + uint8_t cksum = ao_gps_cksum ^ '*'; + if (cksum != ao_gps_hex(2)) + ao_gps_error = 1; + } else + ao_gps_error = 1; + if (!ao_gps_error) { + ao_gps_next.year = i; + ao_gps_next.month = c; + ao_gps_next.day = a; + ao_gps_date_flags = AO_GPS_DATE_VALID; + } } } } diff --git a/src/ao_gps_test.c b/src/ao_gps_test.c index 366bca71..3692f0e5 100644 --- a/src/ao_gps_test.c +++ b/src/ao_gps_test.c @@ -27,8 +27,12 @@ #define AO_GPS_VALID (1 << 4) #define AO_GPS_RUNNING (1 << 5) +#define AO_GPS_DATE_VALID (1 << 6) struct ao_gps_data { + uint8_t year; + uint8_t month; + uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; diff --git a/src/ao_gps_test_skytraq.c b/src/ao_gps_test_skytraq.c index 510bc419..ccf96378 100644 --- a/src/ao_gps_test_skytraq.c +++ b/src/ao_gps_test_skytraq.c @@ -27,8 +27,12 @@ #define AO_GPS_VALID (1 << 4) #define AO_GPS_RUNNING (1 << 5) +#define AO_GPS_DATE_VALID (1 << 6) struct ao_gps_data { + uint8_t year; + uint8_t month; + uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; -- 2.30.2