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,
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;
} 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]);
} 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;
struct cc_gps_time {
+ int year;
+ int month;
+ int day;
int hour;
int minute;
int second;
#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)
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;
#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;
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,
{
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);
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);
+ }
}
}
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);
#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;
__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[] = {
void
ao_gps(void) __reentrant
{
- char c;
+ char a, c;
uint8_t i;
ao_serial_set_speed(AO_SERIAL_SPEED_9600);
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])
/* 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;
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
* *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);
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
*
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;
+ }
}
}
}
#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;
#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;