commit
0e62683cdf
@ -301,7 +301,8 @@ Hereafter described is the default *plain* format, which uses MSB bit numbering.
|
|||||||
byte 3-10: Uptime [seconds]
|
byte 3-10: Uptime [seconds]
|
||||||
byte 11: CPU temperature [°C]
|
byte 11: CPU temperature [°C]
|
||||||
bytes 12-15: Free RAM [bytes]
|
bytes 12-15: Free RAM [bytes]
|
||||||
bytes 16-17: Last CPU reset reason [core 0, core 1]
|
byte 16: Last CPU core 0 reset reason
|
||||||
|
bytes 17-20: Number of restarts since last power cycle
|
||||||
|
|
||||||
**Port #3:** Device configuration query result
|
**Port #3:** Device configuration query result
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define _CONFIGMANAGER_H
|
#define _CONFIGMANAGER_H
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "reset.h"
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
|
|
||||||
void saveConfig(bool erase = false);
|
void saveConfig(bool erase = false);
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
void addCount(uint16_t value, uint8_t sniffytpe);
|
void addCount(uint16_t value, uint8_t sniffytpe);
|
||||||
void addConfig(configData_t value);
|
void addConfig(configData_t value);
|
||||||
void addStatus(uint16_t voltage, uint64_t uptime, float cputemp, uint32_t mem,
|
void addStatus(uint16_t voltage, uint64_t uptime, float cputemp, uint32_t mem,
|
||||||
uint8_t reset1, uint8_t reset2);
|
uint8_t reset0, uint32_t restarts);
|
||||||
void addAlarm(int8_t rssi, uint8_t message);
|
void addAlarm(int8_t rssi, uint8_t message);
|
||||||
void addVoltage(uint16_t value);
|
void addVoltage(uint16_t value);
|
||||||
void addGPS(gpsStatus_t value);
|
void addGPS(gpsStatus_t value);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
|
||||||
|
void reset_rtc_vars(void);
|
||||||
void do_reset(bool warmstart);
|
void do_reset(bool warmstart);
|
||||||
void do_after_reset(void);
|
void do_after_reset(void);
|
||||||
void enter_deepsleep(const uint64_t wakeup_sec = 60,
|
void enter_deepsleep(const uint64_t wakeup_sec = 60,
|
||||||
@ -16,5 +17,6 @@ void enter_deepsleep(const uint64_t wakeup_sec = 60,
|
|||||||
unsigned long long uptime(void);
|
unsigned long long uptime(void);
|
||||||
|
|
||||||
extern RTC_NOINIT_ATTR runmode_t RTC_runmode;
|
extern RTC_NOINIT_ATTR runmode_t RTC_runmode;
|
||||||
|
extern RTC_NOINIT_ATTR uint32_t RTC_restarts;
|
||||||
|
|
||||||
#endif // _RESET_H
|
#endif // _RESET_H
|
@ -328,7 +328,7 @@
|
|||||||
"z": "c26229c6.2d1ae8",
|
"z": "c26229c6.2d1ae8",
|
||||||
"name": "device status",
|
"name": "device status",
|
||||||
"property": "payload",
|
"property": "payload",
|
||||||
"pattern": "l16 => voltage,\nl64 => uptime,\nb8 => temperature,\nl32 => ram,\nb8 => reset0,\nb8 => reset1",
|
"pattern": "l16 => voltage,\nl64 => uptime,\nb8 => temperature,\nl32 => ram,\nb8 => reset0,\nl32 => restarts",
|
||||||
"x": 650,
|
"x": 650,
|
||||||
"y": 200,
|
"y": 200,
|
||||||
"wires": [
|
"wires": [
|
||||||
|
@ -38,8 +38,8 @@ function Decoder(bytes, port) {
|
|||||||
|
|
||||||
if (port === 2) {
|
if (port === 2) {
|
||||||
// device status data
|
// device status data
|
||||||
if (bytes.length === 17) {
|
if (bytes.length === 20) {
|
||||||
return decode(bytes, [uint16, uptime, uint8, uint32, uint8, uint8], ['voltage', 'uptime', 'cputemp', 'memory', 'reset0', 'reset1']);
|
return decode(bytes, [uint16, uptime, uint8, uint32, uint8, uint32], ['voltage', 'uptime', 'cputemp', 'memory', 'reset0', 'restarts']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ function Decoder(bytes, port) {
|
|||||||
decoded.temp = bytes[i++];
|
decoded.temp = bytes[i++];
|
||||||
decoded.memory = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]);
|
decoded.memory = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]);
|
||||||
decoded.reset0 = bytes[i++];
|
decoded.reset0 = bytes[i++];
|
||||||
decoded.reset1 = bytes[i++];
|
decoded.restarts = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port === 4) {
|
if (port === 4) {
|
||||||
|
@ -46,8 +46,8 @@ function decodeUplink(input) {
|
|||||||
|
|
||||||
if (input.fPort === 2) {
|
if (input.fPort === 2) {
|
||||||
// device status data
|
// device status data
|
||||||
if (input.bytes.length === 17) {
|
if (input.bytes.length === 20) {
|
||||||
data = decode(input.bytes, [uint16, uptime, uint8, uint32, uint8, uint8], ['voltage', 'uptime', 'cputemp', 'memory', 'reset0', 'reset1']);
|
data = decode(input.bytes, [uint16, uptime, uint8, uint32, uint8, uint32], ['voltage', 'uptime', 'cputemp', 'memory', 'reset0', 'restarts']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ function decodeUplink(input) {
|
|||||||
data.cputemp = input.bytes[i++];
|
data.cputemp = input.bytes[i++];
|
||||||
data.memory = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
|
data.memory = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
|
||||||
data.reset0 = input.bytes[i++];
|
data.reset0 = input.bytes[i++];
|
||||||
data.reset1 = input.bytes[i++];
|
data.restarts = ((input.bytes[i++] << 24) | (input.bytes[i++] << 16) | (input.bytes[i++] << 8) | input.bytes[i++]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.fPort === 4) {
|
if (input.fPort === 4) {
|
||||||
|
@ -95,8 +95,8 @@ void start_boot_menu(void) {
|
|||||||
// (because esp_restart() from ISR would trigger the ESP32 task watchdog)
|
// (because esp_restart() from ISR would trigger the ESP32 task watchdog)
|
||||||
xTaskCreate(
|
xTaskCreate(
|
||||||
[](void *p) {
|
[](void *p) {
|
||||||
vTaskSuspend(NULL);
|
vTaskSuspend(NULL); // wait for task resume call by watchdog
|
||||||
ESP.restart();
|
esp_restart();
|
||||||
},
|
},
|
||||||
"Restart", configMINIMAL_STACK_SIZE, NULL, (3 | portPRIVILEGE_BIT),
|
"Restart", configMINIMAL_STACK_SIZE, NULL, (3 | portPRIVILEGE_BIT),
|
||||||
&RestartHandle);
|
&RestartHandle);
|
||||||
@ -148,7 +148,6 @@ void start_boot_menu(void) {
|
|||||||
[]() {
|
[]() {
|
||||||
server.sendHeader("Connection", "close");
|
server.sendHeader("Connection", "close");
|
||||||
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
|
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
|
||||||
WiFi.disconnect(true);
|
|
||||||
esp_restart();
|
esp_restart();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -159,4 +159,7 @@ int version_compare(const String v1, const String v2) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eraseConfig(void) { saveConfig(true); }
|
void eraseConfig(void) {
|
||||||
|
reset_rtc_vars();
|
||||||
|
saveConfig(true);
|
||||||
|
}
|
17
src/main.cpp
17
src/main.cpp
@ -140,6 +140,7 @@ void setup() {
|
|||||||
esp_log_level_set("*", ESP_LOG_NONE);
|
esp_log_level_set("*", ESP_LOG_NONE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// load device configuration from NVRAM and set runmode
|
||||||
do_after_reset();
|
do_after_reset();
|
||||||
|
|
||||||
// print chip information on startup if in verbose mode after coldstart
|
// print chip information on startup if in verbose mode after coldstart
|
||||||
@ -206,9 +207,6 @@ void setup() {
|
|||||||
strcat_P(features, " PMU");
|
strcat_P(features, " PMU");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// read (and initialize on first run) runtime settings from NVRAM
|
|
||||||
_ASSERT(loadConfig()); // includes initialize if necessary
|
|
||||||
|
|
||||||
// now that we are powered, we scan i2c bus for devices
|
// now that we are powered, we scan i2c bus for devices
|
||||||
if (RTC_runmode == RUNMODE_POWERCYCLE)
|
if (RTC_runmode == RUNMODE_POWERCYCLE)
|
||||||
i2c_scan();
|
i2c_scan();
|
||||||
@ -291,16 +289,15 @@ void setup() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (BOOTMENU)
|
#if (BOOTMENU)
|
||||||
// start local webserver after device powers up or on rcommand request
|
// start local webserver after each coldstart
|
||||||
if ((RTC_runmode == RUNMODE_POWERCYCLE) ||
|
if (RTC_runmode == RUNMODE_POWERCYCLE)
|
||||||
(RTC_runmode == RUNMODE_MAINTENANCE))
|
|
||||||
start_boot_menu();
|
|
||||||
#else
|
|
||||||
// start local webserver on rcommand request only
|
|
||||||
if (RTC_runmode == RUNMODE_MAINTENANCE)
|
|
||||||
start_boot_menu();
|
start_boot_menu();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// start local webserver on rcommand request
|
||||||
|
if (RTC_runmode == RUNMODE_MAINTENANCE)
|
||||||
|
start_boot_menu();
|
||||||
|
|
||||||
// start mac processing task
|
// start mac processing task
|
||||||
ESP_LOGI(TAG, "Starting MAC processor...");
|
ESP_LOGI(TAG, "Starting MAC processor...");
|
||||||
macQueueInit();
|
macQueueInit();
|
||||||
|
@ -58,7 +58,7 @@ void PayloadConvert::addConfig(configData_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
|
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
|
||||||
uint32_t mem, uint8_t reset1, uint8_t reset2) {
|
uint32_t mem, uint8_t reset0, uint32_t restarts) {
|
||||||
|
|
||||||
buffer[cursor++] = highByte(voltage);
|
buffer[cursor++] = highByte(voltage);
|
||||||
buffer[cursor++] = lowByte(voltage);
|
buffer[cursor++] = lowByte(voltage);
|
||||||
@ -75,8 +75,11 @@ void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
|
|||||||
buffer[cursor++] = (byte)((mem & 0x00FF0000) >> 16);
|
buffer[cursor++] = (byte)((mem & 0x00FF0000) >> 16);
|
||||||
buffer[cursor++] = (byte)((mem & 0x0000FF00) >> 8);
|
buffer[cursor++] = (byte)((mem & 0x0000FF00) >> 8);
|
||||||
buffer[cursor++] = (byte)((mem & 0x000000FF));
|
buffer[cursor++] = (byte)((mem & 0x000000FF));
|
||||||
buffer[cursor++] = (byte)(reset1);
|
buffer[cursor++] = (byte)(reset0);
|
||||||
buffer[cursor++] = (byte)(reset2);
|
buffer[cursor++] = (byte)((restarts & 0xFF000000) >> 24);
|
||||||
|
buffer[cursor++] = (byte)((restarts & 0x00FF0000) >> 16);
|
||||||
|
buffer[cursor++] = (byte)((restarts & 0x0000FF00) >> 8);
|
||||||
|
buffer[cursor++] = (byte)((restarts & 0x000000FF));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PayloadConvert::addGPS(gpsStatus_t value) {
|
void PayloadConvert::addGPS(gpsStatus_t value) {
|
||||||
@ -185,13 +188,13 @@ void PayloadConvert::addConfig(configData_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
|
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
|
||||||
uint32_t mem, uint8_t reset1, uint8_t reset2) {
|
uint32_t mem, uint8_t reset0, uint32_t restarts) {
|
||||||
writeUint16(voltage);
|
writeUint16(voltage);
|
||||||
writeUptime(uptime);
|
writeUptime(uptime);
|
||||||
writeUint8((byte)cputemp);
|
writeUint8((byte)cputemp);
|
||||||
writeUint32(mem);
|
writeUint32(mem);
|
||||||
writeUint8(reset1);
|
writeUint8(reset0);
|
||||||
writeUint8(reset2);
|
writeUint32(restarts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PayloadConvert::addGPS(gpsStatus_t value) {
|
void PayloadConvert::addGPS(gpsStatus_t value) {
|
||||||
@ -397,7 +400,7 @@ void PayloadConvert::addConfig(configData_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float celsius,
|
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float celsius,
|
||||||
uint32_t mem, uint8_t reset1, uint8_t reset2) {
|
uint32_t mem, uint8_t reset0, uint32_t restarts) {
|
||||||
uint16_t temp = celsius * 10;
|
uint16_t temp = celsius * 10;
|
||||||
uint16_t volt = voltage / 10;
|
uint16_t volt = voltage / 10;
|
||||||
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
|
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
|
||||||
|
@ -306,7 +306,7 @@ void get_status(uint8_t val[]) {
|
|||||||
payload.reset();
|
payload.reset();
|
||||||
payload.addStatus(read_voltage(), (uint64_t)(uptime() / 1000ULL),
|
payload.addStatus(read_voltage(), (uint64_t)(uptime() / 1000ULL),
|
||||||
temperatureRead(), getFreeRAM(), rtc_get_reset_reason(0),
|
temperatureRead(), getFreeRAM(), rtc_get_reset_reason(0),
|
||||||
rtc_get_reset_reason(1));
|
RTC_restarts);
|
||||||
SendPayload(STATUSPORT);
|
SendPayload(STATUSPORT);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ static const char TAG[] = __FILE__;
|
|||||||
|
|
||||||
// RTC_NOINIT_ATTR -> keep value after a software restart or system crash
|
// RTC_NOINIT_ATTR -> keep value after a software restart or system crash
|
||||||
RTC_NOINIT_ATTR runmode_t RTC_runmode;
|
RTC_NOINIT_ATTR runmode_t RTC_runmode;
|
||||||
|
RTC_NOINIT_ATTR uint32_t RTC_restarts;
|
||||||
|
|
||||||
// RTC_DATA_ATTR -> keep values after a wakeup from sleep
|
// RTC_DATA_ATTR -> keep values after a wakeup from sleep
|
||||||
RTC_DATA_ATTR struct timeval RTC_sleep_start_time;
|
RTC_DATA_ATTR struct timeval RTC_sleep_start_time;
|
||||||
@ -17,8 +18,10 @@ RTC_DATA_ATTR unsigned long long RTC_millis = 0;
|
|||||||
|
|
||||||
timeval sleep_stop_time;
|
timeval sleep_stop_time;
|
||||||
|
|
||||||
const char *runmode[6] = {"powercycle", "normal", "wakeup",
|
void reset_rtc_vars(void) {
|
||||||
"update", "sleep", "maintenance"};
|
RTC_runmode = RUNMODE_POWERCYCLE;
|
||||||
|
RTC_restarts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void do_reset(bool warmstart) {
|
void do_reset(bool warmstart) {
|
||||||
if (warmstart) {
|
if (warmstart) {
|
||||||
@ -40,19 +43,19 @@ void do_after_reset(void) {
|
|||||||
struct timeval sleep_stop_time;
|
struct timeval sleep_stop_time;
|
||||||
uint64_t sleep_time_ms;
|
uint64_t sleep_time_ms;
|
||||||
|
|
||||||
|
// read (and initialize on first run) runtime settings from NVRAM
|
||||||
|
loadConfig();
|
||||||
|
|
||||||
switch (rtc_get_reset_reason(0)) {
|
switch (rtc_get_reset_reason(0)) {
|
||||||
|
|
||||||
case POWERON_RESET: // 0x01 Vbat power on reset
|
case POWERON_RESET: // 0x01 Vbat power on reset
|
||||||
case RTCWDT_BROWN_OUT_RESET: // 0x0f Reset when the vdd voltage is not
|
case RTCWDT_BROWN_OUT_RESET: // 0x0f Reset when the vdd voltage is not
|
||||||
// stable
|
// stable
|
||||||
RTC_runmode = RUNMODE_POWERCYCLE;
|
reset_rtc_vars();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SW_CPU_RESET: // 0x0c Software reset CPU
|
case SW_CPU_RESET: // 0x0c Software reset CPU
|
||||||
// keep previous runmode, if RTC_runmode has valid value
|
// keep previous set runmode (update / normal / maintenance)
|
||||||
// sets runmode, if RTC_runmode is invalid (i.e. not initialized)
|
|
||||||
if ((RTC_runmode != RUNMODE_UPDATE) && (RTC_runmode != RUNMODE_NORMAL))
|
|
||||||
RTC_runmode = RUNMODE_POWERCYCLE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEEPSLEEP_RESET: // 0x05 Deep Sleep reset digital core
|
case DEEPSLEEP_RESET: // 0x05 Deep Sleep reset digital core
|
||||||
@ -84,8 +87,9 @@ void do_after_reset(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Starting Software v%s, runmode %s", PROGVERSION,
|
RTC_restarts++;
|
||||||
runmode[RTC_runmode]);
|
ESP_LOGI(TAG, "Starting Software v%s (runmode=%d / restarts=%d)", PROGVERSION,
|
||||||
|
RTC_runmode, RTC_restarts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
||||||
|
Loading…
Reference in New Issue
Block a user