From ffc030d0116e6ca115270c92037e9ac91f860caf Mon Sep 17 00:00:00 2001 From: Bertrand Lemasle Date: Wed, 8 Aug 2018 18:10:58 +1200 Subject: [PATCH] Moved defines and include around --- src/Alerts.cpp | 100 ++--- src/Config.cpp | 170 ++++----- src/Core.cpp | 319 ++++++++-------- src/Core.h | 2 - src/Debug.cpp | 589 +++++++++++++++--------------- src/Debug.h | 114 +++--- src/Gps.cpp | 234 ++++++------ src/GpsTracker.h | 10 - src/GpsTracker.ino | 192 +++++----- src/Hardware.cpp | 11 +- src/Hardware.h | 60 +-- src/MainUnit.cpp | 12 +- src/MainUnit.h | 15 +- src/Network.cpp | 150 ++++---- src/NetworkPositionsBackup.cpp | 224 ++++++------ src/Positions.cpp | 389 ++++++++++---------- src/Rtc.cpp | 6 +- src/SdCard.cpp | 2 +- src/SdPositionsBackup.cpp | 236 ++++++------ src/SdPositionsConfig.cpp | 140 +++---- src/config/{Pins.h => Hardware.h} | 8 + src/config/System.h | 8 +- 22 files changed, 1494 insertions(+), 1497 deletions(-) delete mode 100644 src/GpsTracker.h rename src/config/{Pins.h => Hardware.h} (54%) diff --git a/src/Alerts.cpp b/src/Alerts.cpp index d9c8e9a..65a4049 100644 --- a/src/Alerts.cpp +++ b/src/Alerts.cpp @@ -1,50 +1,50 @@ -#pragma once - -#include "Debug.h" -#include "Alerts.h" -#include "Config.h" -#include "Rtc.h" - -#define LOGGER_NAME "Alerts" - -namespace alerts { - - uint8_t getTriggered(PositionEntryMetadata &metadata) { - config_t* config = &config::main::value; - uint8_t active = 0; - - if (metadata.batteryLevel <= config->alertBatteryLevel1) bitSet(active, ALERT_BATTERY_LEVEL_1); - if (metadata.batteryLevel <= config->alertBatteryLevel2) bitSet(active, ALERT_BATTERY_LEVEL_2); - if (metadata.temperature == ALERT_SUSPICIOUS_RTC_TEMPERATURE) bitSet(active, ALERT_RTC_TEMPERATURE_FAILURE); - if (!rtc::isAccurate()) bitSet(active, ALERT_RTC_CLOCK_FAILURE); - - return config->activeAlerts ^ active; - } - - void add(uint8_t mask) { - config_t* config = &config::main::value; - uint8_t active = config->activeAlerts; - - active |= mask; - if (config->activeAlerts == active) return; //save a write to eeprom if there is no change - - config->activeAlerts = active; - config::main::save(); - } - - void clear(PositionEntryMetadata &metadata) { - config_t* config = &config::main::value; - uint8_t clearMask = 0; - uint8_t active = config->activeAlerts; - - if (metadata.batteryLevel >= config->alertBatteryLevelClear) clearMask |= _BV(ALERT_BATTERY_LEVEL_1) | _BV(ALERT_BATTERY_LEVEL_2); - if (metadata.temperature != ALERT_SUSPICIOUS_RTC_TEMPERATURE) bitSet(clearMask, ALERT_RTC_TEMPERATURE_FAILURE); - if (rtc::isAccurate()) bitSet(clearMask, ALERT_RTC_CLOCK_FAILURE); - - active &= ~clearMask; - if (config->activeAlerts == active) return; //save a write to eeprom if there is no change - - config->activeAlerts = active; - config::main::save(); - } -} +#pragma once + +#include "Alerts.h" +#include "Config.h" +#include "Rtc.h" +#include "Logging.h" + +#define LOGGER_NAME "Alerts" + +namespace alerts { + + uint8_t getTriggered(PositionEntryMetadata &metadata) { + config_t* config = &config::main::value; + uint8_t active = 0; + + if (metadata.batteryLevel <= config->alertBatteryLevel1) bitSet(active, ALERT_BATTERY_LEVEL_1); + if (metadata.batteryLevel <= config->alertBatteryLevel2) bitSet(active, ALERT_BATTERY_LEVEL_2); + if (metadata.temperature == ALERT_SUSPICIOUS_RTC_TEMPERATURE) bitSet(active, ALERT_RTC_TEMPERATURE_FAILURE); + if (!rtc::isAccurate()) bitSet(active, ALERT_RTC_CLOCK_FAILURE); + + return config->activeAlerts ^ active; + } + + void add(uint8_t mask) { + config_t* config = &config::main::value; + uint8_t active = config->activeAlerts; + + active |= mask; + if (config->activeAlerts == active) return; //save a write to eeprom if there is no change + + config->activeAlerts = active; + config::main::save(); + } + + void clear(PositionEntryMetadata &metadata) { + config_t* config = &config::main::value; + uint8_t clearMask = 0; + uint8_t active = config->activeAlerts; + + if (metadata.batteryLevel >= config->alertBatteryLevelClear) clearMask |= _BV(ALERT_BATTERY_LEVEL_1) | _BV(ALERT_BATTERY_LEVEL_2); + if (metadata.temperature != ALERT_SUSPICIOUS_RTC_TEMPERATURE) bitSet(clearMask, ALERT_RTC_TEMPERATURE_FAILURE); + if (rtc::isAccurate()) bitSet(clearMask, ALERT_RTC_CLOCK_FAILURE); + + active &= ~clearMask; + if (config->activeAlerts == active) return; //save a write to eeprom if there is no change + + config->activeAlerts = active; + config::main::save(); + } +} diff --git a/src/Config.cpp b/src/Config.cpp index 2328035..745339e 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -1,86 +1,86 @@ -#include "Config.h" -#include "Debug.h" -#include "Hardware.h" - -#define LOGGER_NAME "Config" - -namespace config { - namespace main { - - config_t value; - - namespace details { - - void read() { - VERBOSE("read"); - - hardware::i2c::powerOn(); - hardware::i2c::eeprom.readBlock(CONFIG_ADDR, value); - if (CONFIG_SEED != value.seed) reset(); //todo : reset network if seed for network is not right - hardware::i2c::powerOff(); - - NOTICE_FORMAT("read", "%d, %s, %d, %d, %d, %d, %d, %B, %s", value.seed, value.version, value.firstEntry, value.lastEntry, value.alertBatteryLevel1, value.alertBatteryLevel2, value.alertBatteryLevelClear, value.activeAlerts, value.contactPhone); -#if BACKUP_ENABLE_NETWORK - NOTICE_FORMAT("read", "%d, %d, %s, %s", value.network.saveThreshold, value.network.lastSavedEntry, value.network.apn, value.network.url); - //networkConfig_t c = { - // POSITIONS_CONFIG_NET_DEFAULT_SAVE_THRESHOLD, - // 0xFFFF, - // POSITIONS_CONFIG_NET_DEFAULT_APN, - // POSITIONS_CONFIG_NET_DEFAULT_URL, - //}; - //value.network = c; -#endif - /*strcpy_P(value.version, PSTR(VERSION)); - value.alertBatteryLevel1 = CONFIG_DEFAULT_BATTERY_ALERT_LEVEL1; - value.alertBatteryLevel2 = CONFIG_DEFAULT_BATTERY_ALERT_LEVEL2; - value.alertBatteryLevelClear = CONFIG_DEFAULT_BATTERY_ALERT_CLEAR; - value.activeAlerts = CONFIG_DEFAULT_ACTIVE_ALERTS; - strcpy_P(config.contactPhone, PSTR(CONFIG_DEFAULT_CONTACT_PHONE));*/ - } - - void write() { - NOTICE_FORMAT("write", "%d, %s, %d, %d, %d, %d, %d, %B, %s", value.seed, value.version, value.firstEntry, value.lastEntry, value.alertBatteryLevel1, value.alertBatteryLevel2, value.alertBatteryLevelClear, value.activeAlerts, value.contactPhone); -#if BACKUP_ENABLE_NETWORK - NOTICE_FORMAT("write", "%d, %d, %s, %s", value.network.saveThreshold, value.network.lastSavedEntry, value.network.apn, value.network.url); -#endif - hardware::i2c::powerOn(); - int written = hardware::i2c::eeprom.writeBlock(CONFIG_ADDR, value); - hardware::i2c::powerOff(); - } - } - - void setup() { - details::read(); - //details::write(); - } - - void save() { - details::write(); - } - - void reset() { - VERBOSE("reset"); - - config_t config = {}; - config.seed = CONFIG_SEED; - strcpy_P(config.version, PSTR(VERSION)); - config.firstEntry = config.lastEntry = 0xFFFF; - config.alertBatteryLevel1 = CONFIG_DEFAULT_BATTERY_ALERT_LEVEL1; - config.alertBatteryLevel2 = CONFIG_DEFAULT_BATTERY_ALERT_LEVEL2; - config.alertBatteryLevelClear = CONFIG_DEFAULT_BATTERY_ALERT_CLEAR; - config.activeAlerts = CONFIG_DEFAULT_ACTIVE_ALERTS; - strcpy_P(config.contactPhone, PSTR(CONFIG_DEFAULT_CONTACT_PHONE)); - -#if BACKUP_ENABLE_NETWORK - config.network.saveThreshold = POSITIONS_CONFIG_NET_DEFAULT_SAVE_THRESHOLD; - config.network.lastSavedEntry = 0xFFFF; - strcpy_P(config.network.apn, PSTR(POSITIONS_CONFIG_NET_DEFAULT_APN)); - strcpy_P(config.network.url, PSTR(POSITIONS_CONFIG_NET_DEFAULT_URL)); -#endif - - value = config; - save(); - } - - } +#include "Config.h" +#include "Hardware.h" +#include "Logging.h" + +#define LOGGER_NAME "Config" + +namespace config { + namespace main { + + config_t value; + + namespace details { + + void read() { + VERBOSE("read"); + + hardware::i2c::powerOn(); + hardware::i2c::eeprom.readBlock(CONFIG_ADDR, value); + if (CONFIG_SEED != value.seed) reset(); //todo : reset network if seed for network is not right + hardware::i2c::powerOff(); + + NOTICE_FORMAT("read", "%d, %s, %d, %d, %d, %d, %d, %B, %s", value.seed, value.version, value.firstEntry, value.lastEntry, value.alertBatteryLevel1, value.alertBatteryLevel2, value.alertBatteryLevelClear, value.activeAlerts, value.contactPhone); +#if BACKUP_ENABLE_NETWORK + NOTICE_FORMAT("read", "%d, %d, %s, %s", value.network.saveThreshold, value.network.lastSavedEntry, value.network.apn, value.network.url); + //networkConfig_t c = { + // POSITIONS_CONFIG_NET_DEFAULT_SAVE_THRESHOLD, + // 0xFFFF, + // POSITIONS_CONFIG_NET_DEFAULT_APN, + // POSITIONS_CONFIG_NET_DEFAULT_URL, + //}; + //value.network = c; +#endif + /*strcpy_P(value.version, PSTR(VERSION)); + value.alertBatteryLevel1 = CONFIG_DEFAULT_BATTERY_ALERT_LEVEL1; + value.alertBatteryLevel2 = CONFIG_DEFAULT_BATTERY_ALERT_LEVEL2; + value.alertBatteryLevelClear = CONFIG_DEFAULT_BATTERY_ALERT_CLEAR; + value.activeAlerts = CONFIG_DEFAULT_ACTIVE_ALERTS; + strcpy_P(config.contactPhone, PSTR(CONFIG_DEFAULT_CONTACT_PHONE));*/ + } + + void write() { + NOTICE_FORMAT("write", "%d, %s, %d, %d, %d, %d, %d, %B, %s", value.seed, value.version, value.firstEntry, value.lastEntry, value.alertBatteryLevel1, value.alertBatteryLevel2, value.alertBatteryLevelClear, value.activeAlerts, value.contactPhone); +#if BACKUP_ENABLE_NETWORK + NOTICE_FORMAT("write", "%d, %d, %s, %s", value.network.saveThreshold, value.network.lastSavedEntry, value.network.apn, value.network.url); +#endif + hardware::i2c::powerOn(); + int written = hardware::i2c::eeprom.writeBlock(CONFIG_ADDR, value); + hardware::i2c::powerOff(); + } + } + + void setup() { + details::read(); + //details::write(); + } + + void save() { + details::write(); + } + + void reset() { + VERBOSE("reset"); + + config_t config = {}; + config.seed = CONFIG_SEED; + strcpy_P(config.version, PSTR(VERSION)); + config.firstEntry = config.lastEntry = 0xFFFF; + config.alertBatteryLevel1 = CONFIG_DEFAULT_BATTERY_ALERT_LEVEL1; + config.alertBatteryLevel2 = CONFIG_DEFAULT_BATTERY_ALERT_LEVEL2; + config.alertBatteryLevelClear = CONFIG_DEFAULT_BATTERY_ALERT_CLEAR; + config.activeAlerts = CONFIG_DEFAULT_ACTIVE_ALERTS; + strcpy_P(config.contactPhone, PSTR(CONFIG_DEFAULT_CONTACT_PHONE)); + +#if BACKUP_ENABLE_NETWORK + config.network.saveThreshold = POSITIONS_CONFIG_NET_DEFAULT_SAVE_THRESHOLD; + config.network.lastSavedEntry = 0xFFFF; + strcpy_P(config.network.apn, PSTR(POSITIONS_CONFIG_NET_DEFAULT_APN)); + strcpy_P(config.network.url, PSTR(POSITIONS_CONFIG_NET_DEFAULT_URL)); +#endif + + value = config; + save(); + } + + } } \ No newline at end of file diff --git a/src/Core.cpp b/src/Core.cpp index b460052..987e57e 100644 --- a/src/Core.cpp +++ b/src/Core.cpp @@ -1,160 +1,161 @@ -#include "Core.h" -#include "Config.h" -#include "Flash.h" -#include "Alerts.h" - -#define LOGGER_NAME "Core" -#define SMS_BUFFER_SIZE 140 -#define NO_ALERTS_NOTIFIED 0 - -using namespace utils; - -namespace core { - - uint16_t sleepTime = SLEEP_DEFAULT_TIME_SECONDS; - uint8_t stoppedInARow = SLEEP_DEFAULT_STOPPED_THRESHOLD - 1; - TRACKER_MOVING_STATE movingState = TRACKER_MOVING_STATE::MOVING; - - namespace details { - - void appendToSmsBuffer(char * buffer, const char * fmt, ...) { - va_list args; - va_start(args, fmt); - - size_t bufferLeft = SMS_BUFFER_SIZE - strlen(buffer); - char * p = buffer + strlen(buffer); - vsnprintf_P(p, bufferLeft, fmt, args); - - va_end(args); - } - - } - - void main() { - bool acquired = false; - PositionEntryMetadata metadata; - - if(movingState >= TRACKER_MOVING_STATE::STOPPED) positions::prepareBackup(); - acquired = positions::acquire(metadata); - - if (acquired) { - positions::appendLast(metadata); - - movingState = updateSleepTime(); - gps::preserveCurrentCoordinates(); - } - - alerts::clear(metadata); - alerts::add(notifyFailures(metadata)); - - if(movingState >= TRACKER_MOVING_STATE::STOPPED) { - positions::doBackup(movingState == TRACKER_MOVING_STATE::STOPPED); //do not force on STATIC - } - - if (acquired) updateRtcTime(); - mainunit::deepSleep(sleepTime); - } - - uint8_t notifyFailures(PositionEntryMetadata &metadata) { - SIM808RegistrationStatus networkStatus; - char buffer[SMS_BUFFER_SIZE]; - const __FlashStringHelper * backupFailureString = F(" Backup battery failure ?"); - bool notified = false; - - uint8_t triggered = alerts::getTriggered(metadata); - if (!triggered) return NO_ALERTS_NOTIFIED; - - NOTICE_FORMAT("notifyFailures", "triggered : %B", triggered); - - network::powerOn(); - networkStatus = network::waitForRegistered(NETWORK_DEFAULT_TOTAL_TIMEOUT_MS); - - if (network::isAvailable(networkStatus.stat)) { - strncpy_P(buffer, PSTR("Alerts !"), SMS_BUFFER_SIZE); - if (bitRead(triggered, ALERT_BATTERY_LEVEL_1) || bitRead(triggered, ALERT_BATTERY_LEVEL_2)) { - details::appendToSmsBuffer(buffer, PSTR("\n- Battery at %d%%."), metadata.batteryLevel); - } - - if (bitRead(triggered, ALERT_RTC_TEMPERATURE_FAILURE)) { - details::appendToSmsBuffer(buffer, PSTR("\n- Temperature is %dC.%S"), metadata.temperature, backupFailureString); - } - - if (bitRead(triggered, ALERT_RTC_CLOCK_FAILURE)) { - details::appendToSmsBuffer(buffer, PSTR("\n- RTC was stopped.%S"), backupFailureString); - } - -#if ALERTS_ON_SERIAL_IF_AVAILABLE - if(Serial) { - NOTICE_FORMAT("notifyFailure", "%s", buffer); - notified = true; - } - else { -#endif - notified = network::sendSms(buffer); -#if ALERTS_ON_SERIAL_IF_AVAILABLE - } -#endif - if (!notified) NOTICE_MSG("notifyFailure", "SMS not sent !"); - } - - network::powerOff(); - return notified ? triggered : NO_ALERTS_NOTIFIED; //If not notified, the alerts state should not be persisted (so we can retry to notify them) - } - - void updateRtcTime() { - tmElements_t time; - gps::getTime(time); - rtc::setTime(time); - } - - TRACKER_MOVING_STATE updateSleepTime() { - TRACKER_MOVING_STATE state = TRACKER_MOVING_STATE::MOVING; - uint8_t velocity = gps::getVelocity(); - - sleepTime = mapSleepTime(velocity); - - if (velocity < SLEEP_TIMING_MIN_MOVING_VELOCITY) { - float distance = gps::getDistanceFromPrevious(); //did we missed positions because we were sleeping ? - if (distance > GPS_DEFAULT_MISSED_POSITION_GAP_KM) stoppedInARow = 0; - else stoppedInARow = min(stoppedInARow + 1, SLEEP_DEFAULT_STOPPED_THRESHOLD + 1); //avoid overflow on REALLY long stops - - if (stoppedInARow < SLEEP_DEFAULT_STOPPED_THRESHOLD) { - sleepTime = SLEEP_DEFAULT_PAUSING_TIME_SECONDS; - state = TRACKER_MOVING_STATE::PAUSED; - } - else if (stoppedInARow == SLEEP_DEFAULT_STOPPED_THRESHOLD) state = TRACKER_MOVING_STATE::STOPPED; - else state = TRACKER_MOVING_STATE::STATIC; - } - else stoppedInARow = 0; - - NOTICE_FORMAT("updateSleepTime", "%dkmh => %d seconds", velocity, sleepTime); - return state; - } - - uint16_t mapSleepTime(uint8_t velocity) { - uint16_t result; - uint16_t currentTime = 0xFFFF; - - if (rtc::isAccurate()) { - tmElements_t time; - rtc::getTime(time); - - currentTime = SLEEP_TIMING_TIME(time.Hour, time.Minute); - } - - for (uint8_t i = flash::getArraySize(config::defaultSleepTimings); i--;) { - sleepTimings_t timing; - flash::read(&config::defaultSleepTimings[i], timing); - - if (velocity < timing.speed) continue; - if (currentTime != 0xFFFF && (currentTime < timing.timeMin || currentTime > timing.timeMax)) continue; - - result = timing.seconds; - break; - - } - - VERBOSE_FORMAT("mapSleepTime", "%d,%d", velocity, result); - return result; - } +#include "Core.h" +#include "Config.h" +#include "Flash.h" +#include "Alerts.h" +#include "Logging.h" + +#define LOGGER_NAME "Core" +#define SMS_BUFFER_SIZE 140 +#define NO_ALERTS_NOTIFIED 0 + +using namespace utils; + +namespace core { + + uint16_t sleepTime = SLEEP_DEFAULT_TIME_SECONDS; + uint8_t stoppedInARow = SLEEP_DEFAULT_STOPPED_THRESHOLD - 1; + TRACKER_MOVING_STATE movingState = TRACKER_MOVING_STATE::MOVING; + + namespace details { + + void appendToSmsBuffer(char * buffer, const char * fmt, ...) { + va_list args; + va_start(args, fmt); + + size_t bufferLeft = SMS_BUFFER_SIZE - strlen(buffer); + char * p = buffer + strlen(buffer); + vsnprintf_P(p, bufferLeft, fmt, args); + + va_end(args); + } + + } + + void main() { + bool acquired = false; + PositionEntryMetadata metadata; + + if(movingState >= TRACKER_MOVING_STATE::STOPPED) positions::prepareBackup(); + acquired = positions::acquire(metadata); + + if (acquired) { + positions::appendLast(metadata); + + movingState = updateSleepTime(); + gps::preserveCurrentCoordinates(); + } + + alerts::clear(metadata); + alerts::add(notifyFailures(metadata)); + + if(movingState >= TRACKER_MOVING_STATE::STOPPED) { + positions::doBackup(movingState == TRACKER_MOVING_STATE::STOPPED); //do not force on STATIC + } + + if (acquired) updateRtcTime(); + mainunit::deepSleep(sleepTime); + } + + uint8_t notifyFailures(PositionEntryMetadata &metadata) { + SIM808RegistrationStatus networkStatus; + char buffer[SMS_BUFFER_SIZE]; + const __FlashStringHelper * backupFailureString = F(" Backup battery failure ?"); + bool notified = false; + + uint8_t triggered = alerts::getTriggered(metadata); + if (!triggered) return NO_ALERTS_NOTIFIED; + + NOTICE_FORMAT("notifyFailures", "triggered : %B", triggered); + + network::powerOn(); + networkStatus = network::waitForRegistered(NETWORK_DEFAULT_TOTAL_TIMEOUT_MS); + + if (network::isAvailable(networkStatus.stat)) { + strncpy_P(buffer, PSTR("Alerts !"), SMS_BUFFER_SIZE); + if (bitRead(triggered, ALERT_BATTERY_LEVEL_1) || bitRead(triggered, ALERT_BATTERY_LEVEL_2)) { + details::appendToSmsBuffer(buffer, PSTR("\n- Battery at %d%%."), metadata.batteryLevel); + } + + if (bitRead(triggered, ALERT_RTC_TEMPERATURE_FAILURE)) { + details::appendToSmsBuffer(buffer, PSTR("\n- Temperature is %dC.%S"), metadata.temperature, backupFailureString); + } + + if (bitRead(triggered, ALERT_RTC_CLOCK_FAILURE)) { + details::appendToSmsBuffer(buffer, PSTR("\n- RTC was stopped.%S"), backupFailureString); + } + +#if ALERTS_ON_SERIAL_IF_AVAILABLE + if(Serial) { + NOTICE_FORMAT("notifyFailure", "%s", buffer); + notified = true; + } + else { +#endif + notified = network::sendSms(buffer); +#if ALERTS_ON_SERIAL_IF_AVAILABLE + } +#endif + if (!notified) NOTICE_MSG("notifyFailure", "SMS not sent !"); + } + + network::powerOff(); + return notified ? triggered : NO_ALERTS_NOTIFIED; //If not notified, the alerts state should not be persisted (so we can retry to notify them) + } + + void updateRtcTime() { + tmElements_t time; + gps::getTime(time); + rtc::setTime(time); + } + + TRACKER_MOVING_STATE updateSleepTime() { + TRACKER_MOVING_STATE state = TRACKER_MOVING_STATE::MOVING; + uint8_t velocity = gps::getVelocity(); + + sleepTime = mapSleepTime(velocity); + + if (velocity < SLEEP_TIMING_MIN_MOVING_VELOCITY) { + float distance = gps::getDistanceFromPrevious(); //did we missed positions because we were sleeping ? + if (distance > GPS_DEFAULT_MISSED_POSITION_GAP_KM) stoppedInARow = 0; + else stoppedInARow = min(stoppedInARow + 1, SLEEP_DEFAULT_STOPPED_THRESHOLD + 1); //avoid overflow on REALLY long stops + + if (stoppedInARow < SLEEP_DEFAULT_STOPPED_THRESHOLD) { + sleepTime = SLEEP_DEFAULT_PAUSING_TIME_SECONDS; + state = TRACKER_MOVING_STATE::PAUSED; + } + else if (stoppedInARow == SLEEP_DEFAULT_STOPPED_THRESHOLD) state = TRACKER_MOVING_STATE::STOPPED; + else state = TRACKER_MOVING_STATE::STATIC; + } + else stoppedInARow = 0; + + NOTICE_FORMAT("updateSleepTime", "%dkmh => %d seconds", velocity, sleepTime); + return state; + } + + uint16_t mapSleepTime(uint8_t velocity) { + uint16_t result; + uint16_t currentTime = 0xFFFF; + + if (rtc::isAccurate()) { + tmElements_t time; + rtc::getTime(time); + + currentTime = SLEEP_TIMING_TIME(time.Hour, time.Minute); + } + + for (uint8_t i = flash::getArraySize(config::defaultSleepTimings); i--;) { + sleepTimings_t timing; + flash::read(&config::defaultSleepTimings[i], timing); + + if (velocity < timing.speed) continue; + if (currentTime != 0xFFFF && (currentTime < timing.timeMin || currentTime > timing.timeMax)) continue; + + result = timing.seconds; + break; + + } + + VERBOSE_FORMAT("mapSleepTime", "%d,%d", velocity, result); + return result; + } } \ No newline at end of file diff --git a/src/Core.h b/src/Core.h index 3f61206..7338ece 100644 --- a/src/Core.h +++ b/src/Core.h @@ -2,12 +2,10 @@ #include -#include "Debug.h" #include "Gps.h" #include "MainUnit.h" #include "Network.h" #include "Rtc.h" -#include "config/Pins.h" #include "Positions.h" enum class TRACKER_MOVING_STATE : uint8_t { diff --git a/src/Debug.cpp b/src/Debug.cpp index 7c1c97f..84d4633 100644 --- a/src/Debug.cpp +++ b/src/Debug.cpp @@ -1,300 +1,291 @@ -#include "Debug.h" -#include "Flash.h" -#include "Positions.h" -#include "Core.h" -#include "Alerts.h" - -#define LOGGER_NAME "Debug" - -#define MENU_ENTRY(name, text) const char MENU_##name[] PROGMEM = text - -const char FAKE_GPS_ENTRY[] PROGMEM = "1,1,20170924184842.000,49.454862,1.144537,71.900,2.70,172.6,1,,1.3,2.2,1.8,,11,7,,,37,,"; - -MENU_ENTRY(HEADER, "========================\n-- Menu --"); -MENU_ENTRY(SEPARATOR, "----"); - -MENU_ENTRY(RUN, "[R] Run"); -MENU_ENTRY(RUN_ONCE, "[r] Run once"); -MENU_ENTRY(RAM, "[f] Free RAM"); -MENU_ENTRY(READ_BATTERY, "[b] Read battery"); -MENU_ENTRY(GPS_ON, "[G] GPS On"); -MENU_ENTRY(GPS_OFF, "[g] GPS Off"); -MENU_ENTRY(GPS_GET, "[L] Get GPS position"); -MENU_ENTRY(GPS_SET, "[l] Set last GPS position"); -MENU_ENTRY(RTC_SET, "[T] Get RTC time"); -MENU_ENTRY(RTC_GET, "[t] Set RTC time"); -MENU_ENTRY(EEPROM_GET_CONFIG, "[C] Get EEPROM config"); -MENU_ENTRY(EEPROM_RESET_CONFIG, "[c] Reset EEPROM config"); -MENU_ENTRY(EEPROM_GET_CONTENT, "[E] Get EEPROM content"); -MENU_ENTRY(EEPROM_GET_ENTRIES, "[P] Get EEPROM entries"); -MENU_ENTRY(EEPROM_GET_LAST_ENTRY, "[p] Get EEPROM last entry"); -MENU_ENTRY(EEPROM_ADD_ENTRY, "[a] Add last entry to EEPROM"); -MENU_ENTRY(EEPROM_BACKUP_ENTRIES, "[B] Backup EEPROM entries"); -MENU_ENTRY(NOTIFY_FAILURES, "[F] Notify failures"); -MENU_ENTRY(CLEAR_ALERTS, "[A] Clear alerts"); -MENU_ENTRY(SLEEP_DEEP, "[s] Deep sleep for 10s"); -MENU_ENTRY(QUESTION, "?"); - -const uint8_t commandIdMapping[] PROGMEM = { - 'R', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::RUN), - 'r', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::ONCE), - 'f', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::RAM), - 'b', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::BATTERY), - 'G', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::GPS_ON), - 'g', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::GPS_OFF), - 'L', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::GPS_GET), - 'l', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::GPS_SET), - 'T', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::RTC_GET), - 't', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::RTC_SET), - 'C', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_CONFIG), - 'c', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_RESET_CONFIG), - 'E', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_CONTENT), - 'P', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_ENTRIES), - 'p', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_LAST_ENTRY), - 'a', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_ADD_ENTRY), - 'B', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_BACKUP_ENTRIES), - 'F', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::NOTIFY_FAILURES), - 'A', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::CLEAR_ALERTS), - 's', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::SLEEP_DEEP), -}; - -const char * const MENU_ENTRIES[] PROGMEM = { - MENU_HEADER, - MENU_RUN, - MENU_RUN_ONCE, - - MENU_SEPARATOR, - - MENU_RAM, - MENU_READ_BATTERY, - - MENU_SEPARATOR, - - MENU_GPS_ON, - MENU_GPS_OFF, - MENU_GPS_GET, - MENU_GPS_SET, - - MENU_SEPARATOR, - - MENU_RTC_SET, - MENU_RTC_GET, - - MENU_SEPARATOR, - - MENU_EEPROM_GET_CONFIG, - MENU_EEPROM_RESET_CONFIG, - MENU_EEPROM_GET_CONTENT, - MENU_EEPROM_GET_ENTRIES, - MENU_EEPROM_GET_LAST_ENTRY, - MENU_EEPROM_ADD_ENTRY, - MENU_EEPROM_BACKUP_ENTRIES, - MENU_SEPARATOR, - - MENU_NOTIFY_FAILURES, - MENU_CLEAR_ALERTS, - MENU_SEPARATOR, - - MENU_SLEEP_DEEP, - - MENU_QUESTION -}; - -static const PositionEntryMetadata fakeMetadata PROGMEM = { - 100, - 3800, - 10, - 20, - SIM808_GPS_STATUS::ACCURATE_FIX -}; - -int freeRam2() { // dirty hack because putting it in namespace doesn't compile - extern int __heap_start, *__brkval; - int v; - return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval); -} - -using namespace utils; - -namespace debug { - - namespace details { - inline void displayPosition(PositionEntry entry) { - Log.notice(F("%d,%d,%d,%d,%d,%s"), - entry.metadata.batteryLevel, - entry.metadata.batteryVoltage, - entry.metadata.temperature, - static_cast(entry.metadata.status), - entry.metadata.timeToFix, - entry.position); - } - } - - int freeRam() { - return freeRam2(); - } - - void displayFreeRam() { - Log.notice(F("RAM: %d\n"), freeRam()); - } - - GPSTRACKER_DEBUG_COMMAND parseCommand(char id) { - size_t mappingArraySize = flash::getArraySize(commandIdMapping); - char commandId; - - for (uint8_t i = 0; i < mappingArraySize; i += 2) { - commandId = pgm_read_byte_near(commandIdMapping + i); - if (commandId == id) return static_cast(pgm_read_byte_near(commandIdMapping + i + 1)); - } - - return GPSTRACKER_DEBUG_COMMAND::NONE; - } - - GPSTRACKER_DEBUG_COMMAND menu(uint16_t timeout) { - GPSTRACKER_DEBUG_COMMAND command; - size_t menuSize = flash::getArraySize(MENU_ENTRIES); - uint8_t intermediate_timeout = 50; - - do { - for (uint8_t i = 0; i < menuSize; i++) { - Serial.println(reinterpret_cast(pgm_read_word_near(&MENU_ENTRIES[i]))); - } - - while (!Serial.available()) { - if (timeout > 0) { - delay(intermediate_timeout); - timeout -= intermediate_timeout; - if (timeout <= 0) { - NOTICE_MSG("menu", "Timeout expired."); - return GPSTRACKER_DEBUG_COMMAND::RUN; - } - } - } - command = parseCommand(Serial.read()); - while (Serial.available()) Serial.read(); //flushing input - } while (command == GPSTRACKER_DEBUG_COMMAND::NONE); - - return command; - } - - void getAndDisplayGpsPosition() { - SIM808_GPS_STATUS gpsStatus = gps::acquireCurrentPosition(GPS_DEFAULT_TOTAL_TIMEOUT_MS); - - NOTICE_FORMAT("getAndDisplayGpsPosition", "%d %s", gpsStatus, gps::lastPosition); - } - - void setFakeGpsPosition() { - strlcpy_P(gps::lastPosition, FAKE_GPS_ENTRY, GPS_POSITION_SIZE); - - NOTICE_FORMAT("setFakeGpsPosition", "Last position set to : %s", gps::lastPosition); - NOTICE_FORMAT("setFakeGpsPosition", "Speed : %d", gps::getVelocity()); - NOTICE_FORMAT("setFakeGpsPosition", "Sleep time : %d", core::mapSleepTime(gps::getVelocity())); - } - - void getAndDisplayBattery() { - hardware::sim808::powerOn(); - SIM808ChargingStatus status = hardware::sim808::device.getChargingState(); - hardware::sim808::powerOff(); - - NOTICE_FORMAT("getAndDisplayBattery", "%d %d%% %dmV", status.state, status.level, status.voltage); - } - - void getAndDisplayRtcTime() { - tmElements_t time; - rtc::getTime(time); - - NOTICE_FORMAT("getAndDisplayRtcTime", "%d/%d/%d %d:%d:%d %t %d", tmYearToCalendar(time.Year), time.Month, time.Day, time.Hour, time.Minute, time.Second, rtc::isAccurate(), rtc::getTemperature()); - } - - void setRtcTime() { - tmElements_t time; - gps::getTime(time); - rtc::setTime(time); - } - - void getAndDisplaySleepTimes() { - size_t arraySize = flash::getArraySize(config::defaultSleepTimings); - sleepTimings_t maxSpeedTiming; - utils::flash::read(&config::defaultSleepTimings[arraySize - 1], maxSpeedTiming); - - for (int i = 0; i <= maxSpeedTiming.speed; i++) { - core::mapSleepTime(i); - } - - NOTICE_MSG("getAndDisplaySleepTimes", "Done"); - } - - void getAndDisplayEepromConfig() { - config::main::setup(); //forcing read again - } - - void getAndDisplayEepromContent() { - char buffer[128]; - hardware::i2c::powerOn(); - - for (int i = 0; i < 8; i++) { - hardware::i2c::eeprom.read(128 * i, buffer, 128); - for (int i = 0; i < 128; i++) { - Serial.print(buffer[i], HEX); - } - } - Serial.println(); - hardware::i2c::powerOff(); - - NOTICE_MSG("getAndDisplayEepromContent", "Done"); - } - - void getAndDisplayEepromPositions() { - uint16_t currentEntryIndex = config::main::value.firstEntry; - PositionEntry currentEntry; - - hardware::i2c::powerOn(); - do { - if (!positions::get(currentEntryIndex, currentEntry)) break; - details::displayPosition(currentEntry); - } while (positions::moveNext(currentEntryIndex)); - hardware::i2c::powerOff(); - } - - void getAndDisplayEepromLastPosition() { - uint16_t lastEntryIndex = config::main::value.lastEntry; - PositionEntry lastEntry; - - if(positions::get(lastEntryIndex, lastEntry)) details::displayPosition(lastEntry); - else Log.notice(F("No position recorded\n")); - } - - void addLastPositionToEeprom() { - hardware::sim808::powerOn(); - SIM808ChargingStatus status = hardware::sim808::device.getChargingState(); - hardware::sim808::powerOff(); - - PositionEntryMetadata metadata = { - status.level, - status.voltage, - rtc::getTemperature(), - 0, - SIM808_GPS_STATUS::OFF - }; - - for(int i = 0; i < 10; i++) positions::appendLast(metadata); - } - - void notifyFailures() { - PositionEntryMetadata metadata = {}; - flash::read(&fakeMetadata, metadata); - metadata.batteryLevel = 1; - metadata.temperature = ALERT_SUSPICIOUS_RTC_TEMPERATURE; - - uint8_t alerts = core::notifyFailures(metadata); - NOTICE_FORMAT("notifyFailures", "result : %B", alerts); - alerts::add(alerts); - } - - void clearAlerts() { - PositionEntryMetadata metadata = {}; - flash::read(&fakeMetadata, metadata); - - alerts::clear(metadata); - } +#include "Debug.h" +#include "MainUnit.h" +#include "Flash.h" +#include "Positions.h" +#include "Core.h" +#include "Alerts.h" +#include "Logging.h" + +#define LOGGER_NAME "Debug" + +#define MENU_ENTRY(name, text) const char MENU_##name[] PROGMEM = text + +const char FAKE_GPS_ENTRY[] PROGMEM = "1,1,20170924184842.000,49.454862,1.144537,71.900,2.70,172.6,1,,1.3,2.2,1.8,,11,7,,,37,,"; + +MENU_ENTRY(HEADER, "========================\n-- Menu --"); +MENU_ENTRY(SEPARATOR, "----"); + +MENU_ENTRY(RUN, "[R] Run"); +MENU_ENTRY(RUN_ONCE, "[r] Run once"); +MENU_ENTRY(RAM, "[f] Free RAM"); +MENU_ENTRY(READ_BATTERY, "[b] Read battery"); +MENU_ENTRY(GPS_ON, "[G] GPS On"); +MENU_ENTRY(GPS_OFF, "[g] GPS Off"); +MENU_ENTRY(GPS_GET, "[L] Get GPS position"); +MENU_ENTRY(GPS_SET, "[l] Set last GPS position"); +MENU_ENTRY(RTC_SET, "[T] Get RTC time"); +MENU_ENTRY(RTC_GET, "[t] Set RTC time"); +MENU_ENTRY(EEPROM_GET_CONFIG, "[C] Get EEPROM config"); +MENU_ENTRY(EEPROM_RESET_CONFIG, "[c] Reset EEPROM config"); +MENU_ENTRY(EEPROM_GET_CONTENT, "[E] Get EEPROM content"); +MENU_ENTRY(EEPROM_GET_ENTRIES, "[P] Get EEPROM entries"); +MENU_ENTRY(EEPROM_GET_LAST_ENTRY, "[p] Get EEPROM last entry"); +MENU_ENTRY(EEPROM_ADD_ENTRY, "[a] Add last entry to EEPROM"); +MENU_ENTRY(EEPROM_BACKUP_ENTRIES, "[B] Backup EEPROM entries"); +MENU_ENTRY(NOTIFY_FAILURES, "[F] Notify failures"); +MENU_ENTRY(CLEAR_ALERTS, "[A] Clear alerts"); +MENU_ENTRY(SLEEP_DEEP, "[s] Deep sleep for 10s"); +MENU_ENTRY(QUESTION, "?"); + +const uint8_t commandIdMapping[] PROGMEM = { + 'R', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::RUN), + 'r', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::ONCE), + 'f', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::RAM), + 'b', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::BATTERY), + 'G', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::GPS_ON), + 'g', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::GPS_OFF), + 'L', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::GPS_GET), + 'l', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::GPS_SET), + 'T', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::RTC_GET), + 't', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::RTC_SET), + 'C', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_CONFIG), + 'c', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_RESET_CONFIG), + 'E', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_CONTENT), + 'P', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_ENTRIES), + 'p', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_LAST_ENTRY), + 'a', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_ADD_ENTRY), + 'B', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_BACKUP_ENTRIES), + 'F', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::NOTIFY_FAILURES), + 'A', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::CLEAR_ALERTS), + 's', static_cast(debug::GPSTRACKER_DEBUG_COMMAND::SLEEP_DEEP), +}; + +const char * const MENU_ENTRIES[] PROGMEM = { + MENU_HEADER, + MENU_RUN, + MENU_RUN_ONCE, + + MENU_SEPARATOR, + + MENU_RAM, + MENU_READ_BATTERY, + + MENU_SEPARATOR, + + MENU_GPS_ON, + MENU_GPS_OFF, + MENU_GPS_GET, + MENU_GPS_SET, + + MENU_SEPARATOR, + + MENU_RTC_SET, + MENU_RTC_GET, + + MENU_SEPARATOR, + + MENU_EEPROM_GET_CONFIG, + MENU_EEPROM_RESET_CONFIG, + MENU_EEPROM_GET_CONTENT, + MENU_EEPROM_GET_ENTRIES, + MENU_EEPROM_GET_LAST_ENTRY, + MENU_EEPROM_ADD_ENTRY, + MENU_EEPROM_BACKUP_ENTRIES, + MENU_SEPARATOR, + + MENU_NOTIFY_FAILURES, + MENU_CLEAR_ALERTS, + MENU_SEPARATOR, + + MENU_SLEEP_DEEP, + + MENU_QUESTION +}; + +static const PositionEntryMetadata fakeMetadata PROGMEM = { + 100, + 3800, + 10, + 20, + SIM808_GPS_STATUS::ACCURATE_FIX +}; + +using namespace utils; + +namespace debug { + + namespace details { + inline void displayPosition(PositionEntry entry) { + Log.notice(F("%d,%d,%d,%d,%d,%s"), + entry.metadata.batteryLevel, + entry.metadata.batteryVoltage, + entry.metadata.temperature, + static_cast(entry.metadata.status), + entry.metadata.timeToFix, + entry.position); + } + } + + void displayFreeRam() { + Log.notice(F("RAM: %d\n"), mainunit::freeRam()); + } + + GPSTRACKER_DEBUG_COMMAND parseCommand(char id) { + size_t mappingArraySize = flash::getArraySize(commandIdMapping); + char commandId; + + for (uint8_t i = 0; i < mappingArraySize; i += 2) { + commandId = pgm_read_byte_near(commandIdMapping + i); + if (commandId == id) return static_cast(pgm_read_byte_near(commandIdMapping + i + 1)); + } + + return GPSTRACKER_DEBUG_COMMAND::NONE; + } + + GPSTRACKER_DEBUG_COMMAND menu(uint16_t timeout) { + GPSTRACKER_DEBUG_COMMAND command; + size_t menuSize = flash::getArraySize(MENU_ENTRIES); + + do { + for (uint8_t i = 0; i < menuSize; i++) { + Serial.println(reinterpret_cast(pgm_read_word_near(&MENU_ENTRIES[i]))); + } + + while (!Serial.available()) { + if (timeout > 0) { + delay(MENU_INTERMEDIATE_TIMEOUT); + timeout -= MENU_INTERMEDIATE_TIMEOUT; + if (timeout <= 0) { + NOTICE_MSG("menu", "Timeout expired."); + return GPSTRACKER_DEBUG_COMMAND::RUN; + } + } + } + command = parseCommand(Serial.read()); + while (Serial.available()) Serial.read(); //flushing input + } while (command == GPSTRACKER_DEBUG_COMMAND::NONE); + + return command; + } + + void getAndDisplayGpsPosition() { + SIM808_GPS_STATUS gpsStatus = gps::acquireCurrentPosition(GPS_DEFAULT_TOTAL_TIMEOUT_MS); + + NOTICE_FORMAT("getAndDisplayGpsPosition", "%d %s", gpsStatus, gps::lastPosition); + } + + void setFakeGpsPosition() { + strlcpy_P(gps::lastPosition, FAKE_GPS_ENTRY, GPS_POSITION_SIZE); + + NOTICE_FORMAT("setFakeGpsPosition", "Last position set to : %s", gps::lastPosition); + NOTICE_FORMAT("setFakeGpsPosition", "Speed : %d", gps::getVelocity()); + NOTICE_FORMAT("setFakeGpsPosition", "Sleep time : %d", core::mapSleepTime(gps::getVelocity())); + } + + void getAndDisplayBattery() { + hardware::sim808::powerOn(); + SIM808ChargingStatus status = hardware::sim808::device.getChargingState(); + hardware::sim808::powerOff(); + + NOTICE_FORMAT("getAndDisplayBattery", "%d %d%% %dmV", status.state, status.level, status.voltage); + } + + void getAndDisplayRtcTime() { + tmElements_t time; + rtc::getTime(time); + + NOTICE_FORMAT("getAndDisplayRtcTime", "%d/%d/%d %d:%d:%d %t %d", tmYearToCalendar(time.Year), time.Month, time.Day, time.Hour, time.Minute, time.Second, rtc::isAccurate(), rtc::getTemperature()); + } + + void setRtcTime() { + tmElements_t time; + gps::getTime(time); + rtc::setTime(time); + } + + void getAndDisplaySleepTimes() { + size_t arraySize = flash::getArraySize(config::defaultSleepTimings); + sleepTimings_t maxSpeedTiming; + utils::flash::read(&config::defaultSleepTimings[arraySize - 1], maxSpeedTiming); + + for (int i = 0; i <= maxSpeedTiming.speed; i++) { + core::mapSleepTime(i); + } + + NOTICE_MSG("getAndDisplaySleepTimes", "Done"); + } + + void getAndDisplayEepromConfig() { + config::main::setup(); //forcing read again + } + + void getAndDisplayEepromContent() { + char buffer[128]; + hardware::i2c::powerOn(); + + for (int i = 0; i < 8; i++) { + hardware::i2c::eeprom.read(128 * i, buffer, 128); + for (int i = 0; i < 128; i++) { + Serial.print(buffer[i], HEX); + } + } + Serial.println(); + hardware::i2c::powerOff(); + + NOTICE_MSG("getAndDisplayEepromContent", "Done"); + } + + void getAndDisplayEepromPositions() { + uint16_t currentEntryIndex = config::main::value.firstEntry; + PositionEntry currentEntry; + + hardware::i2c::powerOn(); + do { + if (!positions::get(currentEntryIndex, currentEntry)) break; + details::displayPosition(currentEntry); + } while (positions::moveNext(currentEntryIndex)); + hardware::i2c::powerOff(); + } + + void getAndDisplayEepromLastPosition() { + uint16_t lastEntryIndex = config::main::value.lastEntry; + PositionEntry lastEntry; + + if(positions::get(lastEntryIndex, lastEntry)) details::displayPosition(lastEntry); + else Log.notice(F("No position recorded\n")); + } + + void addLastPositionToEeprom() { + hardware::sim808::powerOn(); + SIM808ChargingStatus status = hardware::sim808::device.getChargingState(); + hardware::sim808::powerOff(); + + PositionEntryMetadata metadata = { + status.level, + status.voltage, + rtc::getTemperature(), + 0, + SIM808_GPS_STATUS::OFF + }; + + for(int i = 0; i < 10; i++) positions::appendLast(metadata); + } + + void notifyFailures() { + PositionEntryMetadata metadata = {}; + flash::read(&fakeMetadata, metadata); + metadata.batteryLevel = 1; + metadata.temperature = ALERT_SUSPICIOUS_RTC_TEMPERATURE; + + uint8_t alerts = core::notifyFailures(metadata); + NOTICE_FORMAT("notifyFailures", "result : %B", alerts); + alerts::add(alerts); + } + + void clearAlerts() { + PositionEntryMetadata metadata = {}; + flash::read(&fakeMetadata, metadata); + + alerts::clear(metadata); + } } \ No newline at end of file diff --git a/src/Debug.h b/src/Debug.h index b02fea7..dbe40f4 100644 --- a/src/Debug.h +++ b/src/Debug.h @@ -1,61 +1,53 @@ -#pragma once - -#include -#include "Config.h" -#include "Logging.h" - -#include "Core.h" - -#include "Hardware.h" -#include "Gps.h" -#include "Rtc.h" - -namespace debug { - - enum class GPSTRACKER_DEBUG_COMMAND : uint8_t { - NONE, - RUN, - ONCE, - RAM, - BATTERY, - GPS_ON, - GPS_OFF, - GPS_GET, - GPS_SET, - RTC_GET, - RTC_SET, - EEPROM_GET_CONFIG, - EEPROM_RESET_CONFIG, - EEPROM_GET_CONTENT, - EEPROM_GET_LAST_ENTRY, - EEPROM_GET_ENTRIES, - EEPROM_ADD_ENTRY, - EEPROM_BACKUP_ENTRIES, - NOTIFY_FAILURES, - CLEAR_ALERTS, - SLEEP_DEEP - }; - - int freeRam(); - void displayFreeRam(); - - GPSTRACKER_DEBUG_COMMAND menu(uint16_t timeout); - - void getAndDisplayBattery(); - void getAndDisplayGpsPosition(); - void setFakeGpsPosition(); - - void getAndDisplayRtcTime(); - void setRtcTime(); - - void getAndDisplaySleepTimes(); - - void getAndDisplayEepromConfig(); - void getAndDisplayEepromContent(); - void getAndDisplayEepromPositions(); - void getAndDisplayEepromLastPosition(); - void addLastPositionToEeprom(); - - void notifyFailures(); - void clearAlerts(); -} +#pragma once + +#include + +namespace debug { + + enum class GPSTRACKER_DEBUG_COMMAND : uint8_t { + NONE, + RUN, + ONCE, + RAM, + BATTERY, + GPS_ON, + GPS_OFF, + GPS_GET, + GPS_SET, + RTC_GET, + RTC_SET, + EEPROM_GET_CONFIG, + EEPROM_RESET_CONFIG, + EEPROM_GET_CONTENT, + EEPROM_GET_LAST_ENTRY, + EEPROM_GET_ENTRIES, + EEPROM_ADD_ENTRY, + EEPROM_BACKUP_ENTRIES, + NOTIFY_FAILURES, + CLEAR_ALERTS, + SLEEP_DEEP + }; + + int freeRam(); + void displayFreeRam(); + + GPSTRACKER_DEBUG_COMMAND menu(uint16_t timeout); + + void getAndDisplayBattery(); + void getAndDisplayGpsPosition(); + void setFakeGpsPosition(); + + void getAndDisplayRtcTime(); + void setRtcTime(); + + void getAndDisplaySleepTimes(); + + void getAndDisplayEepromConfig(); + void getAndDisplayEepromContent(); + void getAndDisplayEepromPositions(); + void getAndDisplayEepromLastPosition(); + void addLastPositionToEeprom(); + + void notifyFailures(); + void clearAlerts(); +} diff --git a/src/Gps.cpp b/src/Gps.cpp index 16e5944..ba05898 100644 --- a/src/Gps.cpp +++ b/src/Gps.cpp @@ -1,118 +1,118 @@ -#include "Gps.h" -#include "Config.h" -#include "Debug.h" -#include "Hardware.h" -#include "MainUnit.h" -#include "math.h" - -#define LOGGER_NAME "Gps" - -#define TIME_YEAR_OFFSET 0 -#define TIME_MONTH_OFFSET 4 -#define TIME_DAY_OFFSET 6 -#define TIME_HOUR_OFFSET 8 -#define TIME_MINUTE_OFFSET 10 -#define TIME_SECOND_OFFSET 12 - -#define EARTH_RADIUS 6371 //kilometers - -namespace gps { - - namespace details { - uint8_t parseSubstring(char *buffer, char *start, uint8_t size) { - strlcpy(buffer, start, size + 1); - return static_cast(strtoul(buffer, NULL, 10)); - } - - } - char lastPosition[GPS_POSITION_SIZE]; - SIM808_GPS_STATUS lastStatus; - - float previousLat = 0; - float previousLng = 0; - - SIM808_GPS_STATUS acquireCurrentPosition(int32_t timeout) { - SIM808_GPS_STATUS currentStatus = SIM808_GPS_STATUS::OFF; - - do { - currentStatus = hardware::sim808::device.getGpsStatus(); - if (currentStatus > SIM808_GPS_STATUS::FIX) break; //if we have an accurate fix, break right now - - NOTICE_FORMAT("acquireCurrentPosition", "%d", currentStatus); - mainunit::deepSleep(GPS_DEFAULT_INTERMEDIATE_TIMEOUT_MS / 1000); - timeout -= GPS_DEFAULT_INTERMEDIATE_TIMEOUT_MS; - } while (timeout > 1); - - if (currentStatus > SIM808_GPS_STATUS::NO_FIX) { - lastStatus = currentStatus; - hardware::sim808::device.getGpsPosition(lastPosition); - } - - NOTICE_FORMAT("acquireCurrentPosition", "%d", currentStatus); - return currentStatus; - } - - void preserveCurrentCoordinates() { - float lat, lng; - if(!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::LATITUDE, &lat)) lat = 0; - if(!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::LONGITUDE, &lng)) lng = 0; - - if (lat == 0 || lng == 0) return; - previousLat = lat; - previousLng = lng; - } - - float getDistanceFromPrevious() { - float lat1, lng1, lat2, lng2; - - if(!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::LATITUDE, &lat2)) return 0; - if(!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::LONGITUDE, &lng2)) return 0; - - VERBOSE_FORMAT("distanceFromPrevious", "%s, %f, %f, %f, %f", lastPosition, previousLat, previousLng, lat2, lng2); - - lat1 = radians(previousLat); - lng1 = radians(previousLng); - - lat2 = radians(lat2); - lng2 = radians(lng2); - - float dlat = lat2 - lat1; - float dlng = lng2 - lng1; - float a = ( - pow(sin(dlat / 2), 2) + - cos(lat1) * cos(lat2) * pow(sin(dlng / 2), 2) - ); - - - a = EARTH_RADIUS * (2 * atan2(sqrt(a), sqrt(1 - a))); //kilometers - - NOTICE_FORMAT("distanceFromPrevious", "%fkm", a); - return a; - } - - uint8_t getVelocity() { - uint8_t velocity; - if (!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::SPEED, &velocity)) velocity = 0; - - VERBOSE_FORMAT("getVelocity", "%d", velocity); - - return velocity; - } - - void getTime(tmElements_t &time) { - char *timeStr; - char buffer[5]; - hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::UTC, &timeStr); - - VERBOSE_FORMAT("getTime", "%s", timeStr); - - time.Year = CalendarYrToTm(details::parseSubstring(buffer, timeStr + TIME_YEAR_OFFSET, 4)); - time.Month = details::parseSubstring(buffer, timeStr + TIME_MONTH_OFFSET, 2); - time.Day = details::parseSubstring(buffer, timeStr + TIME_DAY_OFFSET, 2); - time.Hour = details::parseSubstring(buffer, timeStr + TIME_HOUR_OFFSET, 2); - time.Minute = details::parseSubstring(buffer, timeStr + TIME_MINUTE_OFFSET, 2); - time.Second = details::parseSubstring(buffer, timeStr + TIME_SECOND_OFFSET, 2); - - NOTICE_FORMAT("getTime", "%d/%d/%d %d:%d:%d", tmYearToCalendar(time.Year), time.Month, time.Day, time.Hour, time.Minute, time.Second); - } +#include "Gps.h" +#include "Config.h" +#include "Hardware.h" +#include "MainUnit.h" +#include "Logging.h" +#include "math.h" + +#define LOGGER_NAME "Gps" + +#define TIME_YEAR_OFFSET 0 +#define TIME_MONTH_OFFSET 4 +#define TIME_DAY_OFFSET 6 +#define TIME_HOUR_OFFSET 8 +#define TIME_MINUTE_OFFSET 10 +#define TIME_SECOND_OFFSET 12 + +#define EARTH_RADIUS 6371 //kilometers + +namespace gps { + + namespace details { + uint8_t parseSubstring(char *buffer, char *start, uint8_t size) { + strlcpy(buffer, start, size + 1); + return static_cast(strtoul(buffer, NULL, 10)); + } + + } + char lastPosition[GPS_POSITION_SIZE]; + SIM808_GPS_STATUS lastStatus; + + float previousLat = 0; + float previousLng = 0; + + SIM808_GPS_STATUS acquireCurrentPosition(int32_t timeout) { + SIM808_GPS_STATUS currentStatus = SIM808_GPS_STATUS::OFF; + + do { + currentStatus = hardware::sim808::device.getGpsStatus(); + if (currentStatus > SIM808_GPS_STATUS::FIX) break; //if we have an accurate fix, break right now + + NOTICE_FORMAT("acquireCurrentPosition", "%d", currentStatus); + mainunit::deepSleep(GPS_DEFAULT_INTERMEDIATE_TIMEOUT_MS / 1000); + timeout -= GPS_DEFAULT_INTERMEDIATE_TIMEOUT_MS; + } while (timeout > 1); + + if (currentStatus > SIM808_GPS_STATUS::NO_FIX) { + lastStatus = currentStatus; + hardware::sim808::device.getGpsPosition(lastPosition); + } + + NOTICE_FORMAT("acquireCurrentPosition", "%d", currentStatus); + return currentStatus; + } + + void preserveCurrentCoordinates() { + float lat, lng; + if(!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::LATITUDE, &lat)) lat = 0; + if(!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::LONGITUDE, &lng)) lng = 0; + + if (lat == 0 || lng == 0) return; + previousLat = lat; + previousLng = lng; + } + + float getDistanceFromPrevious() { + float lat1, lng1, lat2, lng2; + + if(!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::LATITUDE, &lat2)) return 0; + if(!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::LONGITUDE, &lng2)) return 0; + + VERBOSE_FORMAT("distanceFromPrevious", "%s, %f, %f, %f, %f", lastPosition, previousLat, previousLng, lat2, lng2); + + lat1 = radians(previousLat); + lng1 = radians(previousLng); + + lat2 = radians(lat2); + lng2 = radians(lng2); + + float dlat = lat2 - lat1; + float dlng = lng2 - lng1; + float a = ( + pow(sin(dlat / 2), 2) + + cos(lat1) * cos(lat2) * pow(sin(dlng / 2), 2) + ); + + + a = EARTH_RADIUS * (2 * atan2(sqrt(a), sqrt(1 - a))); //kilometers + + NOTICE_FORMAT("distanceFromPrevious", "%fkm", a); + return a; + } + + uint8_t getVelocity() { + uint8_t velocity; + if (!hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::SPEED, &velocity)) velocity = 0; + + VERBOSE_FORMAT("getVelocity", "%d", velocity); + + return velocity; + } + + void getTime(tmElements_t &time) { + char *timeStr; + char buffer[5]; + hardware::sim808::device.getGpsField(lastPosition, SIM808_GPS_FIELD::UTC, &timeStr); + + VERBOSE_FORMAT("getTime", "%s", timeStr); + + time.Year = CalendarYrToTm(details::parseSubstring(buffer, timeStr + TIME_YEAR_OFFSET, 4)); + time.Month = details::parseSubstring(buffer, timeStr + TIME_MONTH_OFFSET, 2); + time.Day = details::parseSubstring(buffer, timeStr + TIME_DAY_OFFSET, 2); + time.Hour = details::parseSubstring(buffer, timeStr + TIME_HOUR_OFFSET, 2); + time.Minute = details::parseSubstring(buffer, timeStr + TIME_MINUTE_OFFSET, 2); + time.Second = details::parseSubstring(buffer, timeStr + TIME_SECOND_OFFSET, 2); + + NOTICE_FORMAT("getTime", "%d/%d/%d %d:%d:%d", tmYearToCalendar(time.Year), time.Month, time.Day, time.Hour, time.Minute, time.Second); + } } \ No newline at end of file diff --git a/src/GpsTracker.h b/src/GpsTracker.h deleted file mode 100644 index 6863ac7..0000000 --- a/src/GpsTracker.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include - -#include "Debug.h" -#include "Config.h" -#include "Core.h" - -#define LOGGER_NAME "GpsTracker" diff --git a/src/GpsTracker.ino b/src/GpsTracker.ino index 984c9bb..7963c48 100644 --- a/src/GpsTracker.ino +++ b/src/GpsTracker.ino @@ -1,95 +1,97 @@ -#include "GpsTracker.h" -#include "Positions.h" - -#if _DEBUG -#define MENU_DEFAULT_TIMEOUT 0 -#else -#define MENU_DEFAULT_TIMEOUT 10000 - -#endif -bool bypassMenu = false; -uint16_t menuTimeout = MENU_DEFAULT_TIMEOUT; - -void setup() { - logging::setup(); - - config::main::setup(); - rtc::setup(); - hardware::sim808::setup(); - - positions::setup(); -} - -void loop() { - - debug::GPSTRACKER_DEBUG_COMMAND command = debug::GPSTRACKER_DEBUG_COMMAND::RUN; - if (Serial && !bypassMenu) command = debug::menu(menuTimeout); - - if (command == debug::GPSTRACKER_DEBUG_COMMAND::RUN) bypassMenu = true; - else menuTimeout = 0; //disable timeout once a command has been entered - - bypassMenu = command == debug::GPSTRACKER_DEBUG_COMMAND::RUN; - - switch (command) { - case debug::GPSTRACKER_DEBUG_COMMAND::RUN: - case debug::GPSTRACKER_DEBUG_COMMAND::ONCE: - core::main(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::RAM: - debug::displayFreeRam(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::BATTERY: - debug::getAndDisplayBattery(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::GPS_ON: - gps::powerOn(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::GPS_OFF: - gps::powerOff(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::GPS_GET: - debug::getAndDisplayGpsPosition(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::GPS_SET: - debug::setFakeGpsPosition(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::RTC_GET: - debug::getAndDisplayRtcTime(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::RTC_SET: - debug::setRtcTime(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_CONFIG: - debug::getAndDisplayEepromConfig(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_RESET_CONFIG: - config::main::reset(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_CONTENT: - debug::getAndDisplayEepromContent(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_ENTRIES: - debug::getAndDisplayEepromPositions(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_LAST_ENTRY: - debug::getAndDisplayEepromLastPosition(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_ADD_ENTRY: - debug::addLastPositionToEeprom(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_BACKUP_ENTRIES: - positions::doBackup(true); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::NOTIFY_FAILURES: - debug::notifyFailures(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::CLEAR_ALERTS: - debug::clearAlerts(); - break; - case debug::GPSTRACKER_DEBUG_COMMAND::SLEEP_DEEP: - mainunit::deepSleep(10); - break; - default: - NOTICE_MSG("loop", "Unsupported"); - } -} +#include +#include + +#include "Debug.h" +#include "Config.h" +#include "Core.h" +#include "Positions.h" +#include "Logging.h" + +#define LOGGER_NAME "GpsTracker" + +bool bypassMenu = false; +uint16_t menuTimeout = MENU_TIMEOUT; + +void setup() { + logging::setup(); + + config::main::setup(); + rtc::setup(); + hardware::sim808::setup(); + + positions::setup(); +} + +void loop() { + + debug::GPSTRACKER_DEBUG_COMMAND command = debug::GPSTRACKER_DEBUG_COMMAND::RUN; + if (Serial && !bypassMenu) command = debug::menu(menuTimeout); + + if (command == debug::GPSTRACKER_DEBUG_COMMAND::RUN) bypassMenu = true; + else menuTimeout = 0; //disable timeout once a command has been entered + + bypassMenu = command == debug::GPSTRACKER_DEBUG_COMMAND::RUN; + + switch (command) { + case debug::GPSTRACKER_DEBUG_COMMAND::RUN: + case debug::GPSTRACKER_DEBUG_COMMAND::ONCE: + core::main(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::RAM: + debug::displayFreeRam(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::BATTERY: + debug::getAndDisplayBattery(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::GPS_ON: + gps::powerOn(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::GPS_OFF: + gps::powerOff(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::GPS_GET: + debug::getAndDisplayGpsPosition(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::GPS_SET: + debug::setFakeGpsPosition(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::RTC_GET: + debug::getAndDisplayRtcTime(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::RTC_SET: + debug::setRtcTime(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_CONFIG: + debug::getAndDisplayEepromConfig(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_RESET_CONFIG: + config::main::reset(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_CONTENT: + debug::getAndDisplayEepromContent(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_ENTRIES: + debug::getAndDisplayEepromPositions(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_GET_LAST_ENTRY: + debug::getAndDisplayEepromLastPosition(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_ADD_ENTRY: + debug::addLastPositionToEeprom(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::EEPROM_BACKUP_ENTRIES: + positions::doBackup(true); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::NOTIFY_FAILURES: + debug::notifyFailures(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::CLEAR_ALERTS: + debug::clearAlerts(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::SLEEP_DEEP: + mainunit::deepSleep(10); + break; + default: + NOTICE_MSG("loop", "Unsupported"); + } +} diff --git a/src/Hardware.cpp b/src/Hardware.cpp index 3400604..ac2197a 100644 --- a/src/Hardware.cpp +++ b/src/Hardware.cpp @@ -1,22 +1,19 @@ #include "Config.h" #include "Hardware.h" -#include "config/Pins.h" -#include "Debug.h" +#include "config/Hardware.h" +#include "Logging.h" -#include #include -#include #include #include - namespace hardware { #define LOGGER_NAME "Hardware::sim808" namespace sim808 { - SoftwareSerial simSerial = SoftwareSerial(SIM_TX, SIM_RX); + SIM_SERIAL_TYPE simSerial = SIM_SERIAL; SIM808 device = SIM808(SIM_RST, SIM_PWR, SIM_STATUS); uint8_t networkPoweredCount = 0; uint8_t gpsPoweredCount = 0; @@ -119,7 +116,7 @@ namespace hardware { namespace i2c { - E24 eeprom = E24(E24Size_t::E24_512K); + E24 eeprom = E24(E24Size_t::E24_512K, E24_ADDRESS); uint8_t poweredCount = 0; void powerOn() { diff --git a/src/Hardware.h b/src/Hardware.h index 4e1353a..e245f13 100644 --- a/src/Hardware.h +++ b/src/Hardware.h @@ -1,31 +1,31 @@ -#pragma once - -#include -#include -#include - -namespace hardware { - - namespace sim808 { - extern SoftwareSerial simSerial; - extern SIM808 device; - - void powerOn(); - void powerOff(); - - void setup(); - - void gpsPowerOn(); - void gpsPowerOff(); - - void networkPowerOn(); - void networkPowerOff(); - } - - namespace i2c { - extern E24 eeprom; - - void powerOn(); - void powerOff(bool forced = false); - } +#pragma once + +#include "config/Hardware.h" +#include +#include + +namespace hardware { + + namespace sim808 { + extern SIM_SERIAL_TYPE simSerial; + extern SIM808 device; + + void powerOn(); + void powerOff(); + + void setup(); + + void gpsPowerOn(); + void gpsPowerOff(); + + void networkPowerOn(); + void networkPowerOff(); + } + + namespace i2c { + extern E24 eeprom; + + void powerOn(); + void powerOff(bool forced = false); + } } \ No newline at end of file diff --git a/src/MainUnit.cpp b/src/MainUnit.cpp index fe12fdf..9f0f79b 100644 --- a/src/MainUnit.cpp +++ b/src/MainUnit.cpp @@ -1,10 +1,13 @@ #include "MainUnit.h" #include "Rtc.h" -#include "config/Pins.h" -#include "Debug.h" +#include "Hardware.h" +#include "config/Hardware.h" +#include "Logging.h" #define LOGGER_NAME "MainUnit" +extern int __heap_start, *__brkval; + namespace mainunit { namespace details { @@ -42,4 +45,9 @@ namespace mainunit { LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); details::wokeUp(); } + + int freeRam() { + int v; + return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval); + } } \ No newline at end of file diff --git a/src/MainUnit.h b/src/MainUnit.h index 791894a..089d6c4 100644 --- a/src/MainUnit.h +++ b/src/MainUnit.h @@ -1,8 +1,9 @@ -#pragma once - -#include -#include - -namespace mainunit { - void deepSleep(uint16_t seconds); +#pragma once + +#include +#include + +namespace mainunit { + void deepSleep(uint16_t seconds); + int freeRam(); } \ No newline at end of file diff --git a/src/Network.cpp b/src/Network.cpp index 79033f3..d5f7d5b 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -1,76 +1,76 @@ -#include "Config.h" - -#include "Debug.h" -#include "Network.h" -#include "Hardware.h" -#include "MainUnit.h" -#include "Rtc.h" - -#define LOGGER_NAME "Network" - -namespace network { - - timestamp_t _poweredOnTime; - - void powerOn() { - hardware::sim808::networkPowerOn(); - _poweredOnTime = rtc::getTime(); - } - - void powerOff() { - hardware::sim808::networkPowerOff(); - _poweredOnTime = 0; - } - - __attribute__((__optimize__("O2"))) - SIM808RegistrationStatus waitForRegistered(uint32_t timeout, bool relativeToPowerOnTime = true) { - - SIM808RegistrationStatus currentStatus; - SIM808SignalQualityReport report; - uint8_t noReliableNetwork = 0; - - if (relativeToPowerOnTime) timeout -= (rtc::getTime() - _poweredOnTime) * 1000; - - currentStatus = hardware::sim808::device.getNetworkRegistrationStatus(); - report = hardware::sim808::device.getSignalQuality(); - - do { - if (isAvailable(currentStatus.stat)) break; - - NOTICE_FORMAT("waitForRegistered", "%d, [%d %ddBm]", currentStatus.stat, report.ssri, report.attenuation); - - if (report.ssri < NETWORK_DEFAULT_NO_NETWORK_QUALITY_THRESHOLD) noReliableNetwork++; - else noReliableNetwork = 0; - if (noReliableNetwork > NETWORK_DEFAULT_NO_NETWORK_TRIES) { - NOTICE_MSG("waitForRegistered", "No reliable signal"); - break; //after a while, no network really means no network. Bailing out - } - - mainunit::deepSleep(NETWORK_DEFAULT_INTERMEDIATE_TIMEOUT_MS / 1000); - timeout -= NETWORK_DEFAULT_INTERMEDIATE_TIMEOUT_MS; - - currentStatus = hardware::sim808::device.getNetworkRegistrationStatus(); - report = hardware::sim808::device.getSignalQuality(); - } while (timeout > 1); - - NOTICE_FORMAT("waitForRegistered", "%d, [%d %ddBm]", currentStatus.stat, report.ssri, report.attenuation); - return currentStatus; - } - - bool isAvailable(SIM808_NETWORK_REGISTRATION_STATE state) { - return static_cast(state) & - (static_cast(SIM808_NETWORK_REGISTRATION_STATE::REGISTERED) | static_cast(SIM808_NETWORK_REGISTRATION_STATE::ROAMING)) - != 0; - } - - bool enableGprs() { - return hardware::sim808::device.enableGprs(config::main::value.network.apn); - } - - bool sendSms(const char * msg) { - const char * phoneNumber = config::main::value.contactPhone; - - NOTICE_FORMAT("sendSms", "%s, %s", phoneNumber, msg); - return hardware::sim808::device.sendSms(phoneNumber, msg); - } +#include "Config.h" + +#include "Network.h" +#include "Hardware.h" +#include "MainUnit.h" +#include "Rtc.h" +#include "Logging.h" + +#define LOGGER_NAME "Network" + +namespace network { + + timestamp_t _poweredOnTime; + + void powerOn() { + hardware::sim808::networkPowerOn(); + _poweredOnTime = rtc::getTime(); + } + + void powerOff() { + hardware::sim808::networkPowerOff(); + _poweredOnTime = 0; + } + + __attribute__((__optimize__("O2"))) + SIM808RegistrationStatus waitForRegistered(uint32_t timeout, bool relativeToPowerOnTime = true) { + + SIM808RegistrationStatus currentStatus; + SIM808SignalQualityReport report; + uint8_t noReliableNetwork = 0; + + if (relativeToPowerOnTime) timeout -= (rtc::getTime() - _poweredOnTime) * 1000; + + currentStatus = hardware::sim808::device.getNetworkRegistrationStatus(); + report = hardware::sim808::device.getSignalQuality(); + + do { + if (isAvailable(currentStatus.stat)) break; + + NOTICE_FORMAT("waitForRegistered", "%d, [%d %ddBm]", currentStatus.stat, report.ssri, report.attenuation); + + if (report.ssri < NETWORK_DEFAULT_NO_NETWORK_QUALITY_THRESHOLD) noReliableNetwork++; + else noReliableNetwork = 0; + if (noReliableNetwork > NETWORK_DEFAULT_NO_NETWORK_TRIES) { + NOTICE_MSG("waitForRegistered", "No reliable signal"); + break; //after a while, no network really means no network. Bailing out + } + + mainunit::deepSleep(NETWORK_DEFAULT_INTERMEDIATE_TIMEOUT_MS / 1000); + timeout -= NETWORK_DEFAULT_INTERMEDIATE_TIMEOUT_MS; + + currentStatus = hardware::sim808::device.getNetworkRegistrationStatus(); + report = hardware::sim808::device.getSignalQuality(); + } while (timeout > 1); + + NOTICE_FORMAT("waitForRegistered", "%d, [%d %ddBm]", currentStatus.stat, report.ssri, report.attenuation); + return currentStatus; + } + + bool isAvailable(SIM808_NETWORK_REGISTRATION_STATE state) { + return static_cast(state) & + (static_cast(SIM808_NETWORK_REGISTRATION_STATE::REGISTERED) | static_cast(SIM808_NETWORK_REGISTRATION_STATE::ROAMING)) + != 0; + } + + bool enableGprs() { + return hardware::sim808::device.enableGprs(config::main::value.network.apn); + } + + bool sendSms(const char * msg) { + const char * phoneNumber = config::main::value.contactPhone; + + NOTICE_FORMAT("sendSms", "%s, %s", phoneNumber, msg); + return hardware::sim808::device.sendSms(phoneNumber, msg); + } } \ No newline at end of file diff --git a/src/NetworkPositionsBackup.cpp b/src/NetworkPositionsBackup.cpp index 8961120..b4c9e45 100644 --- a/src/NetworkPositionsBackup.cpp +++ b/src/NetworkPositionsBackup.cpp @@ -1,112 +1,114 @@ -#pragma once - -#include "Config.h" - -#if BACKUP_ENABLE_NETWORK -#include "NetworkPositionsBackup.h" -#include "Debug.h" -#include "Hardware.h" -#include "Network.h" - -#define LOGGER_NAME "Positions::backup::network" -#define BUFFER_SIZE 170 - -namespace positions { - namespace backup { - namespace net { - - uint8_t networkUnavailableInARow = 0; - uint8_t networkUnavailablePostpone = 1; - - bool NetworkPositionsBackup::isBackupNeeded(bool forPrepare) { - config_t *config = &config::main::value; - return (config->network.lastSavedEntry == 0xFFFF && config->lastEntry != 0xFFFF) || - positions::count(config->network.lastSavedEntry) > (config->network.saveThreshold * networkUnavailablePostpone) - (forPrepare ? 1 : 0); - } - - bool NetworkPositionsBackup::appendPosition(PositionEntry &entry) { - char buffer[BUFFER_SIZE]; - snprintf_P(buffer, BUFFER_SIZE, PSTR("%d,%d,%d,%d,%d,%d,%d,%s"), - debug::freeRam(), - hardware::sim808::device.getSignalQuality().attenuation, - entry.metadata.batteryLevel, - entry.metadata.batteryVoltage, - entry.metadata.temperature, - static_cast(entry.metadata.status), - entry.metadata.timeToFix, - entry.position); - - NOTICE_FORMAT("appendPosition", "Sending : %s", buffer); - uint16_t responseCode = hardware::sim808::device.httpPost( - config::main::value.network.url, - F("text/gpstracker"), - buffer, - buffer, - BUFFER_SIZE - ); - - NOTICE_FORMAT("appendPosition", "Response : %d", responseCode); - return responseCode == POSITIONS_CONFIG_NET_DEFAULT_EXPECTED_RESPONSE; - } - - //__attribute__((__optimize__("O2"))) - void NetworkPositionsBackup::appendPositions() { - uint16_t currentEntryIndex = config::main::value.network.lastSavedEntry + 1; - PositionEntry currentEntry; - SIM808RegistrationStatus networkStatus; - - //avoid edge case where if 0, whole set of positions will be sent again - if (!positions::count(config::main::value.network.lastSavedEntry)) return; - - network::powerOn(); - networkStatus = network::waitForRegistered(NETWORK_DEFAULT_TOTAL_TIMEOUT_MS); - - if (!network::isAvailable(networkStatus.stat) || !network::enableGprs()) { - networkUnavailableInARow = min(networkUnavailableInARow + 1, POSITIONS_CONFIG_NET_DEFAULT_UNAVAILABLE_NETWORK_POSTPONE_THRESHOLD + 1); //avoid increment overflow - NOTICE_MSG("appendPositions", "network or gprs unavailable"); - - if (networkUnavailableInARow > POSITIONS_CONFIG_NET_DEFAULT_UNAVAILABLE_NETWORK_POSTPONE_THRESHOLD) { - networkUnavailablePostpone++; - } - } - else { - networkUnavailableInARow = 0; - networkUnavailablePostpone = 1; - - hardware::i2c::powerOn(); - do { - if (!positions::get(currentEntryIndex, currentEntry)) break; - if (!appendPosition(currentEntry)) break; - - config::main::value.network.lastSavedEntry = currentEntryIndex; - config::main::save(); - - } while (positions::moveNext(currentEntryIndex)); - hardware::i2c::powerOff(); - } - - network::powerOff(); - } - - void NetworkPositionsBackup::setup() {} - - void NetworkPositionsBackup::prepare() { - NOTICE("prepare"); - - if (!isBackupNeeded(true)) return; - network::powerOn(); - } - - void NetworkPositionsBackup::backup(bool force) { - NOTICE("backup"); - - if (force || isBackupNeeded(false)) { - appendPositions(); - } - - network::powerOff(); - } - } - } -} +#pragma once + +#include "Config.h" + +#if BACKUP_ENABLE_NETWORK +#include "NetworkPositionsBackup.h" +#include "MainUnit.h" +#include "Hardware.h" +#include "Network.h" +#include "Logging.h" + +#define LOGGER_NAME "Positions::backup::network" + +#define BUFFER_SIZE 170 + +namespace positions { + namespace backup { + namespace net { + + uint8_t networkUnavailableInARow = 0; + uint8_t networkUnavailablePostpone = 1; + + bool NetworkPositionsBackup::isBackupNeeded(bool forPrepare) { + config_t *config = &config::main::value; + return (config->network.lastSavedEntry == 0xFFFF && config->lastEntry != 0xFFFF) || + positions::count(config->network.lastSavedEntry) > (config->network.saveThreshold * networkUnavailablePostpone) - (forPrepare ? 1 : 0); + } + + bool NetworkPositionsBackup::appendPosition(PositionEntry &entry) { + char buffer[BUFFER_SIZE]; + snprintf_P(buffer, BUFFER_SIZE, PSTR("%d,%d,%d,%d,%d,%d,%d,%s"), + mainunit::freeRam(), + hardware::sim808::device.getSignalQuality().attenuation, + entry.metadata.batteryLevel, + entry.metadata.batteryVoltage, + entry.metadata.temperature, + static_cast(entry.metadata.status), + entry.metadata.timeToFix, + entry.position); + + NOTICE_FORMAT("appendPosition", "Sending : %s", buffer); + uint16_t responseCode = hardware::sim808::device.httpPost( + config::main::value.network.url, + F("text/gpstracker"), + buffer, + buffer, + BUFFER_SIZE + ); + + NOTICE_FORMAT("appendPosition", "Response : %d", responseCode); + return responseCode == POSITIONS_CONFIG_NET_DEFAULT_EXPECTED_RESPONSE; + } + + //__attribute__((__optimize__("O2"))) + void NetworkPositionsBackup::appendPositions() { + uint16_t currentEntryIndex = config::main::value.network.lastSavedEntry + 1; + PositionEntry currentEntry; + SIM808RegistrationStatus networkStatus; + + //avoid edge case where if 0, whole set of positions will be sent again + if (!positions::count(config::main::value.network.lastSavedEntry)) return; + + network::powerOn(); + networkStatus = network::waitForRegistered(NETWORK_DEFAULT_TOTAL_TIMEOUT_MS); + + if (!network::isAvailable(networkStatus.stat) || !network::enableGprs()) { + networkUnavailableInARow = min(networkUnavailableInARow + 1, POSITIONS_CONFIG_NET_DEFAULT_UNAVAILABLE_NETWORK_POSTPONE_THRESHOLD + 1); //avoid increment overflow + NOTICE_MSG("appendPositions", "network or gprs unavailable"); + + if (networkUnavailableInARow > POSITIONS_CONFIG_NET_DEFAULT_UNAVAILABLE_NETWORK_POSTPONE_THRESHOLD) { + networkUnavailablePostpone++; + } + } + else { + networkUnavailableInARow = 0; + networkUnavailablePostpone = 1; + + hardware::i2c::powerOn(); + do { + if (!positions::get(currentEntryIndex, currentEntry)) break; + if (!appendPosition(currentEntry)) break; + + config::main::value.network.lastSavedEntry = currentEntryIndex; + config::main::save(); + + } while (positions::moveNext(currentEntryIndex)); + hardware::i2c::powerOff(); + } + + network::powerOff(); + } + + void NetworkPositionsBackup::setup() {} + + void NetworkPositionsBackup::prepare() { + NOTICE("prepare"); + + if (!isBackupNeeded(true)) return; + network::powerOn(); + } + + void NetworkPositionsBackup::backup(bool force) { + NOTICE("backup"); + + if (force || isBackupNeeded(false)) { + appendPositions(); + } + + network::powerOff(); + } + } + } +} #endif \ No newline at end of file diff --git a/src/Positions.cpp b/src/Positions.cpp index d99e6c5..d4c8440 100644 --- a/src/Positions.cpp +++ b/src/Positions.cpp @@ -1,195 +1,196 @@ -#include "Config.h" -#include "Debug.h" -#include "Positions.h" -#include "Gps.h" - -#if BACKUP_ENABLE_SDCARD || BACKUP_ENABLE_NETWORK -#define BACKUPS_ENABLED (BACKUP_ENABLE_SDCARD + BACKUP_ENABLE_NETWORK) -#endif - -#if BACKUP_ENABLE_SDCARD -#include "SdPositionsBackup.h" -#endif - -#if BACKUP_ENABLE_NETWORK -#include "NetworkPositionsBackup.h" -#endif - -#define LOGGER_NAME "Positions" - -#define ENTRY_RESERVED_SIZE 128 -#define ENTRIES_ADDR CONFIG_RESERVED_SIZE - -namespace positions { -#if BACKUPS_ENABLED > 1 - backup::PositionsBackup **_backups; -#elif BACKUPS_ENABLED == 1 - backup::PositionsBackup * _backup; -#endif - - namespace details { - uint16_t maxEntryIndex = 0; - - uint16_t getEntryAddress(uint16_t index) { - if (index > maxEntryIndex) return -1; - return ENTRIES_ADDR + (ENTRY_RESERVED_SIZE * index); - } - } - - void setup() { - details::maxEntryIndex = (E24_MAX_ADDRESS(hardware::i2c::eeprom.getSize()) - ENTRIES_ADDR) / ENTRY_RESERVED_SIZE; - -#if BACKUPS_ENABLED > 0 - backup::PositionsBackup * backup = NULL; -#if BACKUPS_ENABLED > 1 - uint8_t backupIdx = 0; - _backups = new backup::PositionsBackup*[BACKUPS_ENABLED]; -#endif //BACKUPS_ENABLED > 1 - -#if BACKUP_ENABLE_SDCARD - backup = new backup::sd::SdPositionsBackup(); - backup->setup(); -#if BACKUPS_ENABLED > 1 - _backups[backupIdx] = backup; - backupIdx++; -#endif //BACKUPS_ENABLED > 1 -#endif //BACKUP_ENABLE_SDCARD - -#if BACKUP_ENABLE_NETWORK - backup = new backup::net::NetworkPositionsBackup(); - backup->setup(); -#if BACKUPS_ENABLED > 1 - _backups[backupIdx] = backup; - backupIdx++; -#endif //BACKUPS_ENABLED > 1 -#endif //BACKUP_ENABLE_NETWORK - -#if BACKUPS_ENABLED == 1 - _backup = backup; -#endif //BACKUPS_ENABLED == 1 -#endif //BACKUPS_ENABLED > 0 - - } - - bool acquire(PositionEntryMetadata &metadata) { - NOTICE("acquire"); - - timestamp_t before; - - gps::powerOn(); - before = rtc::getTime(); - SIM808_GPS_STATUS gpsStatus = gps::acquireCurrentPosition(GPS_DEFAULT_TOTAL_TIMEOUT_MS); - uint16_t timeToFix = rtc::getTime() - before; - SIM808ChargingStatus battery = hardware::sim808::device.getChargingState(); - gps::powerOff(); - - bool acquired = gpsStatus >= SIM808_GPS_STATUS::FIX; //prety useless wins 14 bytes on the hex size rather than return gpStatus >= ... - NOTICE_FORMAT("acquire", "Status : %d", gpsStatus); - - metadata = { - battery.level, - battery.voltage, - rtc::getTemperature(), - timeToFix, - gpsStatus - }; - - return acquired; - } - - void appendLast(const PositionEntryMetadata &metadata) { - VERBOSE("appendLast"); - - uint16_t entryIndex; - uint16_t entryAddress; - PositionEntry entry = { metadata }; - strlcpy(entry.position, gps::lastPosition, POSITION_SIZE); - - config_t* config = &config::main::value; - entryIndex = config->lastEntry + 1; - - entryAddress = details::getEntryAddress(entryIndex); - - hardware::i2c::powerOn(); - hardware::i2c::eeprom.writeBlock(entryAddress, entry); - - NOTICE_FORMAT("appendLast", "Saved @ %X : %d,%d,%d,%d,%d,%s", - entryAddress, - entry.metadata.batteryLevel, - entry.metadata.batteryVoltage, - entry.metadata.temperature, - static_cast(entry.metadata.status), - entry.metadata.timeToFix, - entry.position); - - config->lastEntry++; - if (config->lastEntry > details::maxEntryIndex) config->lastEntry = 0; - if (config->lastEntry == config->firstEntry) config->firstEntry++; - if (config->firstEntry > details::maxEntryIndex) config->firstEntry = 0; - - config::main::save(); - hardware::i2c::powerOff(); - } - - bool get(uint16_t index, PositionEntry &entry) { - VERBOSE("get"); - - uint16_t entryAddress = details::getEntryAddress(index); - if (entryAddress == -1) return false; - - VERBOSE_FORMAT("get", "Reading entry %d @ %X", index, entryAddress); - - hardware::i2c::powerOn(); - hardware::i2c::eeprom.readBlock(entryAddress, entry); - hardware::i2c::powerOff(); - - NOTICE_FORMAT("get", "Read from EEPROM @ %X : %d,%d,%d,%d,%d,%s", - entryAddress, - entry.metadata.batteryLevel, - entry.metadata.batteryVoltage, - entry.metadata.temperature, - static_cast(entry.metadata.status), - entry.metadata.timeToFix, - entry.position); - - return true; - } - - bool moveNext(uint16_t &index) { - if (index == config::main::value.lastEntry) return false; - - if (index == details::maxEntryIndex) index = 0; //could use a modulo but easier to understand that way - else index++; - - return true; - } - - uint16_t count(uint16_t fromIndex) { - config_t *config = &config::main::value; - uint16_t lastEntry = config->lastEntry; - - if (lastEntry < fromIndex) { lastEntry += details::maxEntryIndex; } - - return lastEntry - fromIndex; - } - - void prepareBackup() { -#if BACKUPS_ENABLED > 1 - for (int i = 0; i < BACKUPS_ENABLED; i++) { - _backups[i]->prepare(); - } -#elif BACKUPS_ENABLED == 1 - _backup->prepare(); -#endif - } - - void doBackup(bool force) { -#if BACKUPS_ENABLED > 1 - for (int i = 0; i < BACKUPS_ENABLED; i++) { - _backups[i]->backup(force); - } -#elif BACKUPS_ENABLED == 1 - _backup->backup(force); -#endif - } +#include "Config.h" +#include "Positions.h" +#include "Gps.h" +#include "Rtc.h" +#include "Logging.h" + +#if BACKUP_ENABLE_SDCARD || BACKUP_ENABLE_NETWORK +#define BACKUPS_ENABLED (BACKUP_ENABLE_SDCARD + BACKUP_ENABLE_NETWORK) +#endif + +#if BACKUP_ENABLE_SDCARD +#include "SdPositionsBackup.h" +#endif + +#if BACKUP_ENABLE_NETWORK +#include "NetworkPositionsBackup.h" +#endif + +#define LOGGER_NAME "Positions" + +#define ENTRY_RESERVED_SIZE 128 +#define ENTRIES_ADDR CONFIG_RESERVED_SIZE + +namespace positions { +#if BACKUPS_ENABLED > 1 + backup::PositionsBackup **_backups; +#elif BACKUPS_ENABLED == 1 + backup::PositionsBackup * _backup; +#endif + + namespace details { + uint16_t maxEntryIndex = 0; + + uint16_t getEntryAddress(uint16_t index) { + if (index > maxEntryIndex) return -1; + return ENTRIES_ADDR + (ENTRY_RESERVED_SIZE * index); + } + } + + void setup() { + details::maxEntryIndex = (E24_MAX_ADDRESS(hardware::i2c::eeprom.getSize()) - ENTRIES_ADDR) / ENTRY_RESERVED_SIZE; + +#if BACKUPS_ENABLED > 0 + backup::PositionsBackup * backup = NULL; +#if BACKUPS_ENABLED > 1 + uint8_t backupIdx = 0; + _backups = new backup::PositionsBackup*[BACKUPS_ENABLED]; +#endif //BACKUPS_ENABLED > 1 + +#if BACKUP_ENABLE_SDCARD + backup = new backup::sd::SdPositionsBackup(); + backup->setup(); +#if BACKUPS_ENABLED > 1 + _backups[backupIdx] = backup; + backupIdx++; +#endif //BACKUPS_ENABLED > 1 +#endif //BACKUP_ENABLE_SDCARD + +#if BACKUP_ENABLE_NETWORK + backup = new backup::net::NetworkPositionsBackup(); + backup->setup(); +#if BACKUPS_ENABLED > 1 + _backups[backupIdx] = backup; + backupIdx++; +#endif //BACKUPS_ENABLED > 1 +#endif //BACKUP_ENABLE_NETWORK + +#if BACKUPS_ENABLED == 1 + _backup = backup; +#endif //BACKUPS_ENABLED == 1 +#endif //BACKUPS_ENABLED > 0 + + } + + bool acquire(PositionEntryMetadata &metadata) { + NOTICE("acquire"); + + timestamp_t before; + + gps::powerOn(); + before = rtc::getTime(); + SIM808_GPS_STATUS gpsStatus = gps::acquireCurrentPosition(GPS_DEFAULT_TOTAL_TIMEOUT_MS); + uint16_t timeToFix = rtc::getTime() - before; + SIM808ChargingStatus battery = hardware::sim808::device.getChargingState(); + gps::powerOff(); + + bool acquired = gpsStatus >= SIM808_GPS_STATUS::FIX; //prety useless wins 14 bytes on the hex size rather than return gpStatus >= ... + NOTICE_FORMAT("acquire", "Status : %d", gpsStatus); + + metadata = { + battery.level, + battery.voltage, + rtc::getTemperature(), + timeToFix, + gpsStatus + }; + + return acquired; + } + + void appendLast(const PositionEntryMetadata &metadata) { + VERBOSE("appendLast"); + + uint16_t entryIndex; + uint16_t entryAddress; + PositionEntry entry = { metadata }; + strlcpy(entry.position, gps::lastPosition, POSITION_SIZE); + + config_t* config = &config::main::value; + entryIndex = config->lastEntry + 1; + + entryAddress = details::getEntryAddress(entryIndex); + + hardware::i2c::powerOn(); + hardware::i2c::eeprom.writeBlock(entryAddress, entry); + + NOTICE_FORMAT("appendLast", "Saved @ %X : %d,%d,%d,%d,%d,%s", + entryAddress, + entry.metadata.batteryLevel, + entry.metadata.batteryVoltage, + entry.metadata.temperature, + static_cast(entry.metadata.status), + entry.metadata.timeToFix, + entry.position); + + config->lastEntry++; + if (config->lastEntry > details::maxEntryIndex) config->lastEntry = 0; + if (config->lastEntry == config->firstEntry) config->firstEntry++; + if (config->firstEntry > details::maxEntryIndex) config->firstEntry = 0; + + config::main::save(); + hardware::i2c::powerOff(); + } + + bool get(uint16_t index, PositionEntry &entry) { + VERBOSE("get"); + + uint16_t entryAddress = details::getEntryAddress(index); + if (entryAddress == -1) return false; + + VERBOSE_FORMAT("get", "Reading entry %d @ %X", index, entryAddress); + + hardware::i2c::powerOn(); + hardware::i2c::eeprom.readBlock(entryAddress, entry); + hardware::i2c::powerOff(); + + NOTICE_FORMAT("get", "Read from EEPROM @ %X : %d,%d,%d,%d,%d,%s", + entryAddress, + entry.metadata.batteryLevel, + entry.metadata.batteryVoltage, + entry.metadata.temperature, + static_cast(entry.metadata.status), + entry.metadata.timeToFix, + entry.position); + + return true; + } + + bool moveNext(uint16_t &index) { + if (index == config::main::value.lastEntry) return false; + + if (index == details::maxEntryIndex) index = 0; //could use a modulo but easier to understand that way + else index++; + + return true; + } + + uint16_t count(uint16_t fromIndex) { + config_t *config = &config::main::value; + uint16_t lastEntry = config->lastEntry; + + if (lastEntry < fromIndex) { lastEntry += details::maxEntryIndex; } + + return lastEntry - fromIndex; + } + + void prepareBackup() { +#if BACKUPS_ENABLED > 1 + for (int i = 0; i < BACKUPS_ENABLED; i++) { + _backups[i]->prepare(); + } +#elif BACKUPS_ENABLED == 1 + _backup->prepare(); +#endif + } + + void doBackup(bool force) { +#if BACKUPS_ENABLED > 1 + for (int i = 0; i < BACKUPS_ENABLED; i++) { + _backups[i]->backup(force); + } +#elif BACKUPS_ENABLED == 1 + _backup->backup(force); +#endif + } } \ No newline at end of file diff --git a/src/Rtc.cpp b/src/Rtc.cpp index b02fdd5..60ed2e3 100644 --- a/src/Rtc.cpp +++ b/src/Rtc.cpp @@ -1,7 +1,7 @@ -#include "Debug.h" - #include "Rtc.h" -#include "config/Pins.h" +#include "config/Hardware.h" +#include "Hardware.h" +#include "Logging.h" #include #include diff --git a/src/SdCard.cpp b/src/SdCard.cpp index 88f6aa8..c69eea7 100644 --- a/src/SdCard.cpp +++ b/src/SdCard.cpp @@ -2,7 +2,7 @@ #if BACKUP_ENABLE_SDCARD #include "SdCard.h" -#include "config/Pins.h" +#include "config/Hardware.h" namespace hardware { namespace sdcard { diff --git a/src/SdPositionsBackup.cpp b/src/SdPositionsBackup.cpp index 7e543e8..fceeee9 100644 --- a/src/SdPositionsBackup.cpp +++ b/src/SdPositionsBackup.cpp @@ -1,119 +1,119 @@ -#include "SdPositionsBackup.h" -#include "SdPositionsConfig.h" -#include "SdCard.h" -#include "Hardware.h" -#include "Config.h" -#include "Positions.h" -#include "Debug.h" - -#define LOGGER_NAME "Positions::backup::sd" - -#if BACKUP_ENABLE_SDCARD -namespace positions { - namespace backup { - namespace sd { - - namespace details { - - bool isBackupNeeded(SdPositionConfig_t &sdConfig) { - Config_t referenceConfig = config::main::value; - sdConfig = config::backup::sd::get(); - - return sdConfig.lastSavedEntry == 0xFFFF || - positions::count(sdConfig.lastSavedEntry) > sdConfig.saveThreshold; - } - - void getPositionsFileName(uint16_t fileIndex, char *buffer) { - sprintf(buffer, POSITIONS_FILENAME, fileIndex); - } - - void ensurePositionsFolder() { - char positionsFolder[] = POSITIONS_FOLDER; - - hardware::sdcard::filesystem.chdir(); - if (!hardware::sdcard::filesystem.exists(positionsFolder)) { - hardware::sdcard::filesystem.mkdir(positionsFolder, true); - } - - hardware::sdcard::filesystem.chdir(positionsFolder); - } - - void selectFile(SdPositionConfig_t &sdConfig, File &file) { - char positionFileName[POSITIONS_FILENAME_LENGTH]; - - if (sdConfig.fileRecords >= sdConfig.maxRecordsPerFile) { - if (file.isOpen()) { - file.close(); - config::backup::sd::set(sdConfig); - } - - sdConfig.fileIndex++; - sdConfig.filePosition = 0; - sdConfig.fileRecords = 0; - } - - if (!file.isOpen()) { - ensurePositionsFolder(); - getPositionsFileName(sdConfig.fileIndex, positionFileName); - file.open(positionFileName, O_RDWR | O_CREAT); - } - } - - void appendPosition(File &file, SdPositionConfig_t &sdConfig, PositionEntry &entry) { - VERBOSE("appendPosition"); - - const char fieldTerminator = ','; - - file.printField(entry.metadata.batteryLevel, fieldTerminator); - file.printField(entry.metadata.batteryVoltage, fieldTerminator); - file.printField(entry.metadata.temperature, fieldTerminator); - file.printField(entry.metadata.timeToFix, fieldTerminator); - file.printField(static_cast(entry.metadata.status), fieldTerminator); - file.println(entry.position); - - sdConfig.filePosition = file.position(); - } - - void appendPositions(SdPositionConfig_t &sdConfig) { - VERBOSE("appendPositions"); - - uint16_t currentEntryIndex = sdConfig.lastSavedEntry + 1; - PositionEntry currentEntry; - File file; - - hardware::i2c::powerOn(); - do { - if (!positions::get(currentEntryIndex, currentEntry)) break; - selectFile(sdConfig, file); - appendPosition(file, sdConfig, currentEntry); - sdConfig.lastSavedEntry = currentEntryIndex; - } while (positions::moveNext(currentEntryIndex)); - hardware::i2c::powerOff(); - - if (file.isOpen()) file.close(); - config::backup::sd::set(sdConfig); - } - } - - void SdPositionsBackup::setup() { - hardware::sdcard::setup(); - } - - void SdPositionsBackup::backup(bool force) { - VERBOSE("backup"); - - if (!hardware::sdcard::available) { - VERBOSE_MSG("backup", "not available"); - return; - } - - SdPositionConfig_t sdConfig; - - if (!details::isBackupNeeded(sdConfig)) return; - details::appendPositions(sdConfig); - } - - } - } -} +#include "SdPositionsBackup.h" +#include "SdPositionsConfig.h" +#include "SdCard.h" +#include "Hardware.h" +#include "Config.h" +#include "Positions.h" +#include "Logging.h" + +#define LOGGER_NAME "Positions::backup::sd" + +#if BACKUP_ENABLE_SDCARD +namespace positions { + namespace backup { + namespace sd { + + namespace details { + + bool isBackupNeeded(SdPositionConfig_t &sdConfig) { + Config_t referenceConfig = config::main::value; + sdConfig = config::backup::sd::get(); + + return sdConfig.lastSavedEntry == 0xFFFF || + positions::count(sdConfig.lastSavedEntry) > sdConfig.saveThreshold; + } + + void getPositionsFileName(uint16_t fileIndex, char *buffer) { + sprintf(buffer, POSITIONS_FILENAME, fileIndex); + } + + void ensurePositionsFolder() { + char positionsFolder[] = POSITIONS_FOLDER; + + hardware::sdcard::filesystem.chdir(); + if (!hardware::sdcard::filesystem.exists(positionsFolder)) { + hardware::sdcard::filesystem.mkdir(positionsFolder, true); + } + + hardware::sdcard::filesystem.chdir(positionsFolder); + } + + void selectFile(SdPositionConfig_t &sdConfig, File &file) { + char positionFileName[POSITIONS_FILENAME_LENGTH]; + + if (sdConfig.fileRecords >= sdConfig.maxRecordsPerFile) { + if (file.isOpen()) { + file.close(); + config::backup::sd::set(sdConfig); + } + + sdConfig.fileIndex++; + sdConfig.filePosition = 0; + sdConfig.fileRecords = 0; + } + + if (!file.isOpen()) { + ensurePositionsFolder(); + getPositionsFileName(sdConfig.fileIndex, positionFileName); + file.open(positionFileName, O_RDWR | O_CREAT); + } + } + + void appendPosition(File &file, SdPositionConfig_t &sdConfig, PositionEntry &entry) { + VERBOSE("appendPosition"); + + const char fieldTerminator = ','; + + file.printField(entry.metadata.batteryLevel, fieldTerminator); + file.printField(entry.metadata.batteryVoltage, fieldTerminator); + file.printField(entry.metadata.temperature, fieldTerminator); + file.printField(entry.metadata.timeToFix, fieldTerminator); + file.printField(static_cast(entry.metadata.status), fieldTerminator); + file.println(entry.position); + + sdConfig.filePosition = file.position(); + } + + void appendPositions(SdPositionConfig_t &sdConfig) { + VERBOSE("appendPositions"); + + uint16_t currentEntryIndex = sdConfig.lastSavedEntry + 1; + PositionEntry currentEntry; + File file; + + hardware::i2c::powerOn(); + do { + if (!positions::get(currentEntryIndex, currentEntry)) break; + selectFile(sdConfig, file); + appendPosition(file, sdConfig, currentEntry); + sdConfig.lastSavedEntry = currentEntryIndex; + } while (positions::moveNext(currentEntryIndex)); + hardware::i2c::powerOff(); + + if (file.isOpen()) file.close(); + config::backup::sd::set(sdConfig); + } + } + + void SdPositionsBackup::setup() { + hardware::sdcard::setup(); + } + + void SdPositionsBackup::backup(bool force) { + VERBOSE("backup"); + + if (!hardware::sdcard::available) { + VERBOSE_MSG("backup", "not available"); + return; + } + + SdPositionConfig_t sdConfig; + + if (!details::isBackupNeeded(sdConfig)) return; + details::appendPositions(sdConfig); + } + + } + } +} #endif \ No newline at end of file diff --git a/src/SdPositionsConfig.cpp b/src/SdPositionsConfig.cpp index d963f36..29a0550 100644 --- a/src/SdPositionsConfig.cpp +++ b/src/SdPositionsConfig.cpp @@ -1,71 +1,71 @@ -#include "SdPositionsConfig.h" -#include "SdCard.h" -#include "Debug.h" - -#define LOGGER_NAME "Config::backup::sd" - -#if BACKUP_ENABLE_SDCARD -namespace config { - namespace backup { - namespace sd { - - SdPositionConfig_t value; - File configFile; - - namespace details { - - void ensureOpened() { - if (!configFile.isOpen()) { - hardware::sdcard::filesystem.chdir(); - configFile.open(POSITIONS_CONFIG_FILENAME, O_RDWR | O_CREAT); - } - - configFile.rewind(); - } - - void read() { - VERBOSE("read"); - ensureOpened(); - configFile.read((void*)&value, sizeof(value)); - if (value.seed != POSITIONS_CONFIG_SEED) reset(); - } - - void write() { - VERBOSE("write"); - ensureOpened(); - configFile.write((void*)&value, sizeof(value)); - } - - } - - SdPositionConfig_t get() { - if (value.seed != POSITIONS_CONFIG_SEED) details::read(); - - return value; - } - - void set(SdPositionConfig_t config) { - value = config; - details::write(); - } - - void reset() { - VERBOSE("reset"); - SdPositionConfig_t config = { - POSITIONS_CONFIG_SEED, - POSITIONS_CONFIG_DEFAULT_SAVE_THRESHOLD, - POSITIONS_CONFIG_DEFAULT_MAX_RECORDS_PER_FILE, - 0xFFFF, - 0, - 0, - 0 - }; - - value = config; - details::write(); - } - - } - } -} +#include "SdPositionsConfig.h" +#include "SdCard.h" +#include "Logging.h" + +#define LOGGER_NAME "Config::backup::sd" + +#if BACKUP_ENABLE_SDCARD +namespace config { + namespace backup { + namespace sd { + + SdPositionConfig_t value; + File configFile; + + namespace details { + + void ensureOpened() { + if (!configFile.isOpen()) { + hardware::sdcard::filesystem.chdir(); + configFile.open(POSITIONS_CONFIG_FILENAME, O_RDWR | O_CREAT); + } + + configFile.rewind(); + } + + void read() { + VERBOSE("read"); + ensureOpened(); + configFile.read((void*)&value, sizeof(value)); + if (value.seed != POSITIONS_CONFIG_SEED) reset(); + } + + void write() { + VERBOSE("write"); + ensureOpened(); + configFile.write((void*)&value, sizeof(value)); + } + + } + + SdPositionConfig_t get() { + if (value.seed != POSITIONS_CONFIG_SEED) details::read(); + + return value; + } + + void set(SdPositionConfig_t config) { + value = config; + details::write(); + } + + void reset() { + VERBOSE("reset"); + SdPositionConfig_t config = { + POSITIONS_CONFIG_SEED, + POSITIONS_CONFIG_DEFAULT_SAVE_THRESHOLD, + POSITIONS_CONFIG_DEFAULT_MAX_RECORDS_PER_FILE, + 0xFFFF, + 0, + 0, + 0 + }; + + value = config; + details::write(); + } + + } + } +} #endif \ No newline at end of file diff --git a/src/config/Pins.h b/src/config/Hardware.h similarity index 54% rename from src/config/Pins.h rename to src/config/Hardware.h index fe61a5f..0a3cf3c 100644 --- a/src/config/Pins.h +++ b/src/config/Hardware.h @@ -3,6 +3,9 @@ */ #pragma once +#include +#include + #define SIM_RST 5 ///< SIM808 RESET #define SIM_RX 6 ///< SIM808 RXD #define SIM_TX 7 ///< SIM808 TXD @@ -14,3 +17,8 @@ #define SIM_RI 2 ///< Interrupt pin connected to SIM RI. #define RTC_WAKE 3 ///< Interrupt pin connected to DS3231 !INT/SQW + + +#define E24_ADDRESS E24_DEFAULT_ADDR ///< I2C address of the 24xxx chip +#define SIM_SERIAL_TYPE SoftwareSerial ///< Type of variable that holds the Serial communication with SIM808 +#define SIM_SERIAL SIM_SERIAL_TYPE(SIM_TX, SIM_RX) ///< Definition of the instance that holds the Serial communication with SIM808 \ No newline at end of file diff --git a/src/config/System.h b/src/config/System.h index 813afb5..8198a33 100644 --- a/src/config/System.h +++ b/src/config/System.h @@ -34,4 +34,10 @@ When hooked up on Serial port, determine how much milliseconds to wait for a user input before proceeding. */ -#define MENU_TIMEOUT 20000 \ No newline at end of file +#if _DEBUG +#define MENU_TIMEOUT 0 +#else +#define MENU_TIMEOUT 20000 +#endif + +#define MENU_INTERMEDIATE_TIMEOUT 50 \ No newline at end of file