@@ -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); | |||
} | |||
} |
@@ -1,10 +1,23 @@ | |||
#pragma once | |||
#include <Arduino.h> | |||
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(); | |||
} |
@@ -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); | |||
@@ -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); | |||
@@ -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()); } | |||
} |
@@ -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 !")); | |||
} | |||
@@ -6,7 +6,8 @@ | |||
#include <SIM808_Types.h> | |||
#include <Wire.h> | |||
#include <E24.h> | |||
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; | |||
@@ -1,6 +1,7 @@ | |||
#pragma once | |||
#include <SIM808.h> | |||
#include <E24.h> | |||
namespace hardware { | |||
@@ -20,6 +21,8 @@ namespace hardware { | |||
} | |||
namespace i2c { | |||
extern E24 eeprom; | |||
void powerOn(); | |||
void powerOff(); | |||
@@ -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<const __FlashStringHelper *>(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<const __FlashStringHelper *>(pgm_read_word(WOKE_UP))); | |||
} | |||
} |
@@ -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() { | |||
@@ -1,7 +1,19 @@ | |||
#pragma once | |||
#include <SIM808_Types.h> | |||
#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(); |
@@ -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); |
@@ -10,4 +10,6 @@ namespace storage { | |||
inline void powerOff() { | |||
hardware::i2c::eepromPowerOff(); | |||
} | |||
} |