From e861da229f33bcc2ed82b001befb0ebf8b39ac2e Mon Sep 17 00:00:00 2001 From: Richard Meadows Date: Fri, 1 Jul 2016 11:00:09 +0100 Subject: [PATCH] [bugfix] fix days_in_month, add epoch calculation for se880 GPS Fixes bug with backlog write location, which lead to more recent data being overwritten --- firmware/inc/cron.h | 1 + firmware/inc/data.h | 1 + firmware/src/cron.c | 6 ++-- firmware/src/data.c | 31 +++++++++++++++++++ firmware/test/tc/epoch_from_time.h | 45 +++++++++++++++++++++++++++ firmware/test/tc/epoch_from_time.py | 48 +++++++++++++++++++++++++++++ firmware/test/tmain.c | 1 + 7 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 firmware/test/tc/epoch_from_time.h create mode 100644 firmware/test/tc/epoch_from_time.py diff --git a/firmware/inc/cron.h b/firmware/inc/cron.h index 709232c..625b5ab 100644 --- a/firmware/inc/cron.h +++ b/firmware/inc/cron.h @@ -32,6 +32,7 @@ typedef struct tracker_time { uint8_t valid; } tracker_time; +uint8_t days_in_month(struct tracker_time* t); uint32_t cron_current_job_ticks(void); void do_cron(void); void cron_tick(void); diff --git a/firmware/inc/data.h b/firmware/inc/data.h index babf1c9..48cde6a 100644 --- a/firmware/inc/data.h +++ b/firmware/inc/data.h @@ -56,6 +56,7 @@ typedef struct tracker_datapoint { } tracker_datapoint; +uint32_t get_epoch_from_time(struct tracker_time *t); void collect_data_async(void); struct tracker_datapoint* collect_data(void); diff --git a/firmware/src/cron.c b/firmware/src/cron.c index ff3d631..47c3e07 100644 --- a/firmware/src/cron.c +++ b/firmware/src/cron.c @@ -70,9 +70,9 @@ uint8_t days_in_month(struct tracker_time* t) switch (t->month) { case 1: return 31; /* Janua */ case 2: - return (t->year % 4) ? - ((t->year % 100) ? - ((t->year % 400) ? 29 /* div 400, leap */ + return (t->year % 4 == 0) ? + ((t->year % 100 == 0) ? + ((t->year % 400 == 0) ? 29 /* div 400, leap */ : 28) /* div 100, not 400, common */ : 29) /* div 4, not 100, leap */ : 28; /* Not div 4, common */ diff --git a/firmware/src/data.c b/firmware/src/data.c index 35e71be..1b0fa70 100644 --- a/firmware/src/data.c +++ b/firmware/src/data.c @@ -26,6 +26,7 @@ #include "samd20.h" #include "data.h" +#include "cron.h" #include "xosc.h" #include "hw_config.h" #include "analogue.h" @@ -43,6 +44,34 @@ void xosc_measure_callback(uint32_t result) datapoint.xosc_error = result - XOSC_FREQUENCY; } +/** + * Gets epoch from year/month/day/hour/minute/seconds time structure. + */ +uint32_t get_epoch_from_time(struct tracker_time *t) +{ + uint32_t days = 0; + int i; + + /* collect years */ + for (i = 1970; i < t->year; i++) { + days += (i % 4 == 0) ? + ((i % 100 == 0) ? + ((i % 400 == 0) ? 366 /* div 400, leap */ + : 365) /* div 100, not 400, common */ + : 366) /* div 4, not 100, leap */ + : 365; /* Not div 4, common */ + } + /* collect months */ + uint8_t t_month = t->month; + for (i = 1; i < t_month; i++) { + t->month = i; + days += days_in_month(t); + } + /* collect days */ + days += t->day-1; + + return (((((days*24)+t->hour)*60)+t->minute)*60)+t->second; +} /** * Collect data asynchronously. Should be run a few seconds before the collect_data routine @@ -87,6 +116,8 @@ struct tracker_datapoint* collect_data(void) datapoint.time.minute = data.minute; datapoint.time.second = data.second; /* seconds */ + /* calculate epoch */ + datapoint.time.epoch = get_epoch_from_time(&datapoint.time); #endif /* GPS_TYPE_OSP */ diff --git a/firmware/test/tc/epoch_from_time.h b/firmware/test/tc/epoch_from_time.h new file mode 100644 index 0000000..4aa67e9 --- /dev/null +++ b/firmware/test/tc/epoch_from_time.h @@ -0,0 +1,45 @@ +#ifndef __verification__ +#define __verification__ +#endif + +/****************************//* epoch_from_time_tc *//****************************/ +/** + * Write a description of your test case here + */ +#include "data.h" + +/* Parameters in */ +struct epoch_from_time_tc_params { + + /* Input paramters to your test case go here */ + int dummy; + +} epoch_from_time_tc_params; +/* Results out */ +struct epoch_from_time_tc_results { + + /* Result values should be populated here */ + uint32_t epoch; + +} epoch_from_time_tc_results; +/* Function */ +__verification__ void epoch_from_time_tc(void) { + + /** + * The main body of the test case goes here. + * + * Use the input parameters to run the test case. Populate the + * results structure at the end + */ + + struct tracker_time t; + t.year = 2016; + t.month = 6; + t.day = 30; + t.hour = 18; + t.minute = 48; + t.second = 0; + + /* Get epoch */ + epoch_from_time_tc_results.epoch = get_epoch_from_time(&t); +} diff --git a/firmware/test/tc/epoch_from_time.py b/firmware/test/tc/epoch_from_time.py new file mode 100644 index 0000000..24e7943 --- /dev/null +++ b/firmware/test/tc/epoch_from_time.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +# ------------------------------------------------------------------------------ +# Imports +# ------------------------------------------------------------------------------ + +import sys +sys.path.append("./test") +import main + +from random import randint + +# ------------------------------------------------------------------------------ +# Test Script +# ------------------------------------------------------------------------------ + +class epoch_from_time_tc: + def __init__(self): + self.name = self.__class__.__name__ + self.iterations = 20 + + + def get_test(self): + """Returns some suitable test parameters""" + params = main.struct_epoch_from_time_tc_params() + + """ + Assign input parameters here + """ + + return params + + def is_correct(self, params, result, print_info): + """Returns if a result is correct for the given parameters""" + + """ + Compare result and params here, decide sth. + Can use print_info + """ + + epoch = int(result['epoch']) + print_info("calculated epoch is {}".format(epoch)) + + if epoch is 1467312480: + return True + else: + print_info("correct epoch is {}".format(1467312480)) + return False diff --git a/firmware/test/tmain.c b/firmware/test/tmain.c index f4cd44a..7d765a2 100644 --- a/firmware/test/tmain.c +++ b/firmware/test/tmain.c @@ -54,6 +54,7 @@ #include "pressure_temperature.h" #include "thermistor_equation.h" #include "gps_poll.h" +#include "epoch_from_time.h" /* [new_tc] */