merged v2.0.17
This commit is contained in:
commit
21d94247bd
9 files changed
+240
-78
No files matched your search
+69
-29
@@ -16,16 +16,22 @@ static const char TAG[] = __FILE__;
|
||||
|
||||
Preferences nvram;
|
||||
|
||||
static const char cfgMagicBytes[] = {0x21, 0x76, 0x87, 0x32, 0xf3};
|
||||
static const uint8_t cfgMagicBytes[] = {0x21, 0x76, 0x87, 0x32, 0xf4};
|
||||
static const size_t cfgLen = sizeof(cfg), cfgLen2 = sizeof(cfgMagicBytes);
|
||||
static char buffer[cfgLen + cfgLen2];
|
||||
static uint8_t buffer[cfgLen + cfgLen2];
|
||||
|
||||
// populate runtime config with device factory settings
|
||||
//
|
||||
// configuration frame structure in NVRAM;
|
||||
// 1. version header [10 bytes, containing version string]
|
||||
// 2. user settings [cfgLen bytes, containing default runtime settings
|
||||
// (configData_t cfg)]
|
||||
// 3. magicByte [cfgLen2 bytes, containing a fixed identifier]
|
||||
|
||||
// populate runtime config with factory settings
|
||||
static void defaultConfig(configData_t *myconfig) {
|
||||
char version[10];
|
||||
snprintf(version, 10, "%-10s", PROGVERSION);
|
||||
memcpy(myconfig->version, &PROGVERSION, 10); // Firmware version
|
||||
|
||||
// factory settings
|
||||
// device factory settings
|
||||
myconfig->loradr = LORADRDEFAULT; // 0-15, lora datarate, see paxcounter.conf
|
||||
myconfig->txpower = LORATXPOWDEFAULT; // 0-15, lora tx power
|
||||
myconfig->adrmode = 1; // 0=disabled, 1=enabled
|
||||
@@ -56,6 +62,11 @@ static void defaultConfig(configData_t *myconfig) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// migrate runtime configuration from earlier to current version
|
||||
static void migrateConfig(void) {
|
||||
// currently no configuration migration rules are implemented
|
||||
}
|
||||
|
||||
// save current configuration from RAM to NVRAM
|
||||
void saveConfig(bool erase) {
|
||||
ESP_LOGI(TAG, "Storing settings to NVRAM...");
|
||||
@@ -84,36 +95,65 @@ void saveConfig(bool erase) {
|
||||
// load configuration from NVRAM into RAM and make it current
|
||||
bool loadConfig() {
|
||||
|
||||
ESP_LOGI(TAG, "Loading device runtime configuration from NVRAM...");
|
||||
ESP_LOGI(TAG, "Loading device configuration from NVRAM...");
|
||||
|
||||
if (!nvram.begin(DEVCONFIG, true)) {
|
||||
ESP_LOGW(TAG, "NVRAM initialized, device starts with factory settings");
|
||||
ESP_LOGI(TAG, "NVRAM initialized, device starts with factory settings");
|
||||
eraseConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
// simple check that runtime config data matches
|
||||
if (nvram.getBytesLength(DEVCONFIG) != (cfgLen + cfgLen2)) {
|
||||
ESP_LOGE(TAG, "configuration invalid");
|
||||
return false;
|
||||
// simple check that runtime config data matches
|
||||
if (nvram.getBytesLength(DEVCONFIG) != (cfgLen + cfgLen2)) {
|
||||
ESP_LOGE(TAG, "Configuration invalid");
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// load device runtime config from nvram and copy it to byte array
|
||||
nvram.getBytes(DEVCONFIG, buffer, cfgLen + cfgLen2);
|
||||
nvram.end();
|
||||
// validate configuration by checking magic bytes at end of array
|
||||
if (memcmp(buffer + cfgLen, &cfgMagicBytes, cfgLen2) != 0) {
|
||||
ESP_LOGW(TAG, "No configuration found");
|
||||
return false;
|
||||
// load device runtime config from nvram and copy it to byte array
|
||||
nvram.getBytes(DEVCONFIG, buffer, cfgLen + cfgLen2);
|
||||
nvram.end();
|
||||
|
||||
} else {
|
||||
// copy byte array into runtime cfg struct
|
||||
memcpy(&cfg, buffer, cfgLen);
|
||||
ESP_LOGI(TAG, "Runtime configuration loaded");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// validate loaded configuration by checking magic bytes at end of array
|
||||
if (memcmp(buffer + cfgLen, &cfgMagicBytes, cfgLen2) != 0) {
|
||||
ESP_LOGW(TAG, "No configuration found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// copy loaded configuration into runtime cfg struct
|
||||
memcpy(&cfg, buffer, cfgLen);
|
||||
ESP_LOGI(TAG, "Runtime configuration v%s loaded", cfg.version);
|
||||
|
||||
// check if config version matches current firmware version
|
||||
switch (version_compare(PROGVERSION, cfg.version)) {
|
||||
case -1: // device configuration belongs to newer than current firmware
|
||||
ESP_LOGE(TAG, "Incompatible device configuration");
|
||||
return false;
|
||||
case 1: // device configuration belongs to older than current firmware
|
||||
ESP_LOGW(TAG, "Device was updated, attempt to migrate configuration");
|
||||
migrateConfig();
|
||||
return true;
|
||||
default: // device configuration version matches current firmware version
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void eraseConfig(void) { saveConfig(true); }
|
||||
// helper function to convert strings into lower case
|
||||
bool comp(char s1, char s2) { return (tolower(s1) < tolower(s2)); }
|
||||
|
||||
// helper function to lexicographically compare two versions. Returns 1 if v2
|
||||
// is smaller, -1 if v1 is smaller, 0 if equal
|
||||
int version_compare(const String v1, const String v2) {
|
||||
|
||||
if (v1 == v2)
|
||||
return 0;
|
||||
|
||||
const char *a1 = v1.c_str(), *a2 = v2.c_str();
|
||||
|
||||
if (std::lexicographical_compare(a1, a1 + strlen(a1), a2, a2 + strlen(a2),
|
||||
comp))
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void eraseConfig(void) { saveConfig(true); }
|
||||
+19
-20
@@ -12,7 +12,10 @@ static const char TAG[] = __FILE__;
|
||||
// thus precision is only +/- 1 second
|
||||
|
||||
TinyGPSPlus gps;
|
||||
TinyGPSCustom gpstime(gps, "GPZDA", 1); // field 1 = UTC time
|
||||
TinyGPSCustom gpstime(gps, "GPZDA", 1); // field 1 = UTC time (hhmmss.ss)
|
||||
TinyGPSCustom gpsday(gps, "GPZDA", 2); // field 2 = day (01..31)
|
||||
TinyGPSCustom gpsmonth(gps, "GPZDA", 3); // field 3 = month (01..12)
|
||||
TinyGPSCustom gpsyear(gps, "GPZDA", 4); // field 4 = year (4-digit)
|
||||
static const String ZDA_Request = "$EIGPQ,ZDA*39\r\n";
|
||||
TaskHandle_t GpsTask;
|
||||
|
||||
@@ -93,7 +96,7 @@ bool gps_hasfix() {
|
||||
gps.altitude.age() < 4000);
|
||||
}
|
||||
|
||||
// function to fetch current time from struct; note: this is costly
|
||||
// function to poll current time from GPS data; note: this is costly
|
||||
time_t get_gpstime(uint16_t *msec) {
|
||||
|
||||
time_t time_sec = 0;
|
||||
@@ -102,34 +105,30 @@ time_t get_gpstime(uint16_t *msec) {
|
||||
#ifdef GPS_SERIAL
|
||||
GPS_Serial.print(ZDA_Request);
|
||||
// wait for gps NMEA answer
|
||||
vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL));
|
||||
// vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL));
|
||||
#elif defined GPS_I2C
|
||||
Wire.print(ZDA_Request);
|
||||
#endif
|
||||
|
||||
// did we get a current time?
|
||||
if (gpstime.isUpdated() && gpstime.isValid()) {
|
||||
// did we get a current date & time?
|
||||
if (gpstime.isUpdated() && gpstime.isValid() && gpsday.isValid()) {
|
||||
|
||||
tmElements_t tm;
|
||||
|
||||
String rawtime = gpstime.value();
|
||||
uint32_t time_bcd = rawtime.toFloat() * 100;
|
||||
uint32_t time_bcd = atof(gpstime.value()) * 100;
|
||||
uint32_t delay_ms =
|
||||
gpstime.age() + nmea_txDelay_ms + NMEA_COMPENSATION_FACTOR;
|
||||
uint8_t year =
|
||||
CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h
|
||||
|
||||
ESP_LOGD(TAG, "time [bcd]: %u", time_bcd);
|
||||
|
||||
tm.Second = (time_bcd / 100) % 100; // second
|
||||
tm.Minute = (time_bcd / 10000) % 100; // minute
|
||||
tm.Hour = time_bcd / 1000000; // hour
|
||||
tm.Day = gps.date.day(); // day
|
||||
tm.Month = gps.date.month(); // month
|
||||
tm.Year = year; // year
|
||||
tm.Day = atoi(gpsday.value()); // day
|
||||
tm.Month = atoi(gpsmonth.value()); // month
|
||||
tm.Year = CalendarYrToTm(
|
||||
atoi(gpsyear.value())); // year offset from 1970 in microTime.h
|
||||
|
||||
// add protocol delay to time with millisecond precision
|
||||
time_sec = makeTime(tm) + delay_ms / 1000;
|
||||
time_sec = makeTime(tm) + delay_ms / 1000 - 1;
|
||||
*msec = (delay_ms % 1000) ? delay_ms % 1000 : 0;
|
||||
}
|
||||
|
||||
@@ -163,15 +162,15 @@ void gps_loop(void *pvParameters) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// if time hasn't been synchronised yet, and we have a valid GPS time,
|
||||
// update time from GPS.
|
||||
if (timeSource == _unsynced && gpstime.isUpdated() && gpstime.isValid()) {
|
||||
// (only) while device time is not set or unsynched, and we have a valid GPS
|
||||
// time, we trigger a device time update to poll time from GPS
|
||||
if (timeSource == _unsynced && gpstime.isUpdated() && gpstime.isValid() &&
|
||||
gpsday.isValid())
|
||||
calibrateTime();
|
||||
}
|
||||
|
||||
} // if
|
||||
|
||||
// show NMEA data in verbose mode, useful for debugging GPS, bu tvery noisy
|
||||
// show NMEA data in verbose mode, useful only for debugging GPS, very noisy
|
||||
// ESP_LOGV(TAG, "GPS NMEA data: passed %u / failed: %u / with fix: %u",
|
||||
// gps.passedChecksum(), gps.failedChecksum(),
|
||||
// gps.sentencesWithFix());
|
||||
|
||||
-18
@@ -328,22 +328,4 @@ void show_progress(unsigned long current, unsigned long size) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// helper function to convert strings into lower case
|
||||
bool comp(char s1, char s2) { return tolower(s1) < tolower(s2); }
|
||||
|
||||
// helper function to lexicographically compare two versions. Returns 1 if v2 is
|
||||
// smaller, -1 if v1 is smaller, 0 if equal
|
||||
int version_compare(const String v1, const String v2) {
|
||||
|
||||
if (v1 == v2)
|
||||
return 0;
|
||||
|
||||
const char *a1 = v1.c_str(), *a2 = v2.c_str();
|
||||
|
||||
if (lexicographical_compare(a1, a1 + strlen(a1), a2, a2 + strlen(a2), comp))
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // USE_OTA
|
||||
@@ -0,0 +1,135 @@
|
||||
; PlatformIO Project Configuration File
|
||||
; NOTE: PlatformIO v4 is needed!
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
|
||||
|
||||
; ---> SELECT THE TARGET PLATFORM HERE! <---
|
||||
[board]
|
||||
halfile = generic.h
|
||||
;halfile = ebox.h
|
||||
;halfile = eboxtube.h
|
||||
;halfile = ecopower.h
|
||||
;halfile = heltec.h
|
||||
;halfile = heltecv2.h
|
||||
;halfile = ttgov1.h
|
||||
;halfile = ttgov2.h
|
||||
;halfile = ttgov21old.h
|
||||
;halfile = ttgov21new.h
|
||||
;halfile = ttgofox.h
|
||||
;halfile = ttgobeam.h
|
||||
;halfile = ttgobeam10.h
|
||||
;halfile = fipy.h
|
||||
;halfile = lopy.h
|
||||
;halfile = lopy4.h
|
||||
;halfile = lolin32litelora.h
|
||||
;halfile = lolin32lora.h
|
||||
;halfile = lolin32lite.h
|
||||
;halfile = wemos32oled.h
|
||||
;halfile = wemos32matrix.h
|
||||
;halfile = octopus32.h
|
||||
;halfile = tinypico.h
|
||||
;halfile = tinypicomatrix.h
|
||||
;halfile = m5core.h
|
||||
;halfile = m5fire.h
|
||||
;halfile = olimexpoeiso.h
|
||||
|
||||
[platformio]
|
||||
; upload firmware to board with usb cable
|
||||
default_envs = usb
|
||||
; upload firmware to a jfrog bintray repository
|
||||
;default_envs = ota
|
||||
; use latest versions of libraries
|
||||
;default_envs = dev
|
||||
description = Paxcounter is a device for metering passenger flows in realtime. It counts how many mobile devices are around.
|
||||
|
||||
[common]
|
||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
||||
release_version = 2.0.16
|
||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
||||
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||
debug_level = 3
|
||||
extra_scripts = pre:build.py
|
||||
otakeyfile = ota.conf
|
||||
lorakeyfile = loraconf.h
|
||||
lmicconfigfile = lmic_config.h
|
||||
platform_espressif32 = espressif32@2.0.0
|
||||
monitor_speed = 115200
|
||||
upload_speed = 115200 ; set by build.py and taken from hal file
|
||||
display_library = ; set by build.py and taken from hal file
|
||||
lib_deps_lora =
|
||||
mcci-catena/MCCI LoRaWAN LMIC library @ ^3.2.0
|
||||
lib_deps_display =
|
||||
bitbank2/OneBitDisplay @ 1.7.2
|
||||
ricmoo/QRCode @ ^0.0.1
|
||||
bodmer/TFT_eSPI @ ^2.2.20
|
||||
lib_deps_ledmatrix =
|
||||
seeed-studio/Ultrathin_LED_Matrix @ ^1.0.0
|
||||
lib_deps_rgbled =
|
||||
roboticsbrno/SmartLeds @ ^1.2.1
|
||||
lib_deps_gps =
|
||||
mikalhart/TinyGPSPlus @ ^1.0.2
|
||||
lib_deps_sensors =
|
||||
adafruit/Adafruit Unified Sensor @ ^1.1.4
|
||||
adafruit/Adafruit BME280 Library @ ^2.1.1
|
||||
adafruit/Adafruit BMP085 Library @ ^1.1.0
|
||||
boschsensortec/BSEC Software Library @ 1.5.1474
|
||||
https://github.com/ricki-z/SDS011.git
|
||||
lib_deps_basic =
|
||||
bblanchon/ArduinoJson @ <6
|
||||
jchristensen/Timezone @ ^1.2.4
|
||||
makuna/RTC @ ^2.3.5
|
||||
spacehuhn/SimpleButton
|
||||
lewisxhe/AXP202X_Library @ ^1.1.2
|
||||
geeksville/esp32-micro-sdcard @ ^0.1.1
|
||||
256dpi/MQTT @ ^2.4.7
|
||||
lib_deps_all =
|
||||
${common.lib_deps_basic}
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_display}
|
||||
${common.lib_deps_rgbled}
|
||||
${common.lib_deps_gps}
|
||||
${common.lib_deps_sensors}
|
||||
${common.lib_deps_ledmatrix}
|
||||
build_flags_basic =
|
||||
-include "src/hal/${board.halfile}"
|
||||
-include "src/paxcounter.conf"
|
||||
-w
|
||||
'-DCORE_DEBUG_LEVEL=${common.debug_level}'
|
||||
'-DLOG_LOCAL_LEVEL=${common.debug_level}'
|
||||
'-DPROGVERSION="${common.release_version}"'
|
||||
build_flags_sensors =
|
||||
-Llib/Bosch-BSEC/src/esp32/
|
||||
-lalgobsec
|
||||
build_flags_all =
|
||||
${common.build_flags_basic}
|
||||
${common.build_flags_sensors}
|
||||
-mfix-esp32-psram-cache-issue
|
||||
|
||||
[env]
|
||||
lib_ldf_mode = deep ; #632 Fixes compiler error with OneBitDisplay library
|
||||
framework = arduino
|
||||
board = esp32dev
|
||||
board_build.partitions = min_spiffs.csv
|
||||
upload_speed = ${common.upload_speed}
|
||||
;upload_port = COM8
|
||||
platform = ${common.platform_espressif32}
|
||||
lib_deps = ${common.lib_deps_all}
|
||||
build_flags = ${common.build_flags_all}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
monitor_filters = time, esp32_exception_decoder, default
|
||||
|
||||
[env:ota]
|
||||
upload_protocol = custom
|
||||
|
||||
[env:usb]
|
||||
upload_protocol = esptool
|
||||
|
||||
[env:dev]
|
||||
upload_protocol = esptool
|
||||
build_type = debug
|
||||
platform = https://github.com/platformio/platform-espressif32.git#develop
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git
|
||||
Reference in new issue
Block a user