From eaa64690b71e3f43743f52e6d2e1dfce389100e6 Mon Sep 17 00:00:00 2001 From: Richard Meadows Date: Fri, 24 Jul 2015 20:25:57 +0100 Subject: [PATCH] Timeout and retries on gps position and time. Lock and wait for hardware reset after 5 tries --- firmware/inc/cron.h | 1 + firmware/src/cron.c | 28 +++++++++++++++++++++++++--- firmware/src/data.c | 34 +++++++++++++++++++++++++++------- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/firmware/inc/cron.h b/firmware/inc/cron.h index 810fe8f..709232c 100644 --- a/firmware/inc/cron.h +++ b/firmware/inc/cron.h @@ -32,6 +32,7 @@ typedef struct tracker_time { uint8_t valid; } tracker_time; +uint32_t cron_current_job_ticks(void); void do_cron(void); void cron_tick(void); diff --git a/firmware/src/cron.c b/firmware/src/cron.c index 6920cbe..2229ddb 100644 --- a/firmware/src/cron.c +++ b/firmware/src/cron.c @@ -54,6 +54,11 @@ void contestia_telemetry(struct tracker_datapoint* dp); void aprs_telemetry(struct tracker_datapoint* dp); void pips_telemetry(void); +/** + * For GPS time timeout + */ +uint32_t ticks_delta_start; + /** * Number of days in month. This won't be used much but I guess I have * to implement it. Sigh @@ -85,20 +90,37 @@ uint8_t days_in_month(struct tracker_time* t) } } +/** + * Returns the number of ticks the current cron job has been running for + * + * ticks = seconds. Can be used for timeouts etc. + */ +uint32_t cron_current_job_ticks(void) +{ + return ticks; +} + /** * Reads current time from the GPS */ void read_gps_time(void) { + /* Record current ticks */ + ticks_delta_start = cron_current_job_ticks(); + /* GPS Time */ gps_update_time(); - /* Sleep Wait */ - while (gps_update_time_pending()) { + /* Sleep Wait. Timeout after 3 ticks */ + while (gps_update_time_pending() && + (cron_current_job_ticks() - ticks_delta_start) <= 3) { + idle(IDLE_WAIT_FOR_GPS); } - if (gps_get_error_state() == GPS_NOERROR) { + /* If no error and no timeout */ + if ((gps_get_error_state() == GPS_NOERROR) && + (cron_current_job_ticks() - ticks_delta_start) <= 3) { /* Time */ struct ubx_nav_timeutc gt = gps_get_nav_timeutc(); diff --git a/firmware/src/data.c b/firmware/src/data.c index f448f5e..5d3ee67 100644 --- a/firmware/src/data.c +++ b/firmware/src/data.c @@ -34,6 +34,12 @@ #include "telemetry.h" #include "watchdog.h" +/** + * GPS timeout and retries + */ +#define GPS_POSITION_RETRIES 5 +uint32_t ticks_delta_start; + struct tracker_datapoint datapoint = {.time={0}}; void xosc_measure_callback(uint32_t result) @@ -58,6 +64,8 @@ void collect_data_async(void) */ struct tracker_datapoint* collect_data(void) { + uint8_t gps_retries = 0; + /** * ---- Analogue ---- */ @@ -69,15 +77,27 @@ struct tracker_datapoint* collect_data(void) /** * ---- GPS ---- */ - gps_update_position(); + do { + /* Record current ticks */ + ticks_delta_start = cron_current_job_ticks(); - /* Wait for the gps update */ - while (gps_update_position_pending()) { - idle(IDLE_WAIT_FOR_GPS); - } + gps_update_position(); - /* At this point the gps could be in an error state */ - /* We still use the old values however. */ + /* Wait for the gps update. Timeout after 3 ticks */ + while (gps_update_position_pending() && + (cron_current_job_ticks() - ticks_delta_start) <= 3) { + + idle(IDLE_WAIT_FOR_GPS); + } + + /* In the case of a error or timeout keep retrying up to 5 + * times */ + } while (((gps_get_error_state() == GPS_NOERROR) || + (cron_current_job_ticks() - ticks_delta_start) > 3) + && gps_retries++ < GPS_POSITION_RETRIES); + + /* Halt and wait for hw watchdog */ + if (gps_retries >= GPS_POSITION_RETRIES) { while (1); } /* GPS Status */ struct ubx_nav_sol sol = gps_get_nav_sol();