diff --git a/GpsTracker/Config.cpp b/GpsTracker/Config.cpp new file mode 100644 index 0000000..3c165ff --- /dev/null +++ b/GpsTracker/Config.cpp @@ -0,0 +1,37 @@ +#include "Config.h" +#include "Debug.h" +#include "Hardware.h" + +#define LOGGER_NAME "Config" + +namespace config { + Config value; + + void write() { + VERBOSE("writeConfig"); + hardware::i2c::eeprom.writeBlock(CONFIG_ADDR, value); + + VERBOSE_FORMAT("writeConfig", "%s, %s, %d, %d", value.seed, value.version, value.firstEntry, value.lastEntry); + } + + void reset() { + VERBOSE("resetConfig"); + Config config = { + CONFIG_SEED, + VERSION, + 0, + 0 + }; + + value = config; + write(); + } + + void read() { + VERBOSE("readConfig"); + hardware::i2c::eeprom.readBlock(CONFIG_ADDR, value); + if (!String(CONFIG_SEED).equals(value.seed)) reset(); + + VERBOSE_FORMAT("readConfig", "%s, %s, %d, %d", value.seed, value.version, value.firstEntry, value.lastEntry); + } +} \ No newline at end of file diff --git a/GpsTracker/Config.h b/GpsTracker/Config.h index 732b080..d59c858 100644 --- a/GpsTracker/Config.h +++ b/GpsTracker/Config.h @@ -1,10 +1,23 @@ #pragma once +#include + struct sleepTimings_t { uint8_t speed; uint16_t seconds; }; +struct Config { + char seed[5]; + char version[7]; + uint16_t firstEntry; + uint16_t lastEntry; +}; + +#define CONFIG_ADDR 0 +#define CONFIG_SEED "UIYA" +#define VERSION "1.00" + #define SLEEP_DEFAULT_TIME_SECONDS 1800 #define GPS_DEFAULT_INTERMEDIATE_TIMEOUT_MS 10000 @@ -12,6 +25,8 @@ struct sleepTimings_t { namespace config { + extern Config value; + static const sleepTimings_t defaultSleepTimings[] PROGMEM = { { 5, SLEEP_DEFAULT_TIME_SECONDS }, { 10, 1200 }, @@ -23,4 +38,7 @@ namespace config { { 180, 180 }, }; + void read(); + void write(); + } \ No newline at end of file diff --git a/GpsTracker/Core.cpp b/GpsTracker/Core.cpp index f3ab001..2677db5 100644 --- a/GpsTracker/Core.cpp +++ b/GpsTracker/Core.cpp @@ -10,6 +10,7 @@ namespace core { void main() { gps::powerOn(); SIM808_GPS_STATUS gpsStatus = gps::acquireCurrentPosition(GPS_DEFAULT_TOTAL_TIMEOUT_MS); + SIM808ChargingStatus battery = hardware::sim808::device.getChargingState(); gps::powerOff(); if (gpsStatus > SIM808_GPS_STATUS::NO_FIX) { @@ -19,7 +20,7 @@ namespace core { rtc::setTime(time); rtc::powerOff(); - positions::appendLast(); + positions::appendLast(battery, gpsStatus); uint8_t velocity; gps::getVelocity(velocity); diff --git a/GpsTracker/Debug.cpp b/GpsTracker/Debug.cpp index dac94fb..95dcffa 100644 --- a/GpsTracker/Debug.cpp +++ b/GpsTracker/Debug.cpp @@ -1,23 +1,27 @@ #include "Debug.h" #include "Flash.h" +#include "Positions.h" #define MENU_ENTRY(name, text) const char MENU_##name[] PROGMEM = text MENU_ENTRY(HEADER, "-- Debug Menu --"); MENU_ENTRY(SEPARATOR, "----"); -MENU_ENTRY(RUN, "[0] Run"); -MENU_ENTRY(RUN_ONCE, "[1] Run once"); -MENU_ENTRY(RAM, "[2] Read battery"); -MENU_ENTRY(READ_BATTERY, "[3] Read battery"); -MENU_ENTRY(GPS_ON, "[4] GPS On"); -MENU_ENTRY(GPS_OFF, "[5] GPS Off"); -MENU_ENTRY(GPS_GET, "[6] Get GPS position"); -MENU_ENTRY(RTC_ON, "[7] RTC On"); -MENU_ENTRY(RTC_OFF, "[8] RTC Off"); -MENU_ENTRY(RTC_SET, "[9] Get RTC time"); -MENU_ENTRY(RTC_GET, "[10] Set RTC time"); -MENU_ENTRY(QUESTION, "?"); +MENU_ENTRY(RUN, "[0] Run"); +MENU_ENTRY(RUN_ONCE, "[1] Run once"); +MENU_ENTRY(RAM, "[2] Read battery"); +MENU_ENTRY(READ_BATTERY, "[3] Read battery"); +MENU_ENTRY(GPS_ON, "[4] GPS On"); +MENU_ENTRY(GPS_OFF, "[5] GPS Off"); +MENU_ENTRY(GPS_GET, "[6] Get GPS position"); +MENU_ENTRY(RTC_ON, "[7] RTC On"); +MENU_ENTRY(RTC_OFF, "[8] RTC Off"); +MENU_ENTRY(RTC_SET, "[9] Get RTC time"); +MENU_ENTRY(RTC_GET, "[10] Set RTC time"); +MENU_ENTRY(SD_WRITE_TEST "[11] Write to test file"); +MENU_ENTRY(EEPROM_GET_CONFIG, "[16] Get EEPROM config"); +MENU_ENTRY(EEPROM_GET_ENTRIES, "[17] Get EEPROM entries"); +MENU_ENTRY(QUESTION, "?"); const char * const MENU_ENTRIES[] PROGMEM = { MENU_HEADER, @@ -47,7 +51,7 @@ const char * const MENU_ENTRIES[] PROGMEM = { }; -int freeRam2() { +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); @@ -90,7 +94,7 @@ namespace debug { void getAndDisplayBattery() { SIM808ChargingStatus status = hardware::sim808::device.getChargingState(); - Log.notice("%d %d%% %dmV", status.state, status.level, status.voltage); + Log.notice(F("%d %d%% %dmV"), status.state, status.level, status.voltage); } void getAndDisplayRtcTime() { @@ -100,6 +104,27 @@ namespace debug { Log.notice(F("%d/%d/%d %d:%d:%d"), time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second); } + void getAndDisplayEepromConfig() { + hardware::i2c::eepromPowerOn(); + config::read(); + hardware::i2c::eepromPowerOff(); + + Log.notice(F("%s, %s, %d, %d"), config::value.seed, config::value.version, config::value.firstEntry, config::value.lastEntry); + } + + void getAndDisplayEepromPositions() { + uint16_t firstEntryIndex = config::value.firstEntry; + uint16_t currentEntryIndex = firstEntryIndex; + PositionEntry currentEntry; + + do { + positions::get(currentEntryIndex, currentEntry); + Log.notice(F("%d%%, %dmV, %d, %s"), currentEntry.battery.level, currentEntry.battery.voltage, currentEntry.status, currentEntry.position); + + } while (currentEntryIndex != config::value.lastEntry); + + } + void setRtcTime() { tmElements_t time; gps::getTime(time); diff --git a/GpsTracker/Debug.h b/GpsTracker/Debug.h index b79892e..a736f3a 100644 --- a/GpsTracker/Debug.h +++ b/GpsTracker/Debug.h @@ -39,7 +39,10 @@ namespace debug { RTC_ON = 7, RTC_OFF = 8, RTC_GET = 9, - RTC_SET = 10 + RTC_SET = 10, + SD_WRITE_TEST = 11, + EEPROM_GET_CONFIG = 16, + EEPROM_GET_ENTRIES = 17 }; void waitForSerial(); @@ -52,6 +55,10 @@ namespace debug { void getAndDisplayRtcTime(); void setRtcTime(); + + void getAndDisplayEepromConfig(); + void getAndDisplayEepromPositions(); + inline void displayFreeRam() { Serial.println(freeRam()); } } diff --git a/GpsTracker/GpsTracker.ino b/GpsTracker/GpsTracker.ino index ef7e97d..289b62a 100644 --- a/GpsTracker/GpsTracker.ino +++ b/GpsTracker/GpsTracker.ino @@ -52,6 +52,14 @@ void loop() { 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_GET_ENTRIES: + debug::getAndDisplayEepromPositions(); + break; + case debug::GPSTRACKER_DEBUG_COMMAND::SD_WRITE_TEST: default: Serial.println(F("Unsupported command !")); } diff --git a/GpsTracker/Hardware.cpp b/GpsTracker/Hardware.cpp index 44e0f56..3527d4c 100644 --- a/GpsTracker/Hardware.cpp +++ b/GpsTracker/Hardware.cpp @@ -6,7 +6,8 @@ #include #include - +#include + namespace hardware { namespace sim808 { @@ -70,8 +71,12 @@ namespace hardware { #define DEVICE_RTC 1 #define DEVICE_EEPROM 2 + E24 eeprom = E24(E24Size_t::E24_512K); + uint8_t powered = 0; + //inline void powered() { digitalRead(I2C_PWR) == HIGH; } //TODO = replace enum with just reading the output pin ? + void powerOn() { if (powered > 0) return; diff --git a/GpsTracker/Hardware.h b/GpsTracker/Hardware.h index 26c6bd0..2b322d4 100644 --- a/GpsTracker/Hardware.h +++ b/GpsTracker/Hardware.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace hardware { @@ -20,6 +21,8 @@ namespace hardware { } namespace i2c { + extern E24 eeprom; + void powerOn(); void powerOff(); diff --git a/GpsTracker/MainUnit.cpp b/GpsTracker/MainUnit.cpp index da7e796..4750691 100644 --- a/GpsTracker/MainUnit.cpp +++ b/GpsTracker/MainUnit.cpp @@ -1,6 +1,9 @@ #include "MainUnit.h" #include "Rtc.h" #include "Pins.h" +#include "Debug.h" + +const char WOKE_UP[] PROGMEM = "Woke up from sleep"; namespace mainunit { @@ -18,11 +21,20 @@ namespace mainunit { } void sleep(period_t period) { + Log.verbose(F("Sleeping for period : %d"), period); + LowPower.powerDown(period, ADC_OFF, BOD_OFF); + + Log.verbose(reinterpret_cast(pgm_read_word(WOKE_UP))); + } void deepSleep(uint16_t seconds) { + Log.verbose(F("Deep sleeping for %d seconds"), seconds); + interruptIn(seconds); LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); + + Log.verbose(reinterpret_cast(pgm_read_word(WOKE_UP))); } } \ No newline at end of file diff --git a/GpsTracker/Positions.cpp b/GpsTracker/Positions.cpp index 840e302..272fe51 100644 --- a/GpsTracker/Positions.cpp +++ b/GpsTracker/Positions.cpp @@ -1,15 +1,70 @@ #include "Positions.h" +#include "Debug.h" +#include "Config.h" #include "Gps.h" #include "Network.h" #include "Storage.h" #define LOGGER_NAME "Positions" +#define ENTRY_RESERVED_SIZE 128 +#define ENTRIES_ADDR ENTRY_RESERVED_SIZE + namespace positions { - void appendLast() { - //write gps::lastPosition to eeprom and eventually to sd card + uint16_t getEntryAddress(uint16_t &index) { + uint16_t address = ENTRIES_ADDR + (ENTRY_RESERVED_SIZE * index); + if (address + ENTRY_RESERVED_SIZE > E24_MAX_ADDRESS(hardware::i2c::eeprom.getSize())) { + address = ENTRIES_ADDR; + index = 0; + } + + return address; + } + + void setEntriesIndexes(uint16_t lastEntry) { + uint16_t firstEntry = config::value.firstEntry; + + while (config::value.lastEntry < config::value.firstEntry) { + config::value.firstEntry++; + getEntryAddress(firstEntry); + } + + config::value.lastEntry = lastEntry; + config::value.firstEntry = firstEntry; + } + + void appendLast(const SIM808ChargingStatus battery, const SIM808_GPS_STATUS gpsStatus) { + VERBOSE("appendLast"); + + uint16_t entryIndex; + uint16_t entryAddress; + + PositionEntry entry = { battery, gpsStatus }; + strncpy(entry.position, gps::lastPosition, POSITION_SIZE); + + storage::powerOn(); + config::read(); + entryIndex = config::value.lastEntry + 1; + entryAddress = getEntryAddress(entryIndex); + bool success = hardware::i2c::eeprom.writeBlock(entryAddress, entry); + + if (success) { + VERBOSE_MSG("appendLast", "written to EEPROM"); + setEntriesIndexes(entryIndex); + config::write(); + } + + storage::powerOff(); + } + + void get(uint16_t &index, PositionEntry &entry) { + uint16_t entryAddress = getEntryAddress(index); + + storage::powerOn(); + hardware::i2c::eeprom.readBlock(entryAddress, entry); + storage::powerOff(); } bool needsToSend() { diff --git a/GpsTracker/Positions.h b/GpsTracker/Positions.h index d68680c..58b3f52 100644 --- a/GpsTracker/Positions.h +++ b/GpsTracker/Positions.h @@ -1,7 +1,19 @@ #pragma once +#include + +#define POSITION_SIZE 115 + +struct PositionEntry { + SIM808ChargingStatus battery; //sizeof = 4 + SIM808_GPS_STATUS status; //sizeof = 1 + char position[POSITION_SIZE]; //sizeof = 115 +}; //sizeof = 119 + namespace positions { - void appendLast(); + void appendLast(const SIM808ChargingStatus battery, const SIM808_GPS_STATUS gpsStatus); + + void get(uint16_t &index, PositionEntry &entry); bool needsToSend(); void send(); diff --git a/GpsTracker/Rtc.h b/GpsTracker/Rtc.h index 74fe803..66539c6 100644 --- a/GpsTracker/Rtc.h +++ b/GpsTracker/Rtc.h @@ -20,7 +20,7 @@ namespace rtc { inline void setAlarm(uint16_t seconds) { tmElements_t time; getTime(time); - setAlarm(makeTime(time) + seconds); //TODO : use operator + setAlarm(makeTime(time) + seconds); } void setAlarm(tmElements_t &time); diff --git a/GpsTracker/Storage.h b/GpsTracker/Storage.h index 982ab33..db80633 100644 --- a/GpsTracker/Storage.h +++ b/GpsTracker/Storage.h @@ -10,4 +10,6 @@ namespace storage { inline void powerOff() { hardware::i2c::eepromPowerOff(); } + + } \ No newline at end of file