From ce42f417bea81daef1fcaa1065c2ed4a01291701 Mon Sep 17 00:00:00 2001 From: Bertrand Lemasle Date: Tue, 23 Jan 2018 23:29:45 +0100 Subject: [PATCH] Fixed build by importing part of TimeLib in the project. The trick seems to add optimization directive to work around https://github.com/arduino/Arduino/issues/3972 --- GpsTracker/Gps.cpp | 11 ++-- GpsTracker/Gps.h | 9 +-- GpsTracker/GpsTracker.h | 4 -- GpsTracker/GpsTracker.ino | 4 +- GpsTracker/Hardware.cpp | 49 +++++++++++++- GpsTracker/Hardware.h | 8 +++ GpsTracker/Network.cpp | 6 +- GpsTracker/Network.h | 7 +- GpsTracker/Pins.h | 5 +- GpsTracker/Rtc.cpp | 12 ++-- GpsTracker/Rtc.h | 9 ++- GpsTracker/Time2.cpp | 130 ++++++++++++++++++++++++++++++++++++++ GpsTracker/Time2.h | 27 ++++++++ 13 files changed, 245 insertions(+), 36 deletions(-) create mode 100644 GpsTracker/Time2.cpp create mode 100644 GpsTracker/Time2.h diff --git a/GpsTracker/Gps.cpp b/GpsTracker/Gps.cpp index f6983ec..aab7808 100644 --- a/GpsTracker/Gps.cpp +++ b/GpsTracker/Gps.cpp @@ -1,5 +1,6 @@ #include "Gps.h" #include "Debug.h" +#include "Hardware.h" #define LOGGER_NAME "Gps" @@ -8,13 +9,9 @@ namespace gps { char lastPosition[GPS_POSITION_SIZE]; SIM808_GPS_STATUS lastStatus; - void powerOn() { + /*inline */void powerOn() { hardware::sim808::gpsPowerOn(); } + /*inline */void powerOff() { hardware::sim808::gpsPowerOff(); } - } - - void powerOff() { - - } SIM808_GPS_STATUS acquireCurrentPosition() { SIM808_GPS_STATUS currentStatus = SIM808_GPS_STATUS::OFF; @@ -27,7 +24,7 @@ namespace gps { return currentStatus; } - time_t getTime() { + timestamp_t getTime() { } } \ No newline at end of file diff --git a/GpsTracker/Gps.h b/GpsTracker/Gps.h index 282a912..6dd628c 100644 --- a/GpsTracker/Gps.h +++ b/GpsTracker/Gps.h @@ -1,9 +1,10 @@ #pragma once -#include -#include #include +#include "Hardware.h" +#include "Time2.h" + #define GPS_POSITION_SIZE 128 namespace gps { @@ -13,8 +14,8 @@ namespace gps { void powerOn(); void powerOff(); - + SIM808_GPS_STATUS acquireCurrentPosition(); - time_t getTime(); + timestamp_t getTime(); } \ No newline at end of file diff --git a/GpsTracker/GpsTracker.h b/GpsTracker/GpsTracker.h index 998af9d..3723942 100644 --- a/GpsTracker/GpsTracker.h +++ b/GpsTracker/GpsTracker.h @@ -3,15 +3,11 @@ #include #include #include -#include -#include #include "Debug.h" #include "Core.h" -#include "posmgr.h" #include "Gps.h" -#include "posmgr.h" #include "MainUnit.h" #include "Network.h" #include "Rtc.h" diff --git a/GpsTracker/GpsTracker.ino b/GpsTracker/GpsTracker.ino index 0ced4ef..08953a6 100644 --- a/GpsTracker/GpsTracker.ino +++ b/GpsTracker/GpsTracker.ino @@ -21,7 +21,9 @@ void loop() { gps::powerOff(); if (gpsStatus > SIM808_GPS_STATUS::NO_FIX) { - time_t time = gps::getTime(); + timestamp_t time = gps::getTime(); + tmElements_t t; + breakTime(time, t); rtc::powerOn(); rtc::setTime(time); rtc::powerOff(); diff --git a/GpsTracker/Hardware.cpp b/GpsTracker/Hardware.cpp index 257cf7b..582c2d2 100644 --- a/GpsTracker/Hardware.cpp +++ b/GpsTracker/Hardware.cpp @@ -1,13 +1,15 @@ #include "Hardware.h" #include "Pins.h" +#include #include +#include namespace hardware { namespace sim808 { SoftwareSerial simSerial = SoftwareSerial(SIM_TX, SIM_RX); - SIM808 sim = SIM808(0, SIM_PWR, SIM_STATUS); + SIM808 device = SIM808(SIM_RST, SIM_PWR, SIM_STATUS); //idea : int powered //gps::powerOn() => +1 //network::powerOn() => +1 @@ -18,11 +20,54 @@ namespace hardware { //gps/network::powerOff() => powered == 1 => sim808::powerOff() //idea : gps power on = +1, network power on = +1 => powerOff forces power off of all, powerOff one will lead to actual powerOff if void powerOn() { + bool poweredOn = device.powerOnOff(true); + if (!poweredOn) return; + device.init(); } void powerOff() { + bool poweredOff = device.powerOnOff(false); + } + + void init() { + device.powerOnOff(true); + simSerial.begin(4800); + + device.begin(simSerial); + device.init(); + } + + void powerOffIfUnused() { + bool gpsPowered = false; + bool gprsPowered = false; + if ((device.getGpsPowerState(&gpsPowered) && !gpsPowered) && + (device.getGprsPowerState(&gprsPowered) && !gprsPowered)) { + powerOff(); + } + } + + void gpsPowerOn() { + powerOn(); + device.enableGps(); + } + + void gpsPowerOff() { + device.disableGps(); + powerOffIfUnused(); + } + + void networkPowerOn() { + powerOn(); + device.setPhoneFunctionality(SIM808_PHONE_FUNCTIONALITY::FULL); + device.enableGprs("Free"); //TODO : configure + } + + void networkPowerOff() { + device.setPhoneFunctionality(SIM808_PHONE_FUNCTIONALITY::MINIMUM); + device.disableGprs(); + powerOffIfUnused(); } } @@ -35,4 +80,4 @@ namespace hardware { void powerOn(); void powerOff(); } -} \ No newline at end of file +} diff --git a/GpsTracker/Hardware.h b/GpsTracker/Hardware.h index b8ef9da..3a1f320 100644 --- a/GpsTracker/Hardware.h +++ b/GpsTracker/Hardware.h @@ -9,6 +9,14 @@ namespace hardware { void powerOn(); void powerOff(); + + void init(); + + void gpsPowerOn(); + void gpsPowerOff(); + + void networkPowerOn(); + void networkPowerOff(); } namespace rtc { diff --git a/GpsTracker/Network.cpp b/GpsTracker/Network.cpp index e2dc62d..6f92d2e 100644 --- a/GpsTracker/Network.cpp +++ b/GpsTracker/Network.cpp @@ -1,9 +1,9 @@ #include "Network.h" - +#include "Hardware.h" #define LOGGER_NAME "Network" namespace network { - void powerOn() {} - void powerOff() {} + /*inline */void powerOn() { hardware::sim808::networkPowerOn(); } + /*inline */void powerOff() { hardware::sim808::networkPowerOff(); } } \ No newline at end of file diff --git a/GpsTracker/Network.h b/GpsTracker/Network.h index 30659f2..c7324af 100644 --- a/GpsTracker/Network.h +++ b/GpsTracker/Network.h @@ -1,6 +1,9 @@ #pragma once +#include "Hardware.h" + namespace network { - void powerOn(); - void powerOff(); + + /*inline */void powerOn(); + /*inline */void powerOff(); } \ No newline at end of file diff --git a/GpsTracker/Pins.h b/GpsTracker/Pins.h index a88edf0..40334eb 100644 --- a/GpsTracker/Pins.h +++ b/GpsTracker/Pins.h @@ -1,7 +1,8 @@ #pragma once -#define SIM_RX 5 -#define SIM_TX 6 +#define SIM_RST 5 +#define SIM_RX 6 +#define SIM_TX 7 #define SIM_PWR 9 #define SIM_STATUS 8 diff --git a/GpsTracker/Rtc.cpp b/GpsTracker/Rtc.cpp index 5c850b2..a9cca77 100644 --- a/GpsTracker/Rtc.cpp +++ b/GpsTracker/Rtc.cpp @@ -10,7 +10,7 @@ namespace rtc { namespace details { - time_t readTimeFromRegisters() { + timestamp_t readTimeFromRegisters() { tmElements_t tmElements = { RTC.s, RTC.m, @@ -24,7 +24,7 @@ namespace rtc { return makeTime(tmElements); } - void writeTimeToRegisters(time_t &time) { + void writeTimeToRegisters(timestamp_t &time) { tmElements_t tmElements; breakTime(time, tmElements); @@ -64,23 +64,23 @@ namespace rtc { RTC.control(DS3231_INT_ENABLE, DS3231_OFF); //INTCN OFF } - time_t getTime() { + timestamp_t getTime() { RTC.readTime(); return details::readTimeFromRegisters(); } - void setTime(time_t &time) { + void setTime(timestamp_t &time) { details::writeTimeToRegisters(time); RTC.writeTime(); } void setAlarm(uint16_t seconds) { - time_t t = getTime(); + timestamp_t t = getTime(); t = t + seconds; setAlarm(t); } - void setAlarm(time_t &time) { + void setAlarm(timestamp_t &time) { details::writeTimeToRegisters(time); RTC.writeAlarm1(DS3231_ALM_S); diff --git a/GpsTracker/Rtc.h b/GpsTracker/Rtc.h index e5b4c28..a3ced7d 100644 --- a/GpsTracker/Rtc.h +++ b/GpsTracker/Rtc.h @@ -1,7 +1,6 @@ #pragma once -#include -#include +#include "Time2.h" namespace rtc { void powerOn(); @@ -9,9 +8,9 @@ namespace rtc { void setup(); - time_t getTime(); - void setTime(time_t &time); + timestamp_t getTime(); + void setTime(timestamp_t &time); void setAlarm(uint16_t seconds); - void setAlarm(time_t &time); + void setAlarm(timestamp_t &time); } \ No newline at end of file diff --git a/GpsTracker/Time2.cpp b/GpsTracker/Time2.cpp new file mode 100644 index 0000000..85d65d7 --- /dev/null +++ b/GpsTracker/Time2.cpp @@ -0,0 +1,130 @@ +#include "Time2.h" + +/*==============================================================================*/ +/* Useful Constants */ +#define SECS_PER_MIN (60UL) +#define SECS_PER_HOUR (3600UL) +#define SECS_PER_DAY (SECS_PER_HOUR * 24UL) +#define DAYS_PER_WEEK (7UL) +#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK) +#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL) +#define SECS_YR_2000 (946684800UL) // the time at the start of y2k + +/* Useful Macros for getting elapsed time */ +#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN) +#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) +#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR) +#define dayOfWeek(_time_) ((( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday +#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970 +#define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight +// The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971 +// Always set the correct time before settting alarms +#define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day +#define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day +#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY) ) // note that week starts on day 1 +#define previousSunday(_time_) (_time_ - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time +#define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time + + +/* Useful Macros for converting elapsed time to a timestamp_t */ +#define minutesTotimestamp_t ((M)) ( (M) * SECS_PER_MIN) +#define hoursTotimestamp_t ((H)) ( (H) * SECS_PER_HOUR) +#define daysTotimestamp_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011 +#define weeksTotimestamp_t ((W)) ( (W) * SECS_PER_WEEK) + +// leap year calulator expects year argument as years offset from 1970 +#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) + + static const uint8_t monthDays[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; // API starts months from 1, this array starts from 0 + + __attribute__((__optimize__("O2"))) + void breakTime(timestamp_t timeInput, tmElements_t &tm) { + // break the given timestamp_t into time components + // this is a more compact version of the C library localtime function + // note that year is offset from 1970 !!! + + uint8_t year; + uint8_t month, monthLength; + uint32_t time; + unsigned long days; + + time = (uint32_t)timeInput; + tm.Second = time % 60; + time /= 60; // now it is minutes + tm.Minute = time % 60; + time /= 60; // now it is hours + tm.Hour = time % 24; + time /= 24; // now it is days + tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1 + + year = 0; + days = 0; + while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { + year++; + } + tm.Year = year; // year is offset from 1970 + + days -= LEAP_YEAR(year) ? 366 : 365; + time -= days; // now it is days in this year, starting at 0 + + days = 0; + month = 0; + monthLength = 0; + for (month = 0; month<12; month++) { + if (month == 1) { // february + if (LEAP_YEAR(year)) { + monthLength = 29; + } + else { + monthLength = 28; + } + } + else { + monthLength = monthDays[month]; + } + + if (time >= monthLength) { + time -= monthLength; + } + else { + break; + } + } + tm.Month = month + 1; // jan is month 1 + tm.Day = time + 1; // day of month + } + + __attribute__((__optimize__("O2"))) + timestamp_t makeTime(tmElements_t &tm) { + // assemble time elements into timestamp_t + // note year argument is offset from 1970 (see macros in time.h to convert to other formats) + // previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 + + int i; + uint32_t seconds; + + // seconds from 1970 till 1 jan 00:00:00 of the given year + seconds = tm.Year*(SECS_PER_DAY * 365); + for (i = 0; i < tm.Year; i++) { + if (LEAP_YEAR(i)) { + seconds += SECS_PER_DAY; // add extra days for leap years + } + } + + // add days for this year, months start from 1 + for (i = 1; i < tm.Month; i++) { + if ((i == 2) && LEAP_YEAR(tm.Year)) { + seconds += SECS_PER_DAY * 29; + } + else { + seconds += SECS_PER_DAY * monthDays[i - 1]; //monthDay array starts from 0 + } + } + seconds += (tm.Day - 1) * SECS_PER_DAY; + seconds += tm.Hour * SECS_PER_HOUR; + seconds += tm.Minute * SECS_PER_MIN; + seconds += tm.Second; + return (timestamp_t)seconds; + } + /*=====================================================*/ + /* Low level system time functions */ diff --git a/GpsTracker/Time2.h b/GpsTracker/Time2.h new file mode 100644 index 0000000..d62535e --- /dev/null +++ b/GpsTracker/Time2.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +//convenience macros to convert to and from tm years +#define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year +#define CalendarYrToTm(Y) ((Y) - 1970) +#define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000 +#define y2kYearToTm(Y) ((Y) + 30) + +/*============================================================================*/ + + typedef unsigned long timestamp_t; + + typedef struct { + uint8_t Second; + uint8_t Minute; + uint8_t Hour; + uint8_t Wday; // day of week, sunday is day 1 + uint8_t Day; + uint8_t Month; + uint8_t Year; // offset from 1970; + } tmElements_t, TimeElements, *tmElementsPtr_t; + + /* low level functions to convert to and from system time */ + void breakTime(timestamp_t time, tmElements_t &tm); // break timestamp_t into elements + timestamp_t makeTime(tmElements_t &tm); // convert time elements into timestamp_t