Browse Source

Preserve time across warm resets on nRF52 (watchdog, soft reset, pin reset)

nRF52 boards without I2C RTC will drop back to seed time on every reset.
Mirrors fix in #1896 for ESP32.
pull/1962/head
Wessel Nieboer 3 months ago
committed by Wessel Nieboer
parent
commit
8b3f29be0d
No known key found for this signature in database GPG Key ID: 929C8E45E33B5FD2
  1. 4
      src/helpers/NRF52Board.cpp
  2. 41
      src/helpers/NRF52Board.h
  3. 2
      variants/heltec_mesh_solar/target.cpp
  4. 2
      variants/heltec_t114/target.cpp
  5. 2
      variants/ikoka_handheld_nrf/target.cpp
  6. 2
      variants/ikoka_nano_nrf/target.cpp
  7. 2
      variants/ikoka_stick_nrf/target.cpp
  8. 2
      variants/keepteen_lt1/target.cpp
  9. 2
      variants/lilygo_techo/target.cpp
  10. 2
      variants/lilygo_techo_lite/target.cpp
  11. 2
      variants/mesh_pocket/target.cpp
  12. 2
      variants/meshtiny/target.cpp
  13. 2
      variants/minewsemi_me25ls01/target.cpp
  14. 2
      variants/minewsemi_me25ls01/target.h
  15. 2
      variants/nano_g2_ultra/target.cpp
  16. 2
      variants/promicro/target.cpp
  17. 2
      variants/rak3401/target.cpp
  18. 2
      variants/rak4631/target.cpp
  19. 2
      variants/rak_wismesh_tag/target.cpp
  20. 2
      variants/sensecap_solar/target.cpp
  21. 2
      variants/t1000-e/target.cpp
  22. 2
      variants/t1000-e/target.h
  23. 2
      variants/thinknode_m1/target.cpp
  24. 2
      variants/thinknode_m3/target.cpp
  25. 2
      variants/thinknode_m6/target.cpp
  26. 2
      variants/wio-tracker-l1/target.cpp
  27. 2
      variants/wio_wm1110/target.cpp
  28. 2
      variants/wio_wm1110/target.h
  29. 2
      variants/xiao_nrf52/target.cpp

4
src/helpers/NRF52Board.cpp

@ -1,6 +1,10 @@
#if defined(NRF52_PLATFORM)
#include "NRF52Board.h"
// Single definitions for noinit backup variables (declared extern in NRF52Board.h)
uint32_t _noinit_backup_time __attribute__((section(".noinit")));
uint32_t _noinit_backup_magic __attribute__((section(".noinit")));
#include <bluefruit.h>
#include <nrf_soc.h>

41
src/helpers/NRF52Board.h

@ -5,6 +5,47 @@
#if defined(NRF52_PLATFORM)
// noinit variables survive watchdog, soft, pin, and lockup resets (RAM retained).
// Lost on power-on and System OFF (magic check handles this).
extern uint32_t _noinit_backup_time __attribute__((section(".noinit")));
extern uint32_t _noinit_backup_magic __attribute__((section(".noinit")));
#define NRF52_BACKUP_MAGIC 0xAA55CC33
#define NRF52_TIME_MIN 1772323200 // 1 Mar 2026
class NRF52RTCClock : public mesh::RTCClock {
uint32_t base_time;
uint64_t accumulator;
unsigned long prev_millis;
public:
NRF52RTCClock() {
if (_noinit_backup_magic == NRF52_BACKUP_MAGIC && _noinit_backup_time > NRF52_TIME_MIN) {
base_time = _noinit_backup_time;
} else {
base_time = NRF52_TIME_MIN;
}
accumulator = 0;
prev_millis = millis();
}
uint32_t getCurrentTime() override { return base_time + accumulator / 1000; }
void setCurrentTime(uint32_t time) override {
base_time = time;
accumulator = 0;
prev_millis = millis();
_noinit_backup_time = time;
_noinit_backup_magic = NRF52_BACKUP_MAGIC;
}
void tick() override {
unsigned long now = millis();
accumulator += (now - prev_millis);
prev_millis = now;
uint32_t current = base_time + accumulator / 1000;
if (current > NRF52_TIME_MIN && current != _noinit_backup_time) {
_noinit_backup_time = current;
_noinit_backup_magic = NRF52_BACKUP_MAGIC;
}
}
};
#ifdef NRF52_POWER_MANAGEMENT
// Shutdown Reason Codes (stored in GPREGRET before SYSTEMOFF)
#define SHUTDOWN_REASON_NONE 0x00

2
variants/heltec_mesh_solar/target.cpp

@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
SolarSensorManager sensors = SolarSensorManager(nmea);

2
variants/heltec_t114/target.cpp

@ -17,7 +17,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#if ENV_INCLUDE_GPS

2
variants/ikoka_handheld_nrf/target.cpp

@ -8,7 +8,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
EnvironmentSensorManager sensors;

2
variants/ikoka_nano_nrf/target.cpp

@ -13,7 +13,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
EnvironmentSensorManager sensors;

2
variants/ikoka_stick_nrf/target.cpp

@ -13,7 +13,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
EnvironmentSensorManager sensors;

2
variants/keepteen_lt1/target.cpp

@ -8,7 +8,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#if ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>

2
variants/lilygo_techo/target.cpp

@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifdef ENV_INCLUDE_GPS

2
variants/lilygo_techo_lite/target.cpp

@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifdef ENV_INCLUDE_GPS

2
variants/mesh_pocket/target.cpp

@ -11,7 +11,7 @@ WRAPPER_CLASS radio_driver(radio, board);
SensorManager sensors = SensorManager();
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifdef DISPLAY_CLASS

2
variants/meshtiny/target.cpp

@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
EnvironmentSensorManager sensors = EnvironmentSensorManager();

2
variants/minewsemi_me25ls01/target.cpp

@ -7,7 +7,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock rtc_clock;
NRF52RTCClock rtc_clock;
extern EnvironmentSensorManager sensors;
#if ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>

2
variants/minewsemi_me25ls01/target.h

@ -19,7 +19,7 @@
extern MinewsemiME25LS01Board board;
extern WRAPPER_CLASS radio_driver;
extern VolatileRTCClock rtc_clock;
extern NRF52RTCClock rtc_clock;
extern EnvironmentSensorManager sensors;
bool radio_init();

2
variants/nano_g2_ultra/target.cpp

@ -10,7 +10,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
NanoG2UltraSensorManager sensors = NanoG2UltraSensorManager(nmea);

2
variants/promicro/target.cpp

@ -8,7 +8,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#if ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>

2
variants/rak3401/target.cpp

@ -21,7 +21,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#if ENV_INCLUDE_GPS

2
variants/rak4631/target.cpp

@ -21,7 +21,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#if ENV_INCLUDE_GPS

2
variants/rak_wismesh_tag/target.cpp

@ -17,7 +17,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#if ENV_INCLUDE_GPS

2
variants/sensecap_solar/target.cpp

@ -10,7 +10,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifdef ENV_INCLUDE_GPS
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);

2
variants/t1000-e/target.cpp

@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock rtc_clock;
NRF52RTCClock rtc_clock;
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
T1000SensorManager sensors = T1000SensorManager(nmea);

2
variants/t1000-e/target.h

@ -37,7 +37,7 @@ public:
extern T1000eBoard board;
extern WRAPPER_CLASS radio_driver;
extern VolatileRTCClock rtc_clock;
extern NRF52RTCClock rtc_clock;
extern T1000SensorManager sensors;
bool radio_init();

2
variants/thinknode_m1/target.cpp

@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
ThinkNodeM1SensorManager sensors = ThinkNodeM1SensorManager(nmea);

2
variants/thinknode_m3/target.cpp

@ -8,7 +8,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifdef ENV_INCLUDE_GPS
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);

2
variants/thinknode_m6/target.cpp

@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifdef ENV_INCLUDE_GPS
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);

2
variants/wio-tracker-l1/target.cpp

@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifdef ENV_INCLUDE_GPS

2
variants/wio_wm1110/target.cpp

@ -8,7 +8,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock rtc_clock;
NRF52RTCClock rtc_clock;
EnvironmentSensorManager sensors;
#ifndef LORA_CR

2
variants/wio_wm1110/target.h

@ -10,7 +10,7 @@
extern WioWM1110Board board;
extern WRAPPER_CLASS radio_driver;
extern VolatileRTCClock rtc_clock;
extern NRF52RTCClock rtc_clock;
extern EnvironmentSensorManager sensors;
bool radio_init();

2
variants/xiao_nrf52/target.cpp

@ -12,7 +12,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
NRF52RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
EnvironmentSensorManager sensors;

Loading…
Cancel
Save